28 #ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_TYPES_HPP
29 #define INCLUDED_MDDS_MULTI_TYPE_VECTOR_TYPES_HPP
38 #ifdef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
44 #if defined(MDDS_UNIT_TEST) || defined (MDDS_MULTI_TYPE_VECTOR_DEBUG)
52 namespace mdds {
namespace mtv {
54 using element_t = int;
56 constexpr element_t element_type_empty = -1;
58 constexpr element_t element_type_boolean = 0;
59 constexpr element_t element_type_int8 = 1;
60 constexpr element_t element_type_uint8 = 2;
61 constexpr element_t element_type_int16 = 3;
62 constexpr element_t element_type_uint16 = 4;
63 constexpr element_t element_type_int32 = 5;
64 constexpr element_t element_type_uint32 = 6;
65 constexpr element_t element_type_int64 = 7;
66 constexpr element_t element_type_uint64 = 8;
67 constexpr element_t element_type_float = 9;
68 constexpr element_t element_type_double = 10;
69 constexpr element_t element_type_string = 11;
71 constexpr element_t element_type_user_start = 50;
79 element_block_error(
const std::string& msg) : mdds::general_error(msg) {}
82 struct base_element_block;
83 element_t get_block_type(
const base_element_block&);
89 struct base_element_block
94 base_element_block(element_t _t) : type(_t) {}
97 template<
typename _Self, element_t _TypeId,
typename _Data>
98 class element_block :
public base_element_block
100 #ifdef MDDS_UNIT_TEST
101 struct print_block_array
103 void operator() (
const _Data& val)
const
105 std::cout << val <<
" ";
111 #ifdef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
112 typedef std::deque<_Data> store_type;
114 typedef std::vector<_Data> store_type;
118 element_block() : base_element_block(_TypeId) {}
119 element_block(
size_t n) : base_element_block(_TypeId), m_array(n) {}
120 element_block(
size_t n,
const _Data& val) : base_element_block(_TypeId), m_array(n, val) {}
122 template<
typename _Iter>
126 static const element_t block_type = _TypeId;
128 typedef typename store_type::iterator iterator;
129 typedef typename store_type::reverse_iterator reverse_iterator;
130 typedef typename store_type::const_iterator const_iterator;
131 typedef typename store_type::const_reverse_iterator const_reverse_iterator;
132 typedef _Data value_type;
134 bool operator== (
const _Self& r)
const
136 return m_array == r.m_array;
139 bool operator!= (
const _Self& r)
const
141 return !operator==(r);
144 static const value_type& at(
const base_element_block& block,
typename store_type::size_type pos)
146 return get(block).m_array.at(pos);
151 return get(block).m_array.at(pos);
154 static value_type* data(base_element_block& block)
156 return get(block).m_array.data();
159 static typename store_type::size_type size(
const base_element_block& block)
161 return get(block).m_array.size();
164 static iterator begin(base_element_block& block)
166 return get(block).m_array.begin();
169 static iterator end(base_element_block& block)
171 return get(block).m_array.end();
174 static const_iterator begin(
const base_element_block& block)
176 return get(block).m_array.begin();
179 static const_iterator end(
const base_element_block& block)
181 return get(block).m_array.end();
184 static const_iterator cbegin(
const base_element_block& block)
186 return get(block).m_array.begin();
189 static const_iterator cend(
const base_element_block& block)
191 return get(block).m_array.end();
194 static reverse_iterator rbegin(base_element_block& block)
196 return get(block).m_array.rbegin();
199 static reverse_iterator rend(base_element_block& block)
201 return get(block).m_array.rend();
204 static const_reverse_iterator rbegin(
const base_element_block& block)
206 return get(block).m_array.rbegin();
209 static const_reverse_iterator rend(
const base_element_block& block)
211 return get(block).m_array.rend();
214 static const_reverse_iterator crbegin(
const base_element_block& block)
216 return get(block).m_array.rbegin();
219 static const_reverse_iterator crend(
const base_element_block& block)
221 return get(block).m_array.rend();
224 static _Self& get(base_element_block& block)
226 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
229 std::ostringstream os;
230 os <<
"incorrect block type: expected block type=" << _TypeId <<
", passed block type=" <<
get_block_type(block);
231 throw general_error(os.str());
234 return static_cast<_Self&>(block);
237 static const _Self& get(
const base_element_block& block)
239 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
242 std::ostringstream os;
243 os <<
"incorrect block type: expected block type=" << _TypeId <<
", passed block type=" <<
get_block_type(block);
244 throw general_error(os.str());
247 return static_cast<const _Self&>(block);
250 static void set_value(base_element_block& blk,
size_t pos,
const _Data& val)
252 get(blk).m_array[pos] = val;
255 static void get_value(
const base_element_block& blk,
size_t pos, _Data& val)
257 val = get(blk).m_array[pos];
260 static value_type get_value(
const base_element_block& blk,
size_t pos)
262 return get(blk).m_array[pos];
265 static void append_value(base_element_block& blk,
const _Data& val)
267 get(blk).m_array.push_back(val);
270 static void prepend_value(base_element_block& blk,
const _Data& val)
272 store_type& blk2 = get(blk).m_array;
273 blk2.insert(blk2.begin(), val);
276 static _Self* create_block(
size_t init_size)
278 return new _Self(init_size);
281 static void delete_block(
const base_element_block* p)
283 delete static_cast<const _Self*>(p);
286 static void resize_block(base_element_block& blk,
size_t new_size)
288 store_type& st = get(blk).m_array;
293 if (new_size < (st.capacity() / 2))
297 #ifdef MDDS_UNIT_TEST
298 static void print_block(
const base_element_block& blk)
300 const store_type& blk2 = get(blk).m_array;
301 std::for_each(blk2.begin(), blk2.end(), print_block_array());
302 std::cout << std::endl;
305 static void print_block(
const base_element_block&) {}
308 static void erase_block(base_element_block& blk,
size_t pos)
310 store_type& blk2 = get(blk).m_array;
311 blk2.erase(blk2.begin()+pos);
314 static void erase_block(base_element_block& blk,
size_t pos,
size_t size)
316 store_type& blk2 = get(blk).m_array;
317 blk2.erase(blk2.begin()+pos, blk2.begin()+pos+size);
320 static void append_values_from_block(base_element_block& dest,
const base_element_block& src)
322 store_type& d = get(dest).m_array;
323 const store_type& s = get(src).m_array;
324 d.insert(d.end(), s.begin(), s.end());
327 static void append_values_from_block(
328 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
330 store_type& d = get(dest).m_array;
331 const store_type& s = get(src).m_array;
332 std::pair<const_iterator,const_iterator> its = get_iterator_pair(s, begin_pos, len);
333 #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
334 d.reserve(d.size() + len);
336 d.insert(d.end(), its.first, its.second);
339 static void assign_values_from_block(
340 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
342 store_type& d = get(dest).m_array;
343 const store_type& s = get(src).m_array;
344 std::pair<const_iterator,const_iterator> its = get_iterator_pair(s, begin_pos, len);
345 d.assign(its.first, its.second);
348 static void prepend_values_from_block(
349 base_element_block& dest,
const base_element_block& src,
size_t begin_pos,
size_t len)
351 store_type& d = get(dest).m_array;
352 const store_type& s = get(src).m_array;
353 std::pair<const_iterator,const_iterator> its = get_iterator_pair(s, begin_pos, len);
354 #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
355 d.reserve(d.size() + len);
357 d.insert(d.begin(), its.first, its.second);
360 static void swap_values(
361 base_element_block& blk1, base_element_block& blk2,
size_t pos1,
size_t pos2,
size_t len)
363 store_type& st1 = get(blk1).m_array;
364 store_type& st2 = get(blk2).m_array;
365 assert(pos1 + len <= st1.size());
366 assert(pos2 + len <= st2.size());
368 typename store_type::iterator it1 = st1.begin(), it2 = st2.begin();
369 std::advance(it1, pos1);
370 std::advance(it2, pos2);
371 for (
size_t i = 0; i < len; ++i, ++it1, ++it2)
373 #ifdef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
374 std::swap(*it1, *it2);
376 value_type v1 = *it1, v2 = *it2;
383 template<
typename _Iter>
384 static void set_values(
385 base_element_block& block,
size_t pos,
const _Iter& it_begin,
const _Iter& it_end)
387 store_type& d = get(block).m_array;
388 typename store_type::iterator it_dest = d.begin();
389 std::advance(it_dest, pos);
390 for (_Iter it = it_begin; it != it_end; ++it, ++it_dest)
394 template<
typename _Iter>
395 static void append_values(base_element_block& block,
const _Iter& it_begin,
const _Iter& it_end)
397 store_type& d = get(block).m_array;
398 typename store_type::iterator it = d.end();
399 d.insert(it, it_begin, it_end);
402 template<
typename _Iter>
403 static void prepend_values(base_element_block& block,
const _Iter& it_begin,
const _Iter& it_end)
405 store_type& d = get(block).m_array;
406 d.insert(d.begin(), it_begin, it_end);
409 template<
typename _Iter>
410 static void assign_values(base_element_block& dest,
const _Iter& it_begin,
const _Iter& it_end)
412 store_type& d = get(dest).m_array;
413 d.assign(it_begin, it_end);
416 template<
typename _Iter>
417 static void insert_values(
418 base_element_block& block,
size_t pos,
const _Iter& it_begin,
const _Iter& it_end)
420 store_type& blk = get(block).m_array;
421 blk.insert(blk.begin()+pos, it_begin, it_end);
424 static size_t capacity(
const base_element_block& block)
426 #ifdef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
429 const store_type& blk = get(block).m_array;
430 return blk.capacity();
434 static void shrink_to_fit(base_element_block& block)
436 #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
437 get(block).m_array.shrink_to_fit();
442 static std::pair<const_iterator,const_iterator>
443 get_iterator_pair(
const store_type& array,
size_t begin_pos,
size_t len)
445 assert(begin_pos + len <= array.size());
446 const_iterator it = array.begin();
447 std::advance(it, begin_pos);
448 const_iterator it_end = it;
449 std::advance(it_end, len);
450 return std::pair<const_iterator,const_iterator>(it, it_end);
454 template<
typename _Self, element_t _TypeId,
typename _Data>
455 class copyable_element_block :
public element_block<_Self, _TypeId, _Data>
457 typedef element_block<_Self,_TypeId,_Data> base_type;
459 copyable_element_block() : base_type() {}
460 copyable_element_block(
size_t n) : base_type(n) {}
461 copyable_element_block(
size_t n,
const _Data& val) : base_type(n, val) {}
463 template<
typename _Iter>
464 copyable_element_block(
const _Iter& it_begin,
const _Iter& it_end) : base_type(it_begin, it_end) {}
467 using base_type::get;
469 static _Self* clone_block(
const base_element_block& blk)
472 return new _Self(get(blk));
476 template<
typename _Self, element_t _TypeId,
typename _Data>
477 class noncopyable_element_block :
public element_block<_Self, _TypeId, _Data>
479 typedef element_block<_Self,_TypeId,_Data> base_type;
481 noncopyable_element_block() : base_type() {}
482 noncopyable_element_block(
size_t n) : base_type(n) {}
483 noncopyable_element_block(
size_t n,
const _Data& val) : base_type(n, val) {}
485 template<
typename _Iter>
486 noncopyable_element_block(
const _Iter& it_begin,
const _Iter& it_end) : base_type(it_begin, it_end) {}
489 noncopyable_element_block(
const noncopyable_element_block&) =
delete;
490 noncopyable_element_block& operator=(
const noncopyable_element_block&) =
delete;
492 static _Self* clone_block(
const base_element_block&)
494 throw element_block_error(
"attempted to clone a noncopyable element block.");
505 inline element_t get_block_type(
const base_element_block& blk)
514 template<element_t _TypeId,
typename _Data>
515 struct default_element_block :
public copyable_element_block<default_element_block<_TypeId,_Data>, _TypeId, _Data>
517 typedef copyable_element_block<default_element_block, _TypeId, _Data> base_type;
518 typedef default_element_block<_TypeId,_Data> self_type;
520 default_element_block() : base_type() {}
521 default_element_block(
size_t n) : base_type(n) {}
522 default_element_block(
size_t n,
const _Data& val) : base_type(n, val) {}
524 template<
typename _Iter>
527 static self_type* create_block_with_value(
size_t init_size,
const _Data& val)
529 return new self_type(init_size, val);
532 template<
typename _Iter>
533 static self_type* create_block_with_values(
const _Iter& it_begin,
const _Iter& it_end)
535 return new self_type(it_begin, it_end);
538 static void overwrite_values(base_element_block&,
size_t,
size_t)
548 template<element_t _TypeId,
typename _Data>
549 struct managed_element_block :
public copyable_element_block<managed_element_block<_TypeId,_Data>, _TypeId, _Data*>
551 typedef copyable_element_block<managed_element_block<_TypeId,_Data>, _TypeId, _Data*> base_type;
554 using base_type::get;
555 using base_type::set_value;
556 using base_type::m_array;
560 managed_element_block(
const managed_element_block& r)
562 #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
563 m_array.reserve(r.m_array.size());
565 typename managed_element_block::store_type::const_iterator it = r.m_array.begin(), it_end = r.m_array.end();
566 for (; it != it_end; ++it)
567 m_array.push_back(
new _Data(**it));
570 template<
typename _Iter>
573 ~managed_element_block()
575 std::for_each(m_array.begin(), m_array.end(), std::default_delete<_Data>());
578 static self_type* create_block_with_value(
size_t init_size, _Data* val)
582 throw general_error(
"You can't create a managed block with initial value.");
584 std::unique_ptr<self_type> blk = make_unique<self_type>(init_size);
586 set_value(*blk, 0, val);
588 return blk.release();
591 template<
typename _Iter>
592 static self_type* create_block_with_values(
const _Iter& it_begin,
const _Iter& it_end)
594 return new self_type(it_begin, it_end);
600 typename managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
601 typename managed_element_block::store_type::iterator it_end = it + len;
602 std::for_each(it, it_end, std::default_delete<_Data>());
606 template<element_t _TypeId,
typename _Data>
607 struct noncopyable_managed_element_block :
public noncopyable_element_block<noncopyable_managed_element_block<_TypeId,_Data>, _TypeId, _Data*>
609 typedef noncopyable_element_block<noncopyable_managed_element_block<_TypeId,_Data>, _TypeId, _Data*> base_type;
610 typedef managed_element_block<_TypeId,_Data> self_type;
612 using base_type::get;
613 using base_type::m_array;
614 using base_type::set_value;
616 noncopyable_managed_element_block() : base_type() {}
617 noncopyable_managed_element_block(
size_t n) : base_type(n) {}
619 template<
typename _Iter>
620 noncopyable_managed_element_block(
const _Iter& it_begin,
const _Iter& it_end) : base_type(it_begin, it_end) {}
622 ~noncopyable_managed_element_block()
624 std::for_each(m_array.begin(), m_array.end(), std::default_delete<_Data>());
627 static self_type* create_block_with_value(
size_t init_size, _Data* val)
631 throw general_error(
"You can't create a managed block with initial value.");
633 std::unique_ptr<self_type> blk = make_unique<self_type>(init_size);
635 set_value(*blk, 0, val);
637 return blk.release();
640 template<
typename _Iter>
641 static self_type* create_block_with_values(
const _Iter& it_begin,
const _Iter& it_end)
643 return new self_type(it_begin, it_end);
646 static void overwrite_values(base_element_block& block,
size_t pos,
size_t len)
648 noncopyable_managed_element_block& blk = get(block);
649 typename noncopyable_managed_element_block::store_type::iterator it = blk.m_array.begin() + pos;
650 typename noncopyable_managed_element_block::store_type::iterator it_end = it + len;
651 std::for_each(it, it_end, std::default_delete<_Data>());