215class element_block :
public base_element_block
218 using store_type = StoreT<ValueT, std::allocator<ValueT>>;
219 static constexpr element_t block_type = TypeId;
224 element_block()
noexcept(std::is_nothrow_default_constructible_v<store_type>) : base_element_block(TypeId)
226 element_block(
size_t n) : base_element_block(TypeId), m_array(n)
228 element_block(
size_t n,
const ValueT& val) : base_element_block(TypeId), m_array(n, val)
231 template<
typename Iter>
232 element_block(
const Iter& it_begin,
const Iter& it_end) : base_element_block(TypeId), m_array(it_begin, it_end)
236 typedef typename store_type::iterator iterator;
237 typedef typename store_type::reverse_iterator reverse_iterator;
238 typedef typename store_type::const_iterator const_iterator;
239 typedef typename store_type::const_reverse_iterator const_reverse_iterator;
240 typedef ValueT value_type;
242 const store_type& store()
const noexcept
247 store_type& store()
noexcept
253 template<
bool Mutable>
254 class base_range_type
256 using elem_block_type = mdds::detail::mutable_t<base_element_block, Mutable>;
257 elem_block_type& m_blk;
260 using iter_type = std::conditional_t<Mutable, iterator, const_iterator>;
262 base_range_type(elem_block_type& blk) : m_blk(blk)
267 return element_block::begin(m_blk);
272 return element_block::end(m_blk);
276 static constexpr bool nothrow_eq_comparable_v =
noexcept(std::declval<store_type>() == std::declval<store_type>());
279 using range_type = base_range_type<true>;
280 using const_range_type = base_range_type<false>;
282 bool operator==(
const Self& r)
const noexcept(nothrow_eq_comparable_v)
284 return m_array == r.m_array;
287 bool operator!=(
const Self& r)
const noexcept(nothrow_eq_comparable_v)
289 return !operator==(r);
292 static const value_type& at(
const base_element_block& block,
typename store_type::size_type pos)
294 return get(block).m_array.at(pos);
297 static value_type& at(base_element_block& block,
typename store_type::size_type pos)
299 return get(block).m_array.at(pos);
302 static value_type* data(base_element_block& block)
304 return get(block).m_array.data();
307 static typename store_type::size_type size(
const base_element_block& block)
309 return get(block).m_array.size();
312 static iterator begin(base_element_block& block)
314 return get(block).m_array.begin();
317 static iterator end(base_element_block& block)
319 return get(block).m_array.end();
322 static const_iterator begin(
const base_element_block& block)
324 return get(block).m_array.begin();
327 static const_iterator end(
const base_element_block& block)
329 return get(block).m_array.end();
332 static const_iterator cbegin(
const base_element_block& block)
334 return get(block).m_array.begin();
337 static const_iterator cend(
const base_element_block& block)
339 return get(block).m_array.end();
342 static reverse_iterator rbegin(base_element_block& block)
344 return get(block).m_array.rbegin();
347 static reverse_iterator rend(base_element_block& block)
349 return get(block).m_array.rend();
352 static const_reverse_iterator rbegin(
const base_element_block& block)
354 return get(block).m_array.rbegin();
357 static const_reverse_iterator rend(
const base_element_block& block)
359 return get(block).m_array.rend();
362 static const_reverse_iterator crbegin(
const base_element_block& block)
364 return get(block).m_array.rbegin();
367 static const_reverse_iterator crend(
const base_element_block& block)
369 return get(block).m_array.rend();
372 static const_range_type range(
const base_element_block& block)
374 return const_range_type(block);
377 static range_type range(base_element_block& block)
379 return range_type(block);
382 static Self& get(base_element_block& block)
384#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
387 std::ostringstream os;
388 os <<
"incorrect block type: expected block type=" << TypeId
393 return static_cast<Self&
>(block);
396 static const Self& get(
const base_element_block& block)
398#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
401 std::ostringstream os;
402 os <<
"incorrect block type: expected block type=" << TypeId
407 return static_cast<const Self&
>(block);
410 static void set_value(base_element_block& blk,
size_t pos,
const ValueT& val)
412 get(blk).m_array[pos] = val;
415 static void get_value(
const base_element_block& blk,
size_t pos, ValueT& val)
417 val = get(blk).m_array[pos];
420 static value_type get_value(
const base_element_block& blk,
size_t pos)
422 return get(blk).m_array[pos];
425 template<
typename T = ValueT>
426 static void append_value(base_element_block& blk, T&& val)
428 get(blk).m_array.push_back(std::forward<T>(val));
431 template<
typename... Args>
432 static void emplace_back_value(base_element_block& blk, Args&&... args)
434 get(blk).m_array.emplace_back(std::forward<Args>(args)...);
437 static void prepend_value(base_element_block& blk,
const ValueT& val)
439 store_type& blk2 = get(blk).m_array;
440 blk2.insert(blk2.begin(), val);
443 static Self* create_block(
size_t init_size)
445 return new Self(init_size);
448 static void delete_block(
const base_element_block* p)
450 delete static_cast<const Self*
>(p);
453 static void resize_block(base_element_block& blk,
size_t new_size)
455 store_type& st = get(blk).m_array;
460 if (new_size < (detail::get_block_capacity(st) / 2))
461 detail::shrink_to_fit(st);
465 static void print_block(
const base_element_block& blk)
467 const store_type& blk2 = get(blk).m_array;
468 for (
const auto& val : blk2)
469 std::cout << val <<
" ";
471 std::cout << std::endl;
474 static void print_block(
const base_element_block&)
478 static void erase_value(base_element_block& blk,
size_t pos)
480 store_type& blk2 = get(blk).m_array;
481 blk2.erase(blk2.begin() + pos);
484 static void erase_values(base_element_block& blk,
size_t pos,
size_t size)
486 store_type& blk2 = get(blk).m_array;
487 blk2.erase(blk2.begin() + pos, blk2.begin() + pos + size);
490 static void append_block(base_element_block& dest,
const base_element_block& src)
492 store_type& d = get(dest).m_array;
493 const store_type& s = get(src).m_array;
494 d.insert(d.end(), s.begin(), s.end());
497 static void append_values_from_block(
498 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
500 store_type& d = get(dest).m_array;
501 const store_type& s = get(src).m_array;
502 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
503 detail::reserve(d, d.size() + len);
504 d.insert(d.end(), its.first, its.second);
507 static void assign_values_from_block(
508 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
510 store_type& d = get(dest).m_array;
511 const store_type& s = get(src).m_array;
512 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
513 d.assign(its.first, its.second);
516 static void prepend_values_from_block(
517 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
519 store_type& d = get(dest).m_array;
520 const store_type& s = get(src).m_array;
521 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
522 detail::reserve(d, d.size() + len);
523 d.insert(d.begin(), its.first, its.second);
526 static void swap_values(base_element_block& blk1, base_element_block& blk2,
size_t pos1,
size_t pos2,
size_t len)
528 store_type& st1 = get(blk1).m_array;
529 store_type& st2 = get(blk2).m_array;
530 assert(pos1 + len <= st1.size());
531 assert(pos2 + len <= st2.size());
533 typename store_type::iterator it1 = st1.begin(), it2 = st2.begin();
534 std::advance(it1, pos1);
535 std::advance(it2, pos2);
537 for (
size_t i = 0; i < len; ++i, ++it1, ++it2)
539 value_type v1 = *it1, v2 = *it2;
545 static bool equal_block(
const base_element_block& left,
const base_element_block& right)
547 return get(left) == get(right);
550 template<
typename Iter>
551 static void set_values(base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
553 store_type& d = get(block).m_array;
554 typename store_type::iterator it_dest = d.begin();
555 std::advance(it_dest, pos);
556 for (Iter it = it_begin; it != it_end; ++it, ++it_dest)
560 template<
typename Iter>
561 static void append_values(base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
563 store_type& d = get(block).m_array;
564 typename store_type::iterator it = d.end();
565 d.insert(it, it_begin, it_end);
568 template<
typename Iter>
569 static void prepend_values(base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
571 store_type& d = get(block).m_array;
572 d.insert(d.begin(), it_begin, it_end);
575 template<
typename Iter>
576 static void assign_values(base_element_block& dest,
const Iter& it_begin,
const Iter& it_end)
578 store_type& d = get(dest).m_array;
579 d.assign(it_begin, it_end);
582 template<
typename Iter>
583 static void insert_values(base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
585 store_type& blk = get(block).m_array;
586 blk.insert(blk.begin() + pos, it_begin, it_end);
589 static size_t capacity(
const base_element_block& block)
591 const store_type& blk = get(block).m_array;
592 return detail::get_block_capacity(blk);
595 static void reserve(base_element_block& block, std::size_t size)
597 store_type& blk = get(block).m_array;
598 detail::reserve(blk, size);
601 static void shrink_to_fit(base_element_block& block)
603 store_type& blk = get(block).m_array;
604 detail::shrink_to_fit(blk);
608 static std::pair<const_iterator, const_iterator> get_iterator_pair(
609 const store_type& array,
size_t begin_pos,
size_t len)
611 assert(begin_pos + len <= array.size());
612 const_iterator it = array.begin();
613 std::advance(it, begin_pos);
614 const_iterator it_end = it;
615 std::advance(it_end, len);
616 return std::pair<const_iterator, const_iterator>(it, it_end);