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;
400 bool operator==(
const Self& r)
const
402 return m_array == r.m_array;
405 bool operator!=(
const Self& r)
const
407 return !operator==(r);
410 static const value_type& at(
const base_element_block& block,
typename store_type::size_type pos)
412 return get(block).m_array.at(pos);
417 return get(block).m_array.at(pos);
422 return get(block).m_array.data();
427 return get(block).m_array.size();
432 return get(block).m_array.begin();
437 return get(block).m_array.end();
442 return get(block).m_array.begin();
447 return get(block).m_array.end();
452 return get(block).m_array.begin();
457 return get(block).m_array.end();
462 return get(block).m_array.rbegin();
467 return get(block).m_array.rend();
472 return get(block).m_array.rbegin();
477 return get(block).m_array.rend();
482 return get(block).m_array.rbegin();
487 return get(block).m_array.rend();
492#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
495 std::ostringstream os;
496 os <<
"incorrect block type: expected block type=" << TypeId
501 return static_cast<Self&
>(block);
506#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
509 std::ostringstream os;
510 os <<
"incorrect block type: expected block type=" << TypeId
515 return static_cast<const Self&
>(block);
520 get(blk).m_array[pos] = val;
525 val = get(blk).m_array[pos];
530 return get(blk).m_array[pos];
535 get(blk).m_array.push_back(val);
540 store_type& blk2 = get(blk).m_array;
541 blk2.insert(blk2.begin(), val);
544 static Self* create_block(
size_t init_size)
546 return new Self(init_size);
551 delete static_cast<const Self*
>(p);
556 store_type& st = get(blk).m_array;
561 if (new_size < (detail::get_block_capacity(st) / 2))
562 detail::shrink_to_fit(st);
568 const store_type& blk2 = get(blk).m_array;
569 for (
const auto& val : blk2)
570 std::cout << val <<
" ";
572 std::cout << std::endl;
581 store_type& blk2 = get(blk).m_array;
582 blk2.erase(blk2.begin() + pos);
587 store_type& blk2 = get(blk).m_array;
588 blk2.erase(blk2.begin() + pos, blk2.begin() + pos + size);
593 store_type& d = get(dest).m_array;
594 const store_type& s = get(src).m_array;
595 d.insert(d.end(), s.begin(), s.end());
598 static void append_values_from_block(
601 store_type& d = get(dest).m_array;
602 const store_type& s = get(src).m_array;
603 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
604 detail::reserve(d, d.size() + len);
605 d.insert(d.end(), its.first, its.second);
608 static void assign_values_from_block(
611 store_type& d = get(dest).m_array;
612 const store_type& s = get(src).m_array;
613 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
614 d.assign(its.first, its.second);
617 static void prepend_values_from_block(
620 store_type& d = get(dest).m_array;
621 const store_type& s = get(src).m_array;
622 std::pair<const_iterator, const_iterator> its = get_iterator_pair(s, begin_pos, len);
623 detail::reserve(d, d.size() + len);
624 d.insert(d.begin(), its.first, its.second);
629 store_type& st1 = get(blk1).m_array;
630 store_type& st2 = get(blk2).m_array;
631 assert(pos1 + len <= st1.size());
632 assert(pos2 + len <= st2.size());
634 typename store_type::iterator it1 = st1.begin(), it2 = st2.begin();
635 std::advance(it1, pos1);
636 std::advance(it2, pos2);
638 for (
size_t i = 0; i < len; ++i, ++it1, ++it2)
640 value_type v1 = *it1, v2 = *it2;
648 return get(left) == get(right);
651 template<
typename Iter>
652 static void set_values(
base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
654 store_type& d = get(block).m_array;
655 typename store_type::iterator it_dest = d.begin();
656 std::advance(it_dest, pos);
657 for (Iter it = it_begin; it != it_end; ++it, ++it_dest)
661 template<
typename Iter>
662 static void append_values(
base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
664 store_type& d = get(block).m_array;
665 typename store_type::iterator it = d.end();
666 d.insert(it, it_begin, it_end);
669 template<
typename Iter>
670 static void prepend_values(
base_element_block& block,
const Iter& it_begin,
const Iter& it_end)
672 store_type& d = get(block).m_array;
673 d.insert(d.begin(), it_begin, it_end);
676 template<
typename Iter>
677 static void assign_values(
base_element_block& dest,
const Iter& it_begin,
const Iter& it_end)
679 store_type& d = get(dest).m_array;
680 d.assign(it_begin, it_end);
683 template<
typename Iter>
684 static void insert_values(
base_element_block& block,
size_t pos,
const Iter& it_begin,
const Iter& it_end)
686 store_type& blk = get(block).m_array;
687 blk.insert(blk.begin() + pos, it_begin, it_end);
692 const store_type& blk = get(block).m_array;
693 return detail::get_block_capacity(blk);
698 store_type& blk = get(block).m_array;
699 detail::reserve(blk, size);
704 store_type& blk = get(block).m_array;
705 detail::shrink_to_fit(blk);
709 static std::pair<const_iterator, const_iterator> get_iterator_pair(
710 const store_type& array,
size_t begin_pos,
size_t len)
712 assert(begin_pos + len <= array.size());
713 const_iterator it = array.begin();
714 std::advance(it, begin_pos);
715 const_iterator it_end = it;
716 std::advance(it_end, len);
717 return std::pair<const_iterator, const_iterator>(it, it_end);
721template<
typename Self, element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT>
734 template<
typename Iter>
739 using base_type::get;
744 return new Self(get(blk));
748template<
typename Self, element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT>
761 template<
typename Iter>
791template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
805 template<
typename Iter>
809 static self_type* create_block_with_value(
size_t init_size,
const ValueT& val)
814 template<
typename Iter>
815 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
830template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
837 using base_type::get;
838 using base_type::m_array;
839 using base_type::reserve;
840 using base_type::set_value;
848 detail::reserve(m_array, r.m_array.size());
849 for (
const auto& v : r.m_array)
850 m_array.push_back(
new ValueT(*v));
853 template<
typename Iter>
859 std::for_each(m_array.begin(), m_array.end(), std::default_delete<ValueT>());
862 static self_type* create_block_with_value(
size_t init_size, ValueT* val)
866 throw general_error(
"You can't create a managed block with initial value.");
868 std::unique_ptr<self_type> blk = std::make_unique<self_type>(init_size);
870 set_value(*blk, 0, val);
872 return blk.release();
875 template<
typename Iter>
876 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
884 typename managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
885 typename managed_element_block::store_type::iterator it_end = it + len;
886 std::for_each(it, it_end, std::default_delete<ValueT>());
890template<element_t TypeId,
typename ValueT,
template<
typename,
typename>
class StoreT =
delayed_delete_vector>
893 noncopyable_managed_element_block<TypeId, ValueT, StoreT>, TypeId, ValueT*, StoreT>
898 using base_type::get;
899 using base_type::m_array;
900 using base_type::set_value;
907 template<
typename Iter>
913 std::for_each(m_array.begin(), m_array.end(), std::default_delete<ValueT>());
916 static self_type* create_block_with_value(
size_t init_size, ValueT* val)
920 throw general_error(
"You can't create a managed block with initial value.");
922 std::unique_ptr<self_type> blk = std::make_unique<self_type>(init_size);
924 set_value(*blk, 0, val);
926 return blk.release();
929 template<
typename Iter>
930 static self_type* create_block_with_values(
const Iter& it_begin,
const Iter& it_end)
938 typename noncopyable_managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
939 typename noncopyable_managed_element_block::store_type::iterator it_end = it + len;
940 std::for_each(it, it_end, std::default_delete<ValueT>());
946template<
typename Blk>
949 auto it = Blk::cbegin(data);
950 std::advance(it, offset);
954template<
typename Blk>
957 return Blk::at(data, offset);
960template<
typename Blk>
963 typename mdds::mtv::detail::has_std_vector_bool_store<Blk>::type v;
964 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:782
Definition: types.hpp:723
Definition: types.hpp:176
Definition: types.hpp:146
Definition: types.hpp:374
Definition: types.hpp:750
Definition: types.hpp:794
Definition: types_util.hpp:147
Definition: types.hpp:833
Definition: types.hpp:894
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