mdds
Loading...
Searching...
No Matches
aos/main.hpp
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3// SPDX-FileCopyrightText: 2021 - 2025 Kohei Yoshida
4//
5// SPDX-License-Identifier: MIT
6
7#pragma once
8
9#include "../../global.hpp"
10#include "../types.hpp"
11#include "../util.hpp"
12#include "./iterator.hpp"
13#include "./block_util.hpp"
14
15#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
16#include <iostream>
17#endif
18
19namespace mdds { namespace mtv { namespace aos {
20
48template<typename Traits = mdds::mtv::default_traits>
49class multi_type_vector
50{
51public:
52 using size_type = std::size_t;
53 using block_funcs = typename Traits::block_funcs;
54
72 using event_func = typename Traits::event_func;
73
74private:
75 struct block
76 {
77 size_type position;
78 size_type size;
80
81 block() noexcept(std::is_fundamental_v<size_type>);
82 block(size_type _position, size_type _size) noexcept(std::is_fundamental_v<size_type>);
83 block(size_type _position, size_type _size, base_element_block* _data) noexcept(
84 std::is_fundamental_v<size_type>);
85 block(const block& other) = default;
86 block(block&& other) = default;
87 ~block() = default;
88
89 block& operator=(const block&) = default;
90 block& operator=(block&&) = default;
91
92 void swap(block& other) noexcept(std::is_fundamental_v<size_type>);
93 };
94
95 struct element_block_deleter
96 {
97 void operator()(const base_element_block* p)
98 {
99 block_funcs::delete_block(p);
100 }
101 };
102
103 typedef std::vector<block> blocks_type;
104
105 struct blocks_to_transfer
106 {
107 blocks_type blocks;
108 size_type insert_index;
109
110 blocks_to_transfer();
111 };
112
113 struct iterator_trait
114 {
115 typedef multi_type_vector parent;
116 typedef blocks_type blocks;
117 typedef typename blocks_type::iterator base_iterator;
118 };
119
120 struct reverse_iterator_trait
121 {
122 typedef multi_type_vector parent;
123 typedef blocks_type blocks;
124 typedef typename blocks_type::reverse_iterator base_iterator;
125 };
126
127 struct const_iterator_trait
128 {
129 typedef multi_type_vector parent;
130 typedef blocks_type blocks;
131 typedef typename blocks_type::const_iterator base_iterator;
132 };
133
134 struct const_reverse_iterator_trait
135 {
136 typedef multi_type_vector parent;
137 typedef blocks_type blocks;
138 typedef typename blocks_type::const_reverse_iterator base_iterator;
139 };
140
141 typedef mdds::detail::mtv::iterator_value_node<multi_type_vector, size_type> itr_node;
142 typedef mdds::detail::mtv::private_data_forward_update<multi_type_vector, size_type> itr_forward_update;
143 typedef mdds::detail::mtv::private_data_no_update<multi_type_vector, size_type> itr_no_update;
144
145 static constexpr bool nothrow_default_constructible_v = std::is_nothrow_default_constructible_v<event_func> &&
146 std::is_nothrow_default_constructible_v<blocks_type> &&
147 std::is_nothrow_default_constructible_v<size_type>;
148
149 static constexpr bool nothrow_move_constructible_v = std::is_nothrow_move_constructible_v<event_func> &&
150 std::is_nothrow_move_constructible_v<blocks_type> &&
151 std::is_nothrow_move_constructible_v<size_type>;
152
153 static constexpr bool nothrow_swappable_v = std::is_nothrow_swappable_v<event_func> &&
154 std::is_nothrow_swappable_v<size_type> &&
155 std::is_nothrow_swappable_v<blocks_type>;
156
157 static constexpr bool nothrow_move_assignable_v = nothrow_move_constructible_v && nothrow_swappable_v;
158
159 multi_type_vector(mtv::detail::clone_construction_type, const multi_type_vector& other);
160
161public:
162 typedef detail::iterator_base<iterator_trait, itr_forward_update> iterator;
163 typedef detail::iterator_base<reverse_iterator_trait, itr_no_update> reverse_iterator;
164
165 typedef detail::const_iterator_base<const_iterator_trait, itr_forward_update, iterator> const_iterator;
166 typedef detail::const_iterator_base<const_reverse_iterator_trait, itr_no_update, reverse_iterator>
167 const_reverse_iterator;
168
184 typedef itr_node value_type;
185
186 typedef std::pair<iterator, size_type> position_type;
187 typedef std::pair<const_iterator, size_type> const_position_type;
188
197 static position_type next_position(const position_type& pos);
198
208 static position_type advance_position(const position_type& pos, int steps);
209
218 static const_position_type next_position(const const_position_type& pos);
219
229 static const_position_type advance_position(const const_position_type& pos, int steps);
230
239 static size_type logical_position(const const_position_type& pos) noexcept(std::is_fundamental_v<size_type>);
240
249 template<typename Blk>
250 static typename Blk::value_type get(const const_position_type& pos);
251
252 iterator begin();
253 iterator end();
254
255 const_iterator begin() const;
256 const_iterator end() const;
257
258 const_iterator cbegin() const;
259 const_iterator cend() const;
260
261 reverse_iterator rbegin();
262 reverse_iterator rend();
263
264 const_reverse_iterator rbegin() const;
265 const_reverse_iterator rend() const;
266
267 const_reverse_iterator crbegin() const;
268 const_reverse_iterator crend() const;
269
270 event_func& event_handler();
271 const event_func& event_handler() const;
272
276 multi_type_vector() noexcept(nothrow_default_constructible_v);
277
284 multi_type_vector(const event_func& hdl);
285
292 multi_type_vector(event_func&& hdl);
293
301 multi_type_vector(size_type init_size);
302
312 template<typename T>
313 multi_type_vector(size_type init_size, const T& value);
314
328 template<typename T>
329 multi_type_vector(size_type init_size, const T& it_begin, const T& it_end);
330
336 multi_type_vector(const multi_type_vector& other);
337
343 multi_type_vector(multi_type_vector&& other) noexcept(nothrow_move_constructible_v);
344
348 ~multi_type_vector();
349
363 multi_type_vector clone() const;
364
381 template<typename T>
382 iterator set(size_type pos, const T& value);
383
416 template<typename T>
417 iterator set(const iterator& pos_hint, size_type pos, const T& value);
418
440 template<typename T>
441 iterator set(size_type pos, const T& it_begin, const T& it_end);
442
480 template<typename T>
481 iterator set(const iterator& pos_hint, size_type pos, const T& it_begin, const T& it_end);
482
499 template<typename T>
500 iterator push_back(T&& value);
501
509 iterator push_back_empty();
510
528 template<typename T, typename... Args>
529 iterator emplace_back(Args&&... args);
530
552 template<typename T>
553 iterator insert(size_type pos, const T& it_begin, const T& it_end);
554
592 template<typename T>
593 iterator insert(const iterator& pos_hint, size_type pos, const T& it_begin, const T& it_end);
594
605 template<typename T>
606 void get(size_type pos, T& value) const;
607
619 template<typename T>
620 T get(size_type pos) const;
621
636 template<typename T>
637 T release(size_type pos);
638
655 template<typename T>
656 iterator release(size_type pos, T& value);
657
677 template<typename T>
678 iterator release(const iterator& pos_hint, size_type pos, T& value);
679
688 void release();
689
705 iterator release_range(size_type start_pos, size_type end_pos);
706
731 iterator release_range(const iterator& pos_hint, size_type start_pos, size_type end_pos);
732
749 position_type position(size_type pos);
750
770 position_type position(const iterator& pos_hint, size_type pos);
771
785 const_position_type position(size_type pos) const;
786
803 const_position_type position(const const_iterator& pos_hint, size_type pos) const;
804
829 iterator transfer(size_type start_pos, size_type end_pos, multi_type_vector& dest, size_type dest_pos);
830
858 iterator transfer(
859 const iterator& pos_hint, size_type start_pos, size_type end_pos, multi_type_vector& dest, size_type dest_pos);
860
868 mtv::element_t get_type(size_type pos) const;
869
881 bool is_empty(size_type pos) const;
882
896 iterator set_empty(size_type start_pos, size_type end_pos);
897
927 iterator set_empty(const iterator& pos_hint, size_type start_pos, size_type end_pos);
928
944 void erase(size_type start_pos, size_type end_pos);
945
964 iterator insert_empty(size_type pos, size_type length);
965
1000 iterator insert_empty(const iterator& pos_hint, size_type pos, size_type length);
1001
1006 void clear();
1007
1013 size_type size() const noexcept(std::is_nothrow_copy_constructible_v<size_type>);
1014
1032 size_type block_size() const noexcept;
1033
1039 bool empty() const noexcept;
1040
1048 void resize(size_type new_size);
1049
1055 void swap(multi_type_vector& other) noexcept(nothrow_swappable_v);
1056
1065 void swap(size_type start_pos, size_type end_pos, multi_type_vector& other, size_type other_pos);
1066
1071
1072 bool operator==(const multi_type_vector& other) const;
1073 bool operator!=(const multi_type_vector& other) const;
1074
1075 multi_type_vector& operator=(const multi_type_vector& other);
1076 multi_type_vector& operator=(multi_type_vector&& other) noexcept(nothrow_move_assignable_v);
1077
1085 template<typename T>
1086 static mtv::element_t get_element_type(const T& elem);
1087
1088#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
1089 void dump_blocks(std::ostream& os) const;
1090
1091 void check_block_integrity() const;
1092#endif
1093
1094private:
1101 void delete_element_block(block& blk);
1102
1110 void delete_element_blocks(typename blocks_type::iterator it, typename blocks_type::iterator it_end);
1111
1112 template<typename T>
1113 iterator set_impl(size_type pos, size_type block_index, const T& value);
1114
1115 template<typename T>
1116 iterator release_impl(size_type pos, size_type block_index, T& value);
1117
1118 template<typename T>
1119 iterator push_back_impl(T&& value);
1120
1121 template<typename T, typename... Args>
1122 iterator emplace_back_impl(Args&&... args);
1123
1133 size_type get_block_position(size_type row, size_type start_block_index = 0) const;
1134
1139 size_type get_block_position(const typename value_type::private_data& pos_data, size_type row) const;
1140
1141 void resize_impl(size_type new_size);
1142
1143 template<typename T>
1144 void create_new_block_with_new_cell(base_element_block*& data, T&& cell);
1145
1146 template<typename T, typename... Args>
1147 void create_new_block_with_emplace_back(base_element_block*& data, const T& t, Args&&... args);
1148
1149 template<typename T>
1150 iterator set_cell_to_middle_of_block(size_type block_index, size_type pos_in_block, const T& cell);
1151
1152 template<typename T>
1153 void append_cell_to_block(size_type block_index, const T& cell);
1154
1155 template<typename T>
1156 iterator set_cell_to_empty_block(size_type block_index, size_type pos_in_block, const T& cell);
1157
1158 template<typename T>
1159 iterator set_cell_to_block_of_size_one(size_type block_index, const T& cell);
1160
1161 template<typename T>
1162 void set_cell_to_top_of_data_block(size_type block_index, const T& cell);
1163
1164 template<typename T>
1165 void set_cell_to_bottom_of_data_block(size_type block_index, const T& cell);
1166
1167 iterator transfer_impl(
1168 size_type start_pos, size_type end_pos, size_type block_index1, multi_type_vector& dest, size_type dest_pos);
1169
1173 iterator transfer_single_block(
1174 size_type start_pos, size_type end_pos, size_type block_index1, multi_type_vector& dest, size_type dest_pos);
1175
1180 iterator transfer_multi_blocks(
1181 size_type start_pos, size_type end_pos, size_type block_index1, size_type block_index2, multi_type_vector& dest,
1182 size_type dest_pos);
1183
1192 iterator set_empty_impl(size_type start_pos, size_type end_pos, size_type block_index1, bool overwrite);
1193
1194 void swap_impl(
1195 multi_type_vector& other, size_type start_pos, size_type end_pos, size_type other_pos, size_type block_index1,
1196 size_type block_index2, size_type dblock_index1, size_type dblock_index2);
1197
1198 void swap_single_block(
1199 multi_type_vector& other, size_type start_pos, size_type end_pos, size_type other_pos, size_type block_index,
1200 size_type other_block_index);
1201
1202 void swap_single_to_multi_blocks(
1203 multi_type_vector& other, size_type start_pos, size_type end_pos, size_type other_pos, size_type block_index,
1204 size_type dst_block_index1, size_type dst_block_index2);
1205
1206 void swap_multi_to_multi_blocks(
1207 multi_type_vector& other, size_type start_pos, size_type end_pos, size_type other_pos, size_type block_index1,
1208 size_type block_index2, size_type dblock_index1, size_type dblock_index2);
1209
1210 void insert_blocks_at(size_type position, size_type insert_pos, blocks_type& new_blocks);
1211
1212 void prepare_blocks_to_transfer(
1213 blocks_to_transfer& bucket, size_type block_index1, size_type offset1, size_type block_index2,
1214 size_type offset2);
1215
1216 iterator set_whole_block_empty(size_type block_index, bool overwrite);
1217
1218 iterator set_empty_in_single_block(size_type start_row, size_type end_row, size_type block_index, bool overwrite);
1219
1229 iterator set_empty_in_multi_blocks(
1230 size_type start_row, size_type end_row, size_type block_index1, size_type block_index2, bool overwrite);
1231
1232 void erase_impl(size_type start_pos, size_type end_pos);
1233 void erase_in_single_block(size_type start_pos, size_type end_pos, size_type block_pos);
1234
1240 iterator insert_empty_impl(size_type pos, size_type block_index, size_type length);
1241
1242 template<typename T>
1243 iterator set_cells_impl(
1244 size_type row, size_type end_row, size_type block_index1, const T& it_begin, const T& it_end);
1245
1246 template<typename T>
1247 iterator insert_cells_impl(size_type row, size_type block_index, const T& it_begin, const T& it_end);
1248
1249 template<typename T>
1250 iterator set_cells_to_single_block(
1251 size_type start_row, size_type end_row, size_type block_index, const T& it_begin, const T& it_end);
1252
1253 template<typename T>
1254 iterator set_cells_to_multi_blocks(
1255 size_type start_row, size_type end_row, size_type block_index1, size_type block_index2, const T& it_begin,
1256 const T& it_end);
1257
1258 template<typename T>
1259 iterator set_cells_to_multi_blocks_block1_non_equal(
1260 size_type start_row, size_type end_row, size_type block_index1, size_type block_index2, const T& it_begin,
1261 const T& it_end);
1262
1263 template<typename T>
1264 iterator set_cells_to_multi_blocks_block1_non_empty(
1265 size_type start_row, size_type end_row, size_type block_index1, size_type block_index2, const T& it_begin,
1266 const T& it_end);
1267
1276 size_type merge_with_adjacent_blocks(size_type block_index);
1277
1285 bool merge_with_next_block(size_type block_index);
1286
1287 template<typename T>
1288 bool append_to_prev_block(
1289 size_type block_index, element_t cat, size_type length, const T& it_begin, const T& it_end);
1290
1291 template<typename T>
1292 void insert_cells_to_middle(size_type row, size_type block_index, const T& it_begin, const T& it_end);
1293
1307 block& set_new_block_to_middle(size_type block_index, size_type offset, size_type new_block_size, bool overwrite);
1308
1309 block* get_previous_block_of_type(size_type block_index, element_t cat);
1310
1318 block* get_next_block_of_type(size_type block_index, element_t cat);
1319
1337 base_element_block* exchange_elements(
1338 const base_element_block& src_data, size_type src_offset, size_type dst_index, size_type dst_offset,
1339 size_type len);
1340
1341 void exchange_elements(
1342 const base_element_block& src_data, size_type src_offset, size_type dst_index1, size_type dst_offset1,
1343 size_type dst_index2, size_type dst_offset2, size_type len, blocks_type& new_blocks);
1344
1345 bool append_empty(size_type len);
1346
1347 inline iterator get_iterator(size_type block_index)
1348 {
1349 typename blocks_type::iterator block_pos = m_blocks.begin();
1350 std::advance(block_pos, block_index);
1351 return iterator(block_pos, m_blocks.end(), this, block_index);
1352 }
1353
1354 inline const_iterator get_const_iterator(size_type block_index) const
1355 {
1356 typename blocks_type::const_iterator block_pos = m_blocks.begin();
1357 std::advance(block_pos, block_index);
1358 return const_iterator(block_pos, m_blocks.end(), this, block_index);
1359 }
1360
1361#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
1362 void debug_check_full(std::string_view location);
1363#endif
1364
1365private:
1366 using adjust_block_positions_func = detail::adjust_block_positions<blocks_type, Traits::loop_unrolling>;
1367
1368 event_func m_hdl_event;
1369 blocks_type m_blocks;
1370 size_type m_cur_size;
1371};
1372
1373}}} // namespace mdds::mtv::aos
1374
1375#include "main_def.inl"
1376
1377/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const_position_type next_position(const const_position_type &pos)
static mtv::element_t get_element_type(const T &elem)
bool empty() const noexcept
void erase(size_type start_pos, size_type end_pos)
static size_type logical_position(const const_position_type &pos) noexcept(std::is_fundamental_v< size_type >)
bool is_empty(size_type pos) const
multi_type_vector clone() const
multi_type_vector() noexcept(nothrow_default_constructible_v)
typename Traits::event_func event_func
Definition aos/main.hpp:72
position_type position(size_type pos)
static position_type next_position(const position_type &pos)
itr_node value_type
Definition aos/main.hpp:184
iterator set(size_type pos, const T &value)
static Blk::value_type get(const const_position_type &pos)
static position_type advance_position(const position_type &pos, int steps)
iterator set_empty(size_type start_pos, size_type end_pos)
size_type size() const noexcept(std::is_nothrow_copy_constructible_v< size_type >)
size_type block_size() const noexcept
iterator insert(size_type pos, const T &it_begin, const T &it_end)
static const_position_type advance_position(const const_position_type &pos, int steps)
void resize(size_type new_size)
iterator transfer(size_type start_pos, size_type end_pos, multi_type_vector &dest, size_type dest_pos)
mtv::element_t get_type(size_type pos) const
iterator emplace_back(Args &&... args)
iterator insert_empty(size_type pos, size_type length)
iterator release_range(size_type start_pos, size_type end_pos)
void swap(multi_type_vector &other) noexcept(nothrow_swappable_v)
Definition types.hpp:135
multi_type_vector() noexcept(nothrow_default_constructible_v)