DAWorkbench 0.0.1
DAWorkbench API
载入中...
搜索中...
未找到
da_vector_table.hpp
1#ifndef DA_VECTOR_TABLE_H
2#define DA_VECTOR_TABLE_H
3
4#include <vector>
5#include <algorithm>
6#include <stdexcept>
7#include <utility>
8#include <initializer_list>
9#include <type_traits>
10
11namespace DA
12{
20template< typename T >
22{
23public:
24 using value_type = T;
25 using table_index_type = std::pair< std::size_t, std::size_t >;
26
27 // 迭代器类型定义
28 using iterator = typename std::vector< T >::iterator;
29 using const_iterator = typename std::vector< T >::const_iterator;
30 using reverse_iterator = typename std::vector< T >::reverse_iterator;
31 using const_reverse_iterator = typename std::vector< T >::const_reverse_iterator;
32
33public:
34 // 构造函数
36 explicit da_vector_table(std::size_t rows, std::size_t cols = 0, const T& value = T());
37 da_vector_table(std::initializer_list< std::initializer_list< T > > init);
38
39 // 拷贝和移动构造函数
40 da_vector_table(const da_vector_table& other);
41 da_vector_table(da_vector_table&& other) noexcept;
42
43 // 赋值运算符
45 da_vector_table& operator=(da_vector_table&& other) noexcept;
46
47 // 容量操作
48 bool empty() const noexcept;
49 std::size_t size() const noexcept;
50 std::size_t max_size() const noexcept;
51 void reserve(std::size_t new_cap);
52 std::size_t capacity() const noexcept;
53 void shrink_to_fit();
54
55 // 迭代器访问
56 iterator begin() noexcept;
57 const_iterator begin() const noexcept;
58 const_iterator cbegin() const noexcept;
59 iterator end() noexcept;
60 const_iterator end() const noexcept;
61 const_iterator cend() const noexcept;
62 reverse_iterator rbegin() noexcept;
63 const_reverse_iterator rbegin() const noexcept;
64 const_reverse_iterator crbegin() const noexcept;
65 reverse_iterator rend() noexcept;
66 const_reverse_iterator rend() const noexcept;
67 const_reverse_iterator crend() const noexcept;
68
69 // 元素访问
70 T& operator()(std::size_t row, std::size_t col);
71 const T& operator()(std::size_t row, std::size_t col) const;
72 T& at(std::size_t row, std::size_t col);
73 const T& at(std::size_t row, std::size_t col) const;
74 T& front();
75 const T& front() const;
76 T& back();
77 const T& back() const;
78 T* data() noexcept;
79 const T* data() const noexcept;
80
81 // 修改器
82 void assign(std::size_t rows, std::size_t cols, const T& value);
83 template< typename InputIt >
84 void assign(InputIt first, InputIt last);
85 void push_back(const T& value);
86 void push_back(T&& value);
87 template< typename... Args >
88 void emplace_back(Args&&... args);
89 void pop_back();
90 void clear() noexcept;
91 void swap(da_vector_table& other) noexcept;
92
93 // 行操作
94 void append_row(const std::vector< T >& row);
95 void append_row(std::vector< T >&& row);
96 template< typename InputIt >
97 void append_row(InputIt first, InputIt last);
98 void append_row(std::initializer_list< T > il);
99 void insert_row(std::size_t pos, const std::vector< T >& row);
100 void insert_row(std::size_t pos, std::vector< T >&& row);
101 void erase_row(std::size_t pos);
102
103 // 列操作
104 void append_column(const std::vector< T >& col);
105 void append_column(std::vector< T >&& col);
106 template< typename InputIt >
107 void append_column(InputIt first, InputIt last);
108 void append_column(std::initializer_list< T > il);
109 void insert_column(std::size_t pos, const std::vector< T >& col);
110 void insert_column(std::size_t pos, std::vector< T >&& col);
111 void erase_column(std::size_t pos);
112
113 // 形状操作
114 table_index_type shape() const noexcept;
115 std::size_t row_count() const noexcept;
116 std::size_t column_count() const noexcept;
117 void resize(std::size_t rows, std::size_t cols, const T& value = T());
118 void resize(table_index_type sh, const T& value = T());
119 void reshape(std::size_t rows, std::size_t cols);
120
121 // 辅助功能
122 bool is_rectangular() const noexcept
123 {
124 return true;
125 } // 一维存储总是矩形的
126 std::vector< T > get_row(std::size_t row) const;
127 std::vector< T > get_column(std::size_t col) const;
128 void set_row(std::size_t row, const std::vector< T >& values);
129 void set_column(std::size_t col, const std::vector< T >& values);
130
131private:
132 std::vector< T > data_; // 一维数据存储
133 std::size_t rows_; // 行数
134 std::size_t cols_; // 列数
135
136 // 辅助函数
137 std::size_t index(std::size_t row, std::size_t col) const noexcept;
138 void check_bounds(std::size_t row, std::size_t col) const;
139 void check_row_bounds(std::size_t row) const;
140 void check_column_bounds(std::size_t col) const;
141};
142
143// ============================================================================
144// 实现部分
145// ============================================================================
146
156template< typename T >
157da_vector_table< T >::da_vector_table() : data_(), rows_(0), cols_(0)
158{
159}
160
176template< typename T >
177da_vector_table< T >::da_vector_table(std::size_t rows, std::size_t cols, const T& value)
178 : data_(rows * cols, value), rows_(rows), cols_(cols)
179{
180}
181
196template< typename T >
197da_vector_table< T >::da_vector_table(std::initializer_list< std::initializer_list< T > > init)
198 : rows_(init.size()), cols_(0)
199{
200 // 确定最大列数
201 for (const auto& row : init) {
202 if (row.size() > cols_) {
203 cols_ = row.size();
204 }
205 }
206
207 // 分配内存
208 data_.resize(rows_ * cols_);
209
210 // 填充数据
211 std::size_t row_idx = 0;
212 for (const auto& row : init) {
213 std::size_t col_idx = 0;
214 for (const auto& value : row) {
215 data_[ index(row_idx, col_idx) ] = value;
216 ++col_idx;
217 }
218 // 填充剩余部分(如果有)
219 for (; col_idx < cols_; ++col_idx) {
220 data_[ index(row_idx, col_idx) ] = T();
221 }
222 ++row_idx;
223 }
224}
225
237template< typename T >
239 : data_(other.data_), rows_(other.rows_), cols_(other.cols_)
240{
241}
242
257template< typename T >
259 : data_(std::move(other.data_)), rows_(other.rows_), cols_(other.cols_)
260{
261 other.rows_ = 0;
262 other.cols_ = 0;
263}
264
277template< typename T >
279{
280 if (this != &other) {
281 data_ = other.data_;
282 rows_ = other.rows_;
283 cols_ = other.cols_;
284 }
285 return *this;
286}
287
300template< typename T >
302{
303 if (this != &other) {
304 data_ = std::move(other.data_);
305 rows_ = other.rows_;
306 cols_ = other.cols_;
307 other.rows_ = 0;
308 other.cols_ = 0;
309 }
310 return *this;
311}
312
325template< typename T >
326bool da_vector_table< T >::empty() const noexcept
327{
328 return data_.empty();
329}
330
341template< typename T >
342std::size_t da_vector_table< T >::size() const noexcept
343{
344 return data_.size();
345}
346
357template< typename T >
358std::size_t da_vector_table< T >::max_size() const noexcept
359{
360 return data_.max_size();
361}
362
374template< typename T >
375void da_vector_table< T >::reserve(std::size_t new_cap)
376{
377 data_.reserve(new_cap);
378}
379
391template< typename T >
392std::size_t da_vector_table< T >::capacity() const noexcept
393{
394 return data_.capacity();
395}
396
409template< typename T >
411{
412 data_.shrink_to_fit();
413}
414
428template< typename T >
429typename da_vector_table< T >::iterator da_vector_table< T >::begin() noexcept
430{
431 return data_.begin();
432}
433
447template< typename T >
448typename da_vector_table< T >::const_iterator da_vector_table< T >::begin() const noexcept
449{
450 return data_.begin();
451}
452
466template< typename T >
467typename da_vector_table< T >::const_iterator da_vector_table< T >::cbegin() const noexcept
468{
469 return data_.cbegin();
470}
471
485template< typename T >
486typename da_vector_table< T >::iterator da_vector_table< T >::end() noexcept
487{
488 return data_.end();
489}
490
504template< typename T >
505typename da_vector_table< T >::const_iterator da_vector_table< T >::end() const noexcept
506{
507 return data_.end();
508}
509
523template< typename T >
524typename da_vector_table< T >::const_iterator da_vector_table< T >::cend() const noexcept
525{
526 return data_.cend();
527}
528
542template< typename T >
543typename da_vector_table< T >::reverse_iterator da_vector_table< T >::rbegin() noexcept
544{
545 return data_.rbegin();
546}
547
561template< typename T >
562typename da_vector_table< T >::const_reverse_iterator da_vector_table< T >::rbegin() const noexcept
563{
564 return data_.rbegin();
565}
566
580template< typename T >
581typename da_vector_table< T >::const_reverse_iterator da_vector_table< T >::crbegin() const noexcept
582{
583 return data_.crbegin();
584}
585
599template< typename T >
600typename da_vector_table< T >::reverse_iterator da_vector_table< T >::rend() noexcept
601{
602 return data_.rend();
603}
604
618template< typename T >
619typename da_vector_table< T >::const_reverse_iterator da_vector_table< T >::rend() const noexcept
620{
621 return data_.rend();
622}
623
637template< typename T >
638typename da_vector_table< T >::const_reverse_iterator da_vector_table< T >::crend() const noexcept
639{
640 return data_.crend();
641}
642
657template< typename T >
658T& da_vector_table< T >::operator()(std::size_t row, std::size_t col)
659{
660 return data_[ index(row, col) ];
661}
662
677template< typename T >
678const T& da_vector_table< T >::operator()(std::size_t row, std::size_t col) const
679{
680 return data_[ index(row, col) ];
681}
682
704template< typename T >
705T& da_vector_table< T >::at(std::size_t row, std::size_t col)
706{
707 check_bounds(row, col);
708 return data_[ index(row, col) ];
709}
710
732template< typename T >
733const T& da_vector_table< T >::at(std::size_t row, std::size_t col) const
734{
735 check_bounds(row, col);
736 return data_[ index(row, col) ];
737}
738
750template< typename T >
752{
753 return data_.front();
754}
755
767template< typename T >
769{
770 return data_.front();
771}
772
784template< typename T >
786{
787 return data_.back();
788}
789
801template< typename T >
803{
804 return data_.back();
805}
806
821template< typename T >
823{
824 return data_.data();
825}
826
841template< typename T >
842const T* da_vector_table< T >::data() const noexcept
843{
844 return data_.data();
845}
846
860template< typename T >
861void da_vector_table< T >::assign(std::size_t rows, std::size_t cols, const T& value)
862{
863 data_.assign(rows * cols, value);
864 rows_ = rows;
865 cols_ = cols;
866}
867
886template< typename T >
887template< typename InputIt >
888void da_vector_table< T >::assign(InputIt first, InputIt last)
889{
890 data_.assign(first, last);
891 // 注意:调用此方法后需要手动设置rows_和cols_,或者调用reshape
892}
893
906template< typename T >
908{
909 data_.push_back(value);
910 // 注意:此操作会破坏表格结构,需要谨慎使用
911}
912
926template< typename T >
928{
929 data_.push_back(std::move(value));
930 // 注意:此操作会破坏表格结构,需要谨慎使用
931}
932
947template< typename T >
948template< typename... Args >
950{
951 data_.emplace_back(std::forward< Args >(args)...);
952 // 注意:此操作会破坏表格结构,需要谨慎使用
953}
954
966template< typename T >
968{
969 data_.pop_back();
970 // 注意:此操作会破坏表格结构,需要谨慎使用
971}
972
983template< typename T >
985{
986 data_.clear();
987 rows_ = 0;
988 cols_ = 0;
989}
990
1003template< typename T >
1005{
1006 data_.swap(other.data_);
1007 std::swap(rows_, other.rows_);
1008 std::swap(cols_, other.cols_);
1009}
1010
1023template< typename T >
1024void da_vector_table< T >::append_row(const std::vector< T >& row)
1025{
1026 if (cols_ == 0) {
1027 // 空表格,设置列数
1028 cols_ = row.size();
1029 } else if (row.size() != cols_) {
1030 throw std::invalid_argument("Row size must match table column count");
1031 }
1032
1033 data_.insert(data_.end(), row.begin(), row.end());
1034 ++rows_;
1035}
1036
1049template< typename T >
1050void da_vector_table< T >::append_row(std::vector< T >&& row)
1051{
1052 if (cols_ == 0) {
1053 // 空表格,设置列数
1054 cols_ = row.size();
1055 } else if (row.size() != cols_) {
1056 throw std::invalid_argument("Row size must match table column count");
1057 }
1058
1059 data_.insert(data_.end(), std::make_move_iterator(row.begin()), std::make_move_iterator(row.end()));
1060 ++rows_;
1061}
1062
1078template< typename T >
1079template< typename InputIt >
1080void da_vector_table< T >::append_row(InputIt first, InputIt last)
1081{
1082 const std::size_t count = std::distance(first, last);
1083 if (cols_ == 0) {
1084 // 空表格,设置列数
1085 cols_ = count;
1086 } else if (count != cols_) {
1087 throw std::invalid_argument("Row size must match table column count");
1088 }
1089
1090 data_.insert(data_.end(), first, last);
1091 ++rows_;
1092}
1093
1106template< typename T >
1107void da_vector_table< T >::append_row(std::initializer_list< T > il)
1108{
1109 if (cols_ == 0) {
1110 // 空表格,设置列数
1111 cols_ = il.size();
1112 } else if (il.size() != cols_) {
1113 throw std::invalid_argument("Row size must match table column count");
1114 }
1115
1116 data_.insert(data_.end(), il.begin(), il.end());
1117 ++rows_;
1118}
1119
1134template< typename T >
1135void da_vector_table< T >::insert_row(std::size_t pos, const std::vector< T >& row)
1136{
1137 check_row_bounds(pos); // 允许在末尾插入(pos == rows_)
1138
1139 if (cols_ == 0) {
1140 // 空表格,设置列数
1141 cols_ = row.size();
1142 } else if (row.size() != cols_) {
1143 throw std::invalid_argument("Row size must match table column count");
1144 }
1145
1146 // 计算插入位置
1147 const std::size_t insert_pos = pos * cols_;
1148 data_.insert(data_.begin() + insert_pos, row.begin(), row.end());
1149 ++rows_;
1150}
1151
1166template< typename T >
1167void da_vector_table< T >::insert_row(std::size_t pos, std::vector< T >&& row)
1168{
1169 check_row_bounds(pos); // 允许在末尾插入(pos == rows_)
1170
1171 if (cols_ == 0) {
1172 // 空表格,设置列数
1173 cols_ = row.size();
1174 } else if (row.size() != cols_) {
1175 throw std::invalid_argument("Row size must match table column count");
1176 }
1177
1178 // 预留足够空间避免重新分配
1179 if (data_.capacity() < data_.size() + cols_) {
1180 data_.reserve(data_.capacity() + std::max(data_.capacity(), cols_ * 2));
1181 }
1182
1183 // 计算插入位置
1184 const std::size_t insert_pos = pos * cols_;
1185 data_.insert(data_.begin() + insert_pos, std::make_move_iterator(row.begin()), std::make_move_iterator(row.end()));
1186 ++rows_;
1187}
1188
1201template< typename T >
1203{
1204 check_row_bounds(pos);
1205
1206 // 计算要删除的范围
1207 const std::size_t start_pos = pos * cols_;
1208 const std::size_t end_pos = start_pos + cols_;
1209
1210 data_.erase(data_.begin() + start_pos, data_.begin() + end_pos);
1211 --rows_;
1212}
1213
1229template<typename T>
1230template<typename InputIt>
1231void da_vector_table<T>::append_column(InputIt first, InputIt last)
1232{
1233 // 计算元素数量
1234 const std::size_t count = std::distance(first, last);
1235 if (count != rows_) {
1236 throw std::invalid_argument("Column size must match table row count");
1237 }
1238
1239 // 创建新向量,容量为添加一列后的大小
1240 std::vector<T> new_data;
1241 new_data.reserve(rows_ * (cols_ + 1));
1242
1243 // 复制现有数据并添加新列
1244 auto it = first;
1245 for (std::size_t i = 0; i < rows_; ++i) {
1246 const std::size_t row_start = i * cols_;
1247
1248 // 复制当前行的所有元素
1249 for (std::size_t j = 0; j < cols_; ++j) {
1250 new_data.push_back(std::move(data_[row_start + j]));
1251 }
1252
1253 // 添加新列的元素
1254 new_data.push_back(*it);
1255 ++it;
1256 }
1257
1258 // 更新数据
1259 data_ = std::move(new_data);
1260 ++cols_;
1261}
1262
1275template<typename T>
1276void da_vector_table<T>::append_column(const std::vector<T>& col)
1277{
1278 // 使用迭代器版本
1279 append_column(col.begin(), col.end());
1280}
1281
1294template<typename T>
1295void da_vector_table<T>::append_column(std::vector<T>&& col)
1296{
1297 // 使用迭代器版本
1298 append_column(std::make_move_iterator(col.begin()),
1299 std::make_move_iterator(col.end()));
1300}
1301
1314template<typename T>
1315void da_vector_table<T>::append_column(std::initializer_list<T> il)
1316{
1317 // 使用迭代器版本
1318 append_column(il.begin(), il.end());
1319}
1320
1335template< typename T >
1336void da_vector_table< T >::insert_column(std::size_t pos, const std::vector< T >& col)
1337{
1338 check_column_bounds(pos); // 允许在末尾插入(pos == cols_)
1339
1340 if (col.size() != rows_) {
1341 throw std::invalid_argument("Column size must match table row count");
1342 }
1343
1344 // 创建新向量,容量为插入一列后的大小
1345 std::vector< T > new_data;
1346 new_data.reserve(rows_ * (cols_ + 1));
1347
1348 // 复制数据并插入新列
1349 for (std::size_t i = 0; i < rows_; ++i) {
1350 const std::size_t row_start = i * cols_;
1351
1352 // 复制当前行中插入位置之前的元素
1353 for (std::size_t j = 0; j < pos; ++j) {
1354 new_data.push_back(data_[ row_start + j ]);
1355 }
1356
1357 // 插入新列的元素
1358 new_data.push_back(col[ i ]);
1359
1360 // 复制当前行中插入位置之后的元素
1361 for (std::size_t j = pos; j < cols_; ++j) {
1362 new_data.push_back(data_[ row_start + j ]);
1363 }
1364 }
1365
1366 // 更新数据
1367 data_ = std::move(new_data);
1368 ++cols_;
1369}
1370
1385template<typename T>
1386void da_vector_table<T>::insert_column(std::size_t pos, std::vector<T>&& col)
1387{
1388 check_column_bounds(pos); // 允许在末尾插入(pos == cols_)
1389
1390 if (col.size() != rows_) {
1391 throw std::invalid_argument("Column size must match table row count");
1392 }
1393
1394 // 创建新向量,容量为插入一列后的大小
1395 std::vector<T> new_data;
1396 new_data.reserve(rows_ * (cols_ + 1));
1397
1398 // 复制数据并插入新列
1399 for (std::size_t i = 0; i < rows_; ++i) {
1400 const std::size_t row_start = i * cols_;
1401
1402 // 复制当前行中插入位置之前的元素
1403 for (std::size_t j = 0; j < pos; ++j) {
1404 new_data.push_back(std::move(data_[row_start + j]));
1405 }
1406
1407 // 插入新列的元素(使用移动语义)
1408 new_data.push_back(std::move(col[i]));
1409
1410 // 复制当前行中插入位置之后的元素
1411 for (std::size_t j = pos; j < cols_; ++j) {
1412 new_data.push_back(std::move(data_[row_start + j]));
1413 }
1414 }
1415
1416 // 更新数据
1417 data_ = std::move(new_data);
1418 ++cols_;
1419}
1420
1435template< typename T >
1437{
1438 check_column_bounds(pos);
1439
1440 // 创建新向量,容量为移除一列后的大小
1441 std::vector< T > new_data;
1442 new_data.reserve(rows_ * (cols_ - 1));
1443
1444 // 复制除了指定列之外的所有元素
1445 for (std::size_t i = 0; i < rows_; ++i) {
1446 const std::size_t row_start = i * cols_;
1447
1448 // 复制当前行中指定列之前的元素
1449 for (std::size_t j = 0; j < pos; ++j) {
1450 new_data.push_back(data_[ row_start + j ]);
1451 }
1452
1453 // 跳过指定列,复制之后的元素
1454 for (std::size_t j = pos + 1; j < cols_; ++j) {
1455 new_data.push_back(data_[ row_start + j ]);
1456 }
1457 }
1458
1459 // 更新数据
1460 data_ = std::move(new_data);
1461 --cols_;
1462}
1463
1477template< typename T >
1479{
1480 return { rows_, cols_ };
1481}
1482
1494template< typename T >
1495std::size_t da_vector_table< T >::row_count() const noexcept
1496{
1497 return rows_;
1498}
1499
1511template< typename T >
1512std::size_t da_vector_table< T >::column_count() const noexcept
1513{
1514 return cols_;
1515}
1516
1531template< typename T >
1532void da_vector_table< T >::resize(std::size_t rows, std::size_t cols, const T& value)
1533{
1534 if (rows == rows_ && cols == cols_) {
1535 return;
1536 }
1537
1538 // 如果新大小小于等于当前容量,且列数不变,可以原地调整
1539 if (cols == cols_ && rows * cols <= data_.capacity()) {
1540 if (rows > rows_) {
1541 // 增加行数
1542 data_.resize(rows * cols, value);
1543 } else {
1544 // 减少行数
1545 data_.resize(rows * cols);
1546 }
1547 rows_ = rows;
1548 return;
1549 }
1550
1551 // 否则需要重新移动
1552 std::vector< T > new_data(rows * cols, value);
1553
1554 const std::size_t copy_rows = std::min(rows, rows_);
1555 const std::size_t copy_cols = std::min(cols, cols_);
1556
1557 for (std::size_t i = 0; i < copy_rows; ++i) {
1558 for (std::size_t j = 0; j < copy_cols; ++j) {
1559 new_data[ i * cols + j ] = data_[ i * cols_ + j ];
1560 }
1561 }
1562
1563 data_ = std::move(new_data);
1564 rows_ = rows;
1565 cols_ = cols;
1566}
1567
1581template< typename T >
1583{
1584 resize(sh.first, sh.second, value);
1585}
1586
1601template< typename T >
1602void da_vector_table< T >::reshape(std::size_t rows, std::size_t cols)
1603{
1604 if (rows * cols != data_.size()) {
1605 throw std::invalid_argument("New shape must have the same number of elements");
1606 }
1607
1608 rows_ = rows;
1609 cols_ = cols;
1610}
1611
1625template< typename T >
1626std::vector< T > da_vector_table< T >::get_row(std::size_t row) const
1627{
1628 check_row_bounds(row);
1629
1630 std::vector< T > result;
1631 result.reserve(cols_);
1632
1633 const std::size_t start = row * cols_;
1634 for (std::size_t i = 0; i < cols_; ++i) {
1635 result.push_back(data_[ start + i ]);
1636 }
1637
1638 return result;
1639}
1640
1654template< typename T >
1655std::vector< T > da_vector_table< T >::get_column(std::size_t col) const
1656{
1657 check_column_bounds(col);
1658
1659 std::vector< T > result;
1660 result.reserve(rows_);
1661
1662 for (std::size_t i = 0; i < rows_; ++i) {
1663 result.push_back(data_[ i * cols_ + col ]);
1664 }
1665
1666 return result;
1667}
1668
1683template< typename T >
1684void da_vector_table< T >::set_row(std::size_t row, const std::vector< T >& values)
1685{
1686 check_row_bounds(row);
1687
1688 if (values.size() != cols_) {
1689 throw std::invalid_argument("Number of values must match column count");
1690 }
1691
1692 const std::size_t start = row * cols_;
1693 for (std::size_t i = 0; i < cols_; ++i) {
1694 data_[ start + i ] = values[ i ];
1695 }
1696}
1697
1712template< typename T >
1713void da_vector_table< T >::set_column(std::size_t col, const std::vector< T >& values)
1714{
1715 check_column_bounds(col);
1716
1717 if (values.size() != rows_) {
1718 throw std::invalid_argument("Number of values must match row count");
1719 }
1720
1721 for (std::size_t i = 0; i < rows_; ++i) {
1722 data_[ i * cols_ + col ] = values[ i ];
1723 }
1724}
1725
1726// ============================================================================
1727// 私有辅助函数实现
1728// ============================================================================
1729
1737template< typename T >
1738std::size_t da_vector_table< T >::index(std::size_t row, std::size_t col) const noexcept
1739{
1740 return row * cols_ + col;
1741}
1742
1750template< typename T >
1751void da_vector_table< T >::check_bounds(std::size_t row, std::size_t col) const
1752{
1753 if (row >= rows_) {
1754 throw std::out_of_range("Row index out of range");
1755 }
1756 if (col >= cols_) {
1757 throw std::out_of_range("Column index out of range");
1758 }
1759}
1760
1767template< typename T >
1768void da_vector_table< T >::check_row_bounds(std::size_t row) const
1769{
1770 if (row > rows_) { // 允许在末尾插入,所以可以等于rows_
1771 throw std::out_of_range("Row index out of range");
1772 }
1773}
1774
1781template< typename T >
1782void da_vector_table< T >::check_column_bounds(std::size_t col) const
1783{
1784 if (col > cols_) { // 允许在末尾插入,所以可以等于cols_
1785 throw std::out_of_range("Column index out of range");
1786 }
1787}
1788
1789} // namespace DA
1790
1791#endif // DA_VECTOR_TABLE_H
二维表格数据结构,使用一维数组存储以提高缓存友好性
Definition da_vector_table.hpp:22
std::pair< std::size_t, std::size_t > table_index_type
表格形状类型(行数, 列数)
Definition da_vector_table.hpp:25
void swap(da_vector_table &other) noexcept
交换两个表格的内容
Definition da_vector_table.hpp:1004
void append_column(const std::vector< T > &col)
在表格末尾添加一列
Definition da_vector_table.hpp:1276
T & front()
访问表格的第一个元素
Definition da_vector_table.hpp:751
void push_back(const T &value)
在表格末尾添加一个元素
Definition da_vector_table.hpp:907
da_vector_table & operator=(const da_vector_table &other)
拷贝赋值运算符
Definition da_vector_table.hpp:278
void insert_row(std::size_t pos, const std::vector< T > &row)
在指定位置插入一行
Definition da_vector_table.hpp:1135
void insert_column(std::size_t pos, const std::vector< T > &col)
在指定位置插入一列
Definition da_vector_table.hpp:1336
void clear() noexcept
清空表格中的所有元素
Definition da_vector_table.hpp:984
T value_type
元素类型
Definition da_vector_table.hpp:24
T & at(std::size_t row, std::size_t col)
访问指定位置的元素,带边界检查
Definition da_vector_table.hpp:705
const_reverse_iterator crend() const noexcept
返回指向表格第一个元素前一个位置的常量反向迭代器
Definition da_vector_table.hpp:638
void append_row(const std::vector< T > &row)
在表格末尾添加一行
Definition da_vector_table.hpp:1024
void erase_column(std::size_t pos)
移除指定位置的列(高效版本)
Definition da_vector_table.hpp:1436
reverse_iterator rbegin() noexcept
返回指向表格最后一个元素的反向迭代器
Definition da_vector_table.hpp:543
void reshape(std::size_t rows, std::size_t cols)
改变表格形状而不改变数据总量
Definition da_vector_table.hpp:1602
std::size_t max_size() const noexcept
返回表格可容纳的最大元素数
Definition da_vector_table.hpp:358
std::size_t capacity() const noexcept
返回当前分配的存储容量
Definition da_vector_table.hpp:392
T * data() noexcept
返回指向底层数组的指针
Definition da_vector_table.hpp:822
void resize(std::size_t rows, std::size_t cols, const T &value=T())
调整表格大小
Definition da_vector_table.hpp:1532
std::size_t column_count() const noexcept
获取表格的列数
Definition da_vector_table.hpp:1512
std::vector< T > get_row(std::size_t row) const
获取指定行的数据
Definition da_vector_table.hpp:1626
iterator end() noexcept
返回指向表格尾后位置的迭代器
Definition da_vector_table.hpp:486
const_iterator cbegin() const noexcept
返回指向表格第一个元素的常量迭代器
Definition da_vector_table.hpp:467
da_vector_table()
默认构造函数
Definition da_vector_table.hpp:157
void assign(std::size_t rows, std::size_t cols, const T &value)
分配新内容替换当前内容
Definition da_vector_table.hpp:861
void shrink_to_fit()
请求移除未使用的容量
Definition da_vector_table.hpp:410
table_index_type shape() const noexcept
获取表格的形状(行数和列数)
Definition da_vector_table.hpp:1478
iterator begin() noexcept
返回指向表格第一个元素的迭代器
Definition da_vector_table.hpp:429
std::size_t row_count() const noexcept
获取表格的行数
Definition da_vector_table.hpp:1495
void set_row(std::size_t row, const std::vector< T > &values)
设置指定行的数据
Definition da_vector_table.hpp:1684
bool empty() const noexcept
检查表格是否为空
Definition da_vector_table.hpp:326
const_iterator cend() const noexcept
返回指向表格尾后位置的常量迭代器
Definition da_vector_table.hpp:524
void emplace_back(Args &&... args)
在表格末尾原位构造一个元素
Definition da_vector_table.hpp:949
std::vector< T > get_column(std::size_t col) const
获取指定列的数据
Definition da_vector_table.hpp:1655
void erase_row(std::size_t pos)
移除指定位置的行
Definition da_vector_table.hpp:1202
reverse_iterator rend() noexcept
返回指向表格第一个元素前一个位置的反向迭代器
Definition da_vector_table.hpp:600
T & back()
访问表格的最后一个元素
Definition da_vector_table.hpp:785
void pop_back()
移除表格的最后一个元素
Definition da_vector_table.hpp:967
std::size_t size() const noexcept
返回表格中的元素总数
Definition da_vector_table.hpp:342
void reserve(std::size_t new_cap)
预留存储空间
Definition da_vector_table.hpp:375
T & operator()(std::size_t row, std::size_t col)
访问指定位置的元素(函数调用运算符)
Definition da_vector_table.hpp:658
const_reverse_iterator crbegin() const noexcept
返回指向表格最后一个元素的常量反向迭代器
Definition da_vector_table.hpp:581
void set_column(std::size_t col, const std::vector< T > &values)
设置指定列的数据
Definition da_vector_table.hpp:1713
序列化类都是带异常的,使用中需要处理异常
Definition AppMainWindow.cpp:44