29#ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_TYPES_2_HPP
30#define INCLUDED_MDDS_MULTI_TYPE_VECTOR_TYPES_2_HPP
32#include "../global.hpp"
33#include "./types_util.hpp"
41#if defined(MDDS_UNIT_TEST) || defined(MDDS_MULTI_TYPE_VECTOR_DEBUG)
49namespace mdds {
namespace mtv {
53constexpr element_t element_type_empty = -1;
55constexpr element_t element_type_reserved_start = 0;
56constexpr element_t element_type_reserved_end = 49;
58constexpr element_t element_type_user_start = 50;
66enum class lu_factor_t :
int
74 sse2_x64_lu4 = 1 << 8 | 4,
75 sse2_x64_lu8 = 1 << 8 | 8,
76 sse2_x64_lu16 = 1 << 8 | 16,
78 avx2_x64_lu4 = 2 << 8 | 4,
79 avx2_x64_lu8 = 2 << 8 | 8,
101enum class trace_method_t :
int
105 accessor_with_pos_hint = 1 << 8 | 1,
107 mutator_with_pos_hint = 1 << 8 | 2,
117 trace_method_t type = trace_method_t::unspecified;
174template<
typename T,
typename Allocator = std::allocator<T>>
177 typedef std::vector<T, Allocator> store_type;
179 size_t m_front_offset = 0;
181 typedef typename store_type::value_type value_type;
182 typedef typename store_type::size_type size_type;
183 typedef typename store_type::difference_type difference_type;
184 typedef typename store_type::reference reference;
185 typedef typename store_type::const_reference const_reference;
186 typedef typename store_type::pointer pointer;
187 typedef typename store_type::const_pointer const_pointer;
188 typedef typename store_type::iterator iterator;
189 typedef typename store_type::reverse_iterator reverse_iterator;
190 typedef typename store_type::const_iterator const_iterator;
191 typedef typename store_type::const_reverse_iterator const_reverse_iterator;
202 template<
typename InputIt>
206 iterator begin()
noexcept
208 return m_vec.begin() + m_front_offset;
211 iterator end()
noexcept
216 const_iterator begin()
const noexcept
218 return m_vec.begin() + m_front_offset;
221 const_iterator end()
const noexcept
226 reverse_iterator rbegin()
noexcept
228 return m_vec.rbegin();
231 const_reverse_iterator rbegin()
const noexcept
233 return m_vec.rbegin();
236 reverse_iterator rend()
noexcept
238 return m_vec.rend() - m_front_offset;
241 const_reverse_iterator rend()
const noexcept
243 return m_vec.rend() - m_front_offset;
246 reference operator[](size_type pos)
248 return m_vec[pos + m_front_offset];
251 const_reference operator[](size_type pos)
const
253 return m_vec[pos + m_front_offset];
256 reference at(size_type pos)
258 return m_vec.at(pos + m_front_offset);
261 const_reference at(size_type pos)
const
263 return m_vec.at(pos + m_front_offset);
266 void push_back(
const T& value)
268 m_vec.push_back(value);
271 iterator insert(iterator pos,
const T& value)
273 return m_vec.insert(pos, value);
276 iterator insert(const_iterator pos, T&& value)
278 return m_vec.insert(pos, std::move(value));
281 template<
typename InputIt>
282 void insert(iterator pos, InputIt first, InputIt last)
284 m_vec.insert(pos, first, last);
287 void resize(size_type count)
293 iterator erase(iterator pos)
295 if (pos == m_vec.begin() + m_front_offset)
298 return m_vec.begin() + m_front_offset;
301 return m_vec.erase(pos);
304 iterator erase(iterator first, iterator last)
306 return m_vec.erase(first, last);
309 size_type capacity()
const noexcept
311 return m_vec.capacity();
317 m_vec.shrink_to_fit();
320 void reserve(size_type new_cap)
323 m_vec.reserve(new_cap);
326 size_type size()
const
328 return m_vec.size() - m_front_offset;
331 template<
typename InputIt>
332 void assign(InputIt first, InputIt last)
335 m_vec.assign(first, last);
340 return m_vec.data() + m_front_offset;
343 const T* data()
const
345 return m_vec.data() + m_front_offset;
351 m_vec.erase(m_vec.begin(), m_vec.begin() + m_front_offset);
361 using type = std::true_type;
369 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
372template<
typename Self, element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT>
376 using store_type = StoreT<ValueT, std::allocator<ValueT>>;
377 static constexpr element_t block_type = TypeId;
389 template<
typename Iter>
394 typedef typename store_type::iterator iterator;
395 typedef typename store_type::reverse_iterator reverse_iterator;
396 typedef typename store_type::const_iterator const_iterator;
397 typedef typename store_type::const_reverse_iterator const_reverse_iterator;
398 typedef ValueT value_type;
401 template<
bool Mutable>
402 class base_range_type
404 using block_type = mdds::detail::mutable_t<base_element_block, Mutable>;
408 using iter_type = std::conditional_t<Mutable, iterator, const_iterator>;
410 base_range_type(block_type& blk) : m_blk(blk)
415 return element_block::begin(m_blk);
420 return element_block::end(m_blk);
425 using range_type = base_range_type<true>;
426 using const_range_type = base_range_type<false>;
428 bool operator==(
const Self& r)
const
430 return m_array == r.m_array;
433 bool operator!=(
const Self& r)
const
435 return !operator==(r);
438 static const value_type& at(
const base_element_block& block,
typename store_type::size_type pos)
440 return get(block).m_array.at(pos);
445 return get(block).m_array.at(pos);
450 return get(block).m_array.data();
455 return get(block).m_array.size();
460 return get(block).m_array.begin();
465 return get(block).m_array.end();
470 return get(block).m_array.begin();
475 return get(block).m_array.end();
480 return get(block).m_array.begin();
485 return get(block).m_array.end();
490 return get(block).m_array.rbegin();
495 return get(block).m_array.rend();
500 return get(block).m_array.rbegin();
505 return get(block).m_array.rend();
510 return get(block).m_array.rbegin();
515 return get(block).m_array.rend();
520 return const_range_type(block);
525 return range_type(block);
530#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
533 std::ostringstream os;
534 os <<
"incorrect block type: expected block type=" << TypeId
539 return static_cast<Self&
>(block);
544#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
547 std::ostringstream os;
548 os <<
"incorrect block type: expected block type=" << TypeId
553 return static_cast<const Self&
>(block);
558 get(blk).m_array[pos] = val;
563 val = get(blk).m_array[pos];
568 return get(blk).m_array[pos];
573 get(blk).m_array.push_back(val);
578 store_type& blk2 = get(blk).m_array;
579 blk2.insert(blk2.begin(), val);
582 static Self* create_block(
size_t init_size)
584 return new Self(init_size);
589 delete static_cast<const Self*
>(p);
594 store_type& st = get(blk).m_array;
599 if (new_size < (detail::get_block_capacity(st) / 2))
600 detail::shrink_to_fit(st);
606 const store_type& blk2 = get(blk).m_array;
607 for (
const auto& val : blk2)
608 std::cout << val <<
" ";
610 std::cout << std::endl;
619 store_type& blk2 = get(blk).m_array;
620 blk2.erase(blk2.begin() + pos);
625 store_type& blk2 = get(blk).m_array;
626 blk2.erase(blk2.begin() + pos, blk2.begin() + pos + size);
631 store_type& d = get(dest).m_array;
632 const store_type& s = get(src).m_array;
633 d.insert(d.end(), s.begin(), s.end());
636 static void append_values_from_block(
639 store_type& d = get(dest).m_array;
640 const store_type& s = get(src).m_array;
641 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
642 detail::reserve(d, d.size() + len);
643 d.insert(d.end(), its.first, its.second);
646 static void assign_values_from_block(
649 store_type& d = get(dest).m_array;
650 const store_type& s = get(src).m_array;
651 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
652 d.assign(its.first, its.second);
655 static void prepend_values_from_block(
658 store_type& d = get(dest).m_array;
659 const store_type& s = get(src).m_array;
660 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
661 detail::reserve(d, d.size() + len);
662 d.insert(d.begin(), its.first, its.second);
667 store_type& st1 = get(blk1).m_array;
668 store_type& st2 = get(blk2).m_array;
669 assert(pos1 + len <= st1.size());
670 assert(pos2 + len <= st2.size());
672 typename store_type::iterator it1 = st1.begin(), it2 = st2.begin();
673 std::advance(it1, pos1);
674 std::advance(it2, pos2);
676 for (
size_t i = 0; i < len; ++i, ++it1, ++it2)
678 value_type v1 = *it1, v2 = *it2;
686 return get(left) == get(right);
689 template<
typename Iter>
690 static void set_values(
base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
692 store_type& d = get(block).m_array;
693 typename store_type::iterator it_dest = d.begin();
694 std::advance(it_dest, pos);
695 for (Iter it = it_begin; it != it_end; ++it, ++it_dest)
699 template<
typename Iter>
700 static void append_values(
base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
702 store_type& d = get(block).m_array;
703 typename store_type::iterator it = d.end();
704 d.insert(it, it_begin, it_end);
707 template<
typename Iter>
708 static void prepend_values(
base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
710 store_type& d = get(block).m_array;
711 d.insert(d.begin(), it_begin, it_end);
714 template<
typename Iter>
715 static void assign_values(
base_element_block& dest,
const Iter& it_begin,
const Iter& it_end)
717 store_type& d = get(dest).m_array;
718 d.assign(it_begin, it_end);
721 template<
typename Iter>
722 static void insert_values(
base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
724 store_type& blk = get(block).m_array;
725 blk.insert(blk.begin() + pos, it_begin, it_end);
730 const store_type& blk = get(block).m_array;
731 return detail::get_block_capacity(blk);
736 store_type& blk = get(block).m_array;
737 detail::reserve(blk, size);
742 store_type& blk = get(block).m_array;
743 detail::shrink_to_fit(blk);
747 static std::pair<const_iterator, const_iterator> get_iterator_pair(
748 const store_type& array,
size_t begin_pos,
size_t len)
750 assert(begin_pos + len <= array.size());
751 const_iterator it = array.begin();
752 std::advance(it, begin_pos);
753 const_iterator it_end = it;
754 std::advance(it_end, len);
755 return std::pair<const_iterator, const_iterator>(it, it_end);
759template<
typename Self, element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT>
772 template<
typename Iter>
777 using base_type::get;
782 return new Self(get(blk));
786template<
typename Self, element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT>
799 template<
typename Iter>
829template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
843 template<
typename Iter>
847 static self_type* create_block_with_value(
size_t init_size,
const ValueT& val)
852 template<
typename Iter>
853 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
868template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
875 using base_type::get;
876 using base_type::m_array;
877 using base_type::reserve;
878 using base_type::set_value;
886 detail::reserve(m_array, r.m_array.size());
887 for (
const auto& v : r.m_array)
888 m_array.push_back(
new ValueT(*v));
891 template<
typename Iter>
897 std::for_each(m_array.begin(), m_array.end(), std::default_delete<ValueT>());
900 static self_type* create_block_with_value(
size_t init_size, ValueT* val)
904 throw general_error(
"You can't create a managed block with initial value.");
906 std::unique_ptr<self_type> blk = std::make_unique<self_type>(init_size);
908 set_value(*blk, 0, val);
910 return blk.release();
913 template<
typename Iter>
914 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
922 typename managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
923 typename managed_element_block::store_type::iterator it_end = it + len;
924 std::for_each(it, it_end, std::default_delete<ValueT>());
928template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
931 noncopyable_managed_element_block<TypeId, ValueT, StoreT>, TypeId, ValueT*, StoreT>
936 using base_type::get;
937 using base_type::m_array;
938 using base_type::set_value;
945 template<
typename Iter>
951 std::for_each(m_array.begin(), m_array.end(), std::default_delete<ValueT>());
954 static self_type* create_block_with_value(
size_t init_size, ValueT* val)
958 throw general_error(
"You can't create a managed block with initial value.");
960 std::unique_ptr<self_type> blk = std::make_unique<self_type>(init_size);
962 set_value(*blk, 0, val);
964 return blk.release();
967 template<
typename Iter>
968 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
976 typename noncopyable_managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
977 typename noncopyable_managed_element_block::store_type::iterator it_end = it + len;
978 std::for_each(it, it_end, std::default_delete<ValueT>());
984template<
typename Blk>
987 auto it = Blk::cbegin(data);
988 std::advance(it, offset);
992template<
typename Blk>
995 return Blk::at(data, offset);
998template<
typename Blk>
1001 typename mdds::mtv::detail::has_std_vector_bool_store<Blk>::type v;
1002 return get_block_element_at<Blk>(data, offset, v);
Definition: global.hpp:84
Definition: types.hpp:160
friend element_t get_block_type(const base_element_block &)
Definition: types.hpp:820
Definition: types.hpp:761
Definition: types.hpp:176
Definition: types.hpp:146
Definition: types.hpp:374
Definition: types.hpp:788
Definition: types.hpp:832
Definition: types_util.hpp:147
Definition: types.hpp:871
Definition: types.hpp:932
Definition: types.hpp:116
std::string function_args
Definition: types.hpp:133
const char * function_name
Definition: types.hpp:127
int line_number
Definition: types.hpp:139
const void * instance
Definition: types.hpp:124
const char * filepath
Definition: types.hpp:136