218 using store_type = StoreT<ValueT, std::allocator<ValueT>>;
219 static constexpr element_t block_type = TypeId;
231 template<
typename Iter>
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);
299 return get(block).m_array.at(pos);
304 return get(block).m_array.data();
309 return get(block).m_array.size();
314 return get(block).m_array.begin();
319 return get(block).m_array.end();
324 return get(block).m_array.begin();
329 return get(block).m_array.end();
334 return get(block).m_array.begin();
339 return get(block).m_array.end();
344 return get(block).m_array.rbegin();
349 return get(block).m_array.rend();
354 return get(block).m_array.rbegin();
359 return get(block).m_array.rend();
364 return get(block).m_array.rbegin();
369 return get(block).m_array.rend();
374 return const_range_type(block);
379 return range_type(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);
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);
412 get(blk).m_array[pos] = val;
417 val = get(blk).m_array[pos];
422 return get(blk).m_array[pos];
425 template<
typename T = ValueT>
428 get(blk).m_array.push_back(std::forward<T>(val));
431 template<
typename... Args>
434 get(blk).m_array.emplace_back(std::forward<Args>(args)...);
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);
450 delete static_cast<const Self*
>(p);
455 store_type& st = get(blk).m_array;
460 if (new_size < (detail::get_block_capacity(st) / 2))
461 detail::shrink_to_fit(st);
467 const store_type& blk2 = get(blk).m_array;
468 for (
const auto& val : blk2)
469 std::cout << val <<
" ";
471 std::cout << std::endl;
480 store_type& blk2 = get(blk).m_array;
481 blk2.erase(blk2.begin() + pos);
486 store_type& blk2 = get(blk).m_array;
487 blk2.erase(blk2.begin() + pos, blk2.begin() + pos + size);
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(
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(
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(
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);
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;
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);
591 const store_type& blk = get(block).m_array;
592 return detail::get_block_capacity(blk);
597 store_type& blk = get(block).m_array;
598 detail::reserve(blk, size);
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);