mdds
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 
19 namespace mdds { namespace mtv { namespace aos {
20 
48 template<typename Traits = mdds::mtv::default_traits>
50 {
51 public:
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 
74 private:
75  struct block
76  {
77  size_type position;
78  size_type size;
79  base_element_block* data;
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 
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 
161 public:
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 
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 
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 
1070  void shrink_to_fit();
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 
1094 private:
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 
1365 private:
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 mtv::element_t get_element_type(const T &elem)
Definition: iterator_node.hpp:18
size_type block_size() const noexcept
static position_type next_position(const position_type &pos)
Definition: main.hpp:49
static size_type logical_position(const const_position_type &pos) noexcept(std::is_fundamental_v< size_type >)
iterator insert_empty(size_type pos, size_type length)
iterator emplace_back(Args &&...args)
typename Traits::event_func event_func
Definition: main.hpp:72
Definition: iterator_node.hpp:85
iterator insert(size_type pos, const T &it_begin, const T &it_end)
void resize(size_type new_size)
static Blk::value_type get(const const_position_type &pos)
multi_type_vector() noexcept(nothrow_default_constructible_v)
void swap(multi_type_vector &other) noexcept(nothrow_swappable_v)
iterator release_range(size_type start_pos, size_type end_pos)
Definition: iterator_node.hpp:74
size_type size() const noexcept(std::is_nothrow_copy_constructible_v< size_type >)
position_type position(size_type pos)
iterator transfer(size_type start_pos, size_type end_pos, multi_type_vector &dest, size_type dest_pos)
static position_type advance_position(const position_type &pos, int steps)
Definition: cref_wrapper.hpp:12
multi_type_vector clone() const
iterator set(size_type pos, const T &value)
Definition: types.hpp:134
void erase(size_type start_pos, size_type end_pos)
bool empty() const noexcept
itr_node value_type
Definition: main.hpp:184
iterator set_empty(size_type start_pos, size_type end_pos)
bool is_empty(size_type pos) const
mtv::element_t get_type(size_type pos) const