neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
vecarray.hpp
Go to the documentation of this file.
1// vecarray.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <cassert>
40#include <cstddef>
41#include <stdexcept>
42#include <memory>
43#include <algorithm>
44#include <iterator>
45#include <type_traits>
46#include <vector>
47
48namespace neolib
49{
50 struct vecarray_overflow : public std::exception
51 {
52 virtual const char* what() const throw() { return "neolib::vecarray_overflow"; }
53 };
54
55 struct nocheck
56 {
57 inline static void test(bool aValid)
58 {
59 (void)aValid;
60 assert(aValid);
61 }
62 };
63
64 template <typename Exception>
65 struct check
66 {
67 inline static void test(bool aValid)
68 {
69 if (!aValid)
70 throw Exception();
71 }
72 };
73
74 template <typename T>
75 bool constexpr vecarray_trivial_v = std::is_trivial_v<T>;
76
77 namespace detail
78 {
79 template <typename InputIter1, typename InputIter2, typename ForwardIter1, typename ForwardIter2>
80 inline static void uninitialized_copy2(InputIter1 first1, InputIter1 last1, ForwardIter1 dest1, InputIter2 first2, InputIter2 last2, ForwardIter2 dest2)
81 {
82 std::uninitialized_copy(first1, last1, dest1);
83 try
84 {
85 std::uninitialized_copy(first2, last2, dest2);
86 }
87 catch(...)
88 {
89 auto last = dest1 + (last1 - first1);
90 typedef typename std::iterator_traits<ForwardIter1>::value_type value_type;
91 if constexpr (!vecarray_trivial_v<value_type>)
92 for (auto i = dest1; i != last; ++i)
93 (*i).~value_type();
94 throw;
95 }
96 }
97 }
98
99 template<typename T, std::size_t ArraySize, std::size_t MaxVectorSize = ArraySize, typename CheckPolicy = check<vecarray_overflow>, typename Alloc = std::allocator<T> >
101 {
102 public:
103 struct iterator_invalid : std::logic_error { iterator_invalid() : std::logic_error("neolib::vecarray::iterator_invalid") {} };
104 private:
105 enum iterator_type_e { ArrayIterator, VectorIterator };
106 public:
107 typedef T value_type;
108 typedef T* pointer;
109 typedef const T* const_pointer;
110 typedef T& reference;
111 typedef const T& const_reference;
112 typedef std::size_t size_type;
113 typedef std::ptrdiff_t difference_type;
114 typedef Alloc allocator_type;
115 typedef std::vector<value_type, allocator_type> vector_type;
116 class const_iterator;
118 {
119 friend class const_iterator;
120
121 public:
122 typedef std::random_access_iterator_tag iterator_category;
127
128 public:
129 iterator() : iType(ArrayIterator), iArrayPtr(0), iVectorIter()
130 {
131 }
132 iterator(const iterator& aOther) : iType(aOther.iType), iArrayPtr(aOther.iArrayPtr), iVectorIter(aOther.iVectorIter)
133 {
134 }
135 iterator(T* aPtr) : iType(ArrayIterator), iArrayPtr(aPtr), iVectorIter()
136 {
137 }
138 iterator(typename vector_type::iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
139 {
140 }
141
142 public:
144 {
145 if (iType == ArrayIterator)
146 ++iArrayPtr;
147 else
148 ++iVectorIter;
149 return *this;
150 }
152 {
153 if (iType == ArrayIterator)
154 --iArrayPtr;
155 else
156 --iVectorIter;
157 return *this;
158 }
159 iterator operator++(int) { iterator ret(*this); operator++(); return ret; }
160 iterator operator--(int) { iterator ret(*this); operator--(); return ret; }
162 {
163 if (aDifference < 0)
164 return operator-=(-aDifference);
165 if (iType == ArrayIterator)
166 iArrayPtr += aDifference;
167 else
168 iVectorIter += aDifference;
169 return *this;
170 }
172 {
173 if (aDifference < 0)
174 return operator+=(-aDifference);
175 if (iType == ArrayIterator)
176 iArrayPtr -= aDifference;
177 else
178 iVectorIter -= aDifference;
179 return *this;
180 }
181 iterator operator+(difference_type aDifference) const { iterator result(*this); result += aDifference; return result; }
182 iterator operator-(difference_type aDifference) const { iterator result(*this); result -= aDifference; return result; }
183 reference operator[](difference_type aDifference) const { return *((*this) + aDifference); }
184 difference_type operator-(const iterator& aOther) const
185 {
186 if (iType == ArrayIterator)
187 return iArrayPtr - aOther.iArrayPtr;
188 else
189 return iVectorIter - aOther.iVectorIter;
190 }
192 {
193 if (iType == ArrayIterator)
194 return *iArrayPtr;
195 else
196 return *iVectorIter;
197 }
198 pointer operator->() const { return &operator*(); }
199 bool operator==(const iterator& aOther) const
200 {
201 if (iType == ArrayIterator)
202 return iArrayPtr == aOther.iArrayPtr;
203 else
204 return iVectorIter == aOther.iVectorIter;
205 }
206 bool operator!=(const iterator& aOther) const
207 {
208 if (iType == ArrayIterator)
209 return iArrayPtr != aOther.iArrayPtr;
210 else
211 return iVectorIter != aOther.iVectorIter;
212 }
213 bool operator<(const iterator& aOther) const
214 {
215 if (iType == ArrayIterator)
216 return iArrayPtr < aOther.iArrayPtr;
217 else
218 return iVectorIter < aOther.iVectorIter;
219 }
220 public:
221 T* array_ptr() const
222 {
223 if (iType == ArrayIterator)
224 return iArrayPtr;
225 else
226 throw iterator_invalid();
227 }
228 typename vector_type::iterator vector_iter() const
229 {
230 if (iType == VectorIterator)
231 return iVectorIter;
232 else
233 throw iterator_invalid();
234 }
235 private:
236 iterator_type_e iType;
237 T* iArrayPtr;
238 typename vector_type::iterator iVectorIter;
239 };
241 {
242 public:
243 typedef std::random_access_iterator_tag iterator_category;
248
249 public:
250 const_iterator() : iType(ArrayIterator), iArrayPtr(0), iVectorIter()
251 {
252 }
253 const_iterator(const const_iterator& aOther) : iType(aOther.iType), iArrayPtr(aOther.iArrayPtr), iVectorIter(aOther.iVectorIter)
254 {
255 }
256 const_iterator(const typename vecarray::iterator& aOther) : iType(aOther.iType), iArrayPtr(aOther.iArrayPtr), iVectorIter(aOther.iVectorIter)
257 {
258 }
259 const_iterator(const T* aPtr) : iType(ArrayIterator), iArrayPtr(aPtr), iVectorIter()
260 {
261 }
262 const_iterator(typename vector_type::const_iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
263 {
264 }
265 const_iterator(typename vector_type::iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
266 {
267 }
268
269 public:
271 {
272 if (iType == ArrayIterator)
273 ++iArrayPtr;
274 else
275 ++iVectorIter;
276 return *this;
277 }
279 {
280 if (iType == ArrayIterator)
281 --iArrayPtr;
282 else
283 --iVectorIter;
284 return *this;
285 }
286 const_iterator operator++(int) { const_iterator ret(*this); operator++(); return ret; }
287 const_iterator operator--(int) { const_iterator ret(*this); operator--(); return ret; }
289 {
290 if (aDifference < 0)
291 return operator-=(-aDifference);
292 if (iType == ArrayIterator)
293 iArrayPtr += aDifference;
294 else
295 iVectorIter += aDifference;
296 return *this;
297 }
299 {
300 if (aDifference < 0)
301 return operator+=(-aDifference);
302 if (iType == ArrayIterator)
303 iArrayPtr -= aDifference;
304 else
305 iVectorIter -= aDifference;
306 return *this;
307 }
308 const_iterator operator+(difference_type aDifference) const { const_iterator result(*this); result += aDifference; return result; }
309 const_iterator operator-(difference_type aDifference) const { const_iterator result(*this); result -= aDifference; return result; }
310 const_reference operator[](difference_type aDifference) const { return *((*this) + aDifference); }
312 {
313 if (iType == ArrayIterator)
314 return iArrayPtr - aOther.iArrayPtr;
315 else
316 return iVectorIter - aOther.iVectorIter;
317 }
319 {
320 if (iType == ArrayIterator)
321 return *iArrayPtr;
322 else
323 return *iVectorIter;
324 }
325 const_pointer operator->() const { return &operator*(); }
326 bool operator==(const const_iterator& aOther) const
327 {
328 if (iType == ArrayIterator)
329 return iArrayPtr == aOther.iArrayPtr;
330 else
331 return iVectorIter == aOther.iVectorIter;
332 }
333 bool operator!=(const const_iterator& aOther) const
334 {
335 if (iType == ArrayIterator)
336 return iArrayPtr != aOther.iArrayPtr;
337 else
338 return iVectorIter != aOther.iVectorIter;
339 }
340 bool operator<(const const_iterator& aOther) const
341 {
342 if (iType == ArrayIterator)
343 return iArrayPtr < aOther.iArrayPtr;
344 else
345 return iVectorIter < aOther.iVectorIter;
346 }
347
348 public:
349 const T* array_ptr() const
350 {
351 if (iType == ArrayIterator)
352 return iArrayPtr;
353 else
354 throw iterator_invalid();
355 }
356 typename vector_type::const_iterator vector_iter() const
357 {
358 if (iType == VectorIterator)
359 return iVectorIter;
360 else
361 throw iterator_invalid();
362 }
363
364 private:
365 iterator_type_e iType;
366 const T* iArrayPtr;
367 typename vector_type::const_iterator iVectorIter;
368 };
369 typedef std::reverse_iterator<iterator> reverse_iterator;
370 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
371
372 public:
373 static constexpr bool is_fixed_size() { return ArraySize == MaxVectorSize; }
374
375 public:
376 // construction
377 vecarray() : iSize{ 0 }
378 {
379 }
380 vecarray(const vecarray& rhs) : iSize{ 0 }
381 {
382 insert(begin(), rhs.begin(), rhs.end());
383 }
384 vecarray(vecarray&& rhs) : iSize{0}
385 {
386 if (using_vector())
387 {
388 vector() = std::move(rhs.vector());
389 iSize = rhs.iSize;
390 }
391 else
392 {
393 for (auto&& element : rhs)
394 push_back(std::move(element));
395 rhs.clear();
396 }
397 }
398 template <typename T2, std::size_t N2>
399 vecarray(const vecarray<T2, N2>& rhs) : iSize{ 0 }
400 {
401 insert(begin(), rhs.begin(), rhs.end());
402 }
403 vecarray(size_type n) : iSize{ 0 }
404 {
405 insert(begin(), n, value_type());
406 }
407 vecarray(size_type n, value_type value) : iSize{ 0 }
408 {
409 insert(begin(), n, value);
410 }
411 template<typename InputIterator>
412 vecarray(InputIterator first, InputIterator last) : iSize{ 0 }
413 {
414 insert(begin(), first, last);
415 }
416 vecarray(std::initializer_list<T> init) : iSize{ 0 }
417 {
418 insert(begin(), init.begin(), init.end());
419 }
421 {
422 clear();
423 if (using_vector())
424 vector().~vector_type();
425 }
426
427 // traversals
428 public:
429 const_iterator cbegin() const { return using_array() ? const_iterator(reinterpret_cast<const_pointer>(iAlignedBuffer.iData)) : const_iterator(vector().begin()); }
430 const_iterator begin() const { return cbegin(); }
431 iterator begin() { return using_array() ? iterator(reinterpret_cast<pointer>(iAlignedBuffer.iData)) : iterator(vector().begin()); }
432 const_iterator cend() const { return using_array() ? const_iterator(reinterpret_cast<const_pointer>(iAlignedBuffer.iData) + iSize) : const_iterator(vector().end()); }
433 const_iterator end() const { return cend(); }
434 iterator end() { return using_array() ? iterator(reinterpret_cast<pointer>(iAlignedBuffer.iData) + iSize) : iterator(vector().end()); }
439 bool empty() const { return size() == 0; }
440 bool full() const { return size() == MaxVectorSize; }
441 size_type size() const { return using_array() ? iSize : vector().size(); }
442 size_type available() const { return MaxVectorSize - size(); }
443 size_type capacity() const { return MaxVectorSize; }
444 size_type max_size() const { return MaxVectorSize; }
445 size_type after(size_type position) const { return position < size() ? size() - position : 0; }
446
447 // element access
448 public:
449 reference operator[](size_type n) { return *(begin() + n); }
450 const_reference operator[](size_type n) const { return *(begin() + n); }
451 reference at(size_type n) { if (n < size()) return operator[](n); throw std::out_of_range("vecarray::at"); }
452 const_reference at(size_type n) const { if (n < size()) return operator[](n); throw std::out_of_range("vecarray::at"); }
453 reference front() { return *begin(); }
454 reference back() { return *(begin() + (size() - 1)); }
455 const_reference front() const { return *begin(); }
456 const_reference back() const { return *(begin() + (size() - 1)); }
457
458 // modifiers
459 public:
461 {
462 if (&rhs != this)
463 assign(rhs.begin(), rhs.end());
464 return *this;
465 }
466 template<typename T2, std::size_t N2>
468 {
469 if (static_cast<const void*>(&rhs) != static_cast<const void*>(this))
470 assign(rhs.begin(), rhs.end());
471 return *this;
472 }
473 template <typename InputIterator>
474 void assign(InputIterator first, InputIterator last)
475 {
476 clear();
477 insert(cbegin(), first, last);
478 }
480 {
481 clear();
482 insert(cbegin(), n, value);
483 }
484 template <class InputIterator>
485 typename std::enable_if_t<!std::is_integral<InputIterator>::value, iterator>
486 insert(const_iterator position, InputIterator first, InputIterator last)
487 {
488 need(std::distance(first, last), position);
489 position = do_insert(position, first, last);
490 return begin() + (position - cbegin());
491 }
493 {
494 need(1, position);
495 insert(position, 1, value);
496 return begin() + (position - cbegin());
497 }
498 iterator insert(const_iterator position, size_type count, const value_type& value)
499 {
500 need(count, position);
501 if (using_array())
502 {
503 iterator next = std::next(begin(), std::distance(cbegin(), position));
504 while (count > 0)
505 {
506 next = std::next(insert(next, &value, &value + 1));
507 --count;
508 }
509 return next;
510 }
511 else
512 return vector().insert(position.vector_iter(), count, value);
513 }
515 {
516 if (using_array())
517 {
518 assert(iSize > 0);
519 iterator dest = std::next(begin(), std::distance(cbegin(), position));
520 auto garbage = std::copy(std::make_move_iterator(std::next(dest)), std::make_move_iterator(end()), dest);
521 (*garbage).~value_type();
522 --iSize;
523 return dest;
524 }
525 else
526 return vector().erase(position.vector_iter());
527 }
529 {
530 if (first == last)
531 return std::next(begin(), std::distance(cbegin(), first));
532 if (using_array())
533 {
534 assert(iSize > 0);
535 iterator first2 = std::next(begin(), std::distance(cbegin(), first));
536 iterator last2 = std::next(begin(), std::distance(cbegin(), last));
537 auto garbage = std::copy(std::make_move_iterator(last2), std::make_move_iterator(end()), first2);
538 auto garbageLast = end();
539 if constexpr (!vecarray_trivial_v<value_type>)
540 for (auto i = garbage; i != garbageLast; ++i)
541 (*i).~value_type();
542 iSize -= (last - first);
543 return first2;
544 }
545 else
546 return vector().erase(first.vector_iter(), last.vector_iter());
547 }
548 void clear()
549 {
550 erase(cbegin(), cend());
551 }
552 template< class... Args >
553 reference emplace_back(Args&&... args)
554 {
555 CheckPolicy::test(size() < MaxVectorSize);
556 need(1);
557 if (using_array())
558 {
559 new (end().array_ptr()) value_type{ std::forward<Args>(args)... };
560 ++iSize;
561 return back();
562 }
563 else
564 return vector().emplace_back(std::forward<Args>(args)...);
565 }
566 void push_back(const value_type& value)
567 {
568 CheckPolicy::test(size() < MaxVectorSize);
569 need(1);
570 if (using_array())
571 {
572 new (end().array_ptr()) value_type{ value };
573 ++iSize;
574 }
575 else
576 vector().push_back(value);
577 }
578 void push_back(value_type&& value)
579 {
580 CheckPolicy::test(size() < MaxVectorSize);
581 need(1);
582 if (using_array())
583 {
584 new (end().array_ptr()) value_type{ std::move(value) };
585 ++iSize;
586 }
587 else
588 vector().push_back(std::move(value));
589 }
590 void pop_back()
591 {
592 erase(end() - 1);
593 }
594 void remove(value_type value, bool multiple = true)
595 {
596 auto last = end();
597 for (iterator i = begin(); i != last; )
598 {
599 if (*i == value)
600 {
601 erase(i);
602 if (!multiple)
603 return;
604 }
605 else
606 ++i;
607 }
608 }
610 {
611 if (using_array())
612 {
613 if (size() > n)
614 erase(begin() + n, end());
615 else if (size() < n)
616 insert(end(), n - size(), value_type{});
617 }
618 else
619 vector().resize(n);
620 }
621 void resize(size_type n, const value_type& value)
622 {
623 if (using_array())
624 {
625 if (size() > n)
626 erase(begin() + n, end());
627 else if (size() < n)
628 insert(end(), n - size(), value);
629 }
630 else
631 vector().resize(n, value);
632 }
634 {
635 if (n > ArraySize && n > size())
636 need(n - size());
637 }
638 template<typename T2, std::size_t ArraySize2, std::size_t MaxVectorSize2, typename CheckPolicy2, typename Alloc2>
640 {
641 vecarray tmp = rhs;
642 rhs = *this;
643 *this = tmp;
644 }
645
646 // equality
647 public:
648 template<typename T2, std::size_t ArraySize2, std::size_t MaxVectorSize2, typename CheckPolicy2, typename Alloc2>
650 {
651 return rhs.size() == size() && std::equal(begin(), end(), rhs.begin());
652 }
653 template<typename T2, std::size_t ArraySize2, std::size_t MaxVectorSize2, typename CheckPolicy2, typename Alloc2>
658
659 private:
660 template <std::size_t ArraySize2 = ArraySize, std::size_t MaxVectorSize2 = MaxVectorSize>
661 constexpr typename std::enable_if<ArraySize2 == MaxVectorSize2, bool>::type using_array() const
662 {
663 return true;
664 }
665 template <std::size_t ArraySize2 = ArraySize, std::size_t MaxVectorSize2 = MaxVectorSize>
666 typename std::enable_if<ArraySize2 != MaxVectorSize2, bool>::type using_array() const
667 {
668 return iSize != USING_VECTOR;
669 }
670 template <std::size_t ArraySize2 = ArraySize, std::size_t MaxVectorSize2 = MaxVectorSize>
671 constexpr typename std::enable_if<ArraySize2 == MaxVectorSize2, bool>::type using_vector() const
672 {
673 return false;
674 }
675 template <std::size_t ArraySize2 = ArraySize, std::size_t MaxVectorSize2 = MaxVectorSize>
676 typename std::enable_if<ArraySize2 != MaxVectorSize2, bool>::type using_vector() const
677 {
678 return iSize == USING_VECTOR;
679 }
680 vector_type& vector()
681 {
682 return reinterpret_cast<vector_type&>(iAlignedBuffer.iVector);
683 }
684 const vector_type& vector() const
685 {
686 return reinterpret_cast<const vector_type&>(iAlignedBuffer.iVector);
687 }
688 void need(size_type aAmount)
689 {
690 if (using_array() && size() + aAmount > ArraySize)
691 convert(aAmount);
692 }
693 template <typename Iter>
694 void need(size_type aAmount, Iter& aIter)
695 {
696 static_assert(std::is_same_v<Iter, const_iterator> || std::is_same_v<Iter, iterator>, "bad usage");
697 if (using_array() && size() + aAmount > ArraySize)
698 {
699
700 if constexpr (std::is_same_v<Iter, const_iterator>)
701 {
702 size_type index = aIter - cbegin();
703 convert(aAmount);
704 aIter = cbegin() + index;
705 }
706 else if constexpr (std::is_same_v<Iter, iterator>)
707 {
708 size_type index = aIter - begin();
709 convert(aAmount);
710 aIter = begin() + index;
711 }
712 }
713 }
714 void convert(size_type aExtra)
715 {
716 if (using_array())
717 {
718 vector_type copy;
719 copy.reserve(std::max(ArraySize * 2, size() + aExtra));
720 copy.insert(copy.begin(), std::make_move_iterator(begin()), std::make_move_iterator(end()));
721 clear();
722 new (iAlignedBuffer.iVector) vector_type{ std::move(copy) };
723 iSize = USING_VECTOR;
724 }
725 }
726 template <class InputIterator>
727 typename std::enable_if<!std::is_same<typename std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag>::value, iterator>::type
728 do_insert(const_iterator position, InputIterator first, InputIterator last)
729 {
730 difference_type n = last - first;
731 CheckPolicy::test(size() + n <= MaxVectorSize);
732 need(n, position);
733 if (using_array())
734 {
735 auto pos = const_cast<pointer>(position.array_ptr());
736 const_iterator theEnd = end();
737 difference_type t = theEnd - position;
738 if (t > 0)
739 {
740 if (t > n)
741 {
742 std::uninitialized_copy(theEnd - n, theEnd, const_cast<pointer>(theEnd.array_ptr()));
743 iSize += n;
744 std::copy_backward(position, theEnd - n, const_cast<pointer>(theEnd.array_ptr()));
745 std::copy(first, last, pos);
746 }
747 else
748 {
749 detail::uninitialized_copy2(theEnd - t, theEnd, const_cast<pointer>((theEnd + (n - t)).array_ptr()), first + t, last, const_cast<pointer>(theEnd.array_ptr()));
750 iSize += n;
751 std::copy(first, first + t, pos);
752 }
753 }
754 else
755 {
756 std::uninitialized_copy(first, last, pos);
757 iSize += n;
758 }
759 return pos;
760 }
761 else
762 {
763 return vector().insert(position.vector_iter(), first, last);
764 }
765 }
766 template <class InputIterator>
767 typename std::enable_if<std::is_same<typename std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag>::value, iterator>::type
768 do_insert(const_iterator position, InputIterator first, InputIterator last)
769 {
770 iterator next = position;
771 while (first != last)
772 {
773 next = std::next(insert(next, 1, *first++));
774 }
775 return next;
776 }
777
778 private:
779 union
780 {
781 alignas(T) char iData[sizeof(T) * ArraySize];
782 char iVector[sizeof(vector_type)];
783 } iAlignedBuffer;
784 size_type iSize;
785 static const size_type USING_VECTOR = static_cast<size_type>(-1);
786 };
787}
iterator insert(const const_iterator &aPosition, const value_type &aValue)
const_iterator(typename vector_type::const_iterator aIter)
Definition vecarray.hpp:262
const_pointer operator->() const
Definition vecarray.hpp:325
const_iterator(typename vector_type::iterator aIter)
Definition vecarray.hpp:265
vecarray::const_reference reference
Definition vecarray.hpp:247
const_iterator operator-(difference_type aDifference) const
Definition vecarray.hpp:309
const_reference operator*() const
Definition vecarray.hpp:318
const_iterator(const typename vecarray::iterator &aOther)
Definition vecarray.hpp:256
const_iterator operator+(difference_type aDifference) const
Definition vecarray.hpp:308
bool operator==(const const_iterator &aOther) const
Definition vecarray.hpp:326
std::random_access_iterator_tag iterator_category
Definition vecarray.hpp:243
vecarray::value_type value_type
Definition vecarray.hpp:244
const_iterator & operator++()
Definition vecarray.hpp:270
const_reference operator[](difference_type aDifference) const
Definition vecarray.hpp:310
vecarray::const_pointer pointer
Definition vecarray.hpp:246
difference_type operator-(const const_iterator &aOther) const
Definition vecarray.hpp:311
const_iterator operator--(int)
Definition vecarray.hpp:287
const_iterator & operator-=(difference_type aDifference)
Definition vecarray.hpp:298
const_iterator & operator+=(difference_type aDifference)
Definition vecarray.hpp:288
const_iterator & operator--()
Definition vecarray.hpp:278
vecarray::difference_type difference_type
Definition vecarray.hpp:245
const_iterator operator++(int)
Definition vecarray.hpp:286
const_iterator(const const_iterator &aOther)
Definition vecarray.hpp:253
bool operator!=(const const_iterator &aOther) const
Definition vecarray.hpp:333
vector_type::const_iterator vector_iter() const
Definition vecarray.hpp:356
bool operator<(const const_iterator &aOther) const
Definition vecarray.hpp:340
vecarray::reference reference
Definition vecarray.hpp:126
bool operator!=(const iterator &aOther) const
Definition vecarray.hpp:206
vecarray::pointer pointer
Definition vecarray.hpp:125
iterator(const iterator &aOther)
Definition vecarray.hpp:132
std::random_access_iterator_tag iterator_category
Definition vecarray.hpp:122
pointer operator->() const
Definition vecarray.hpp:198
vecarray::value_type value_type
Definition vecarray.hpp:123
bool operator==(const iterator &aOther) const
Definition vecarray.hpp:199
reference operator[](difference_type aDifference) const
Definition vecarray.hpp:183
iterator(typename vector_type::iterator aIter)
Definition vecarray.hpp:138
iterator operator-(difference_type aDifference) const
Definition vecarray.hpp:182
vector_type::iterator vector_iter() const
Definition vecarray.hpp:228
iterator & operator-=(difference_type aDifference)
Definition vecarray.hpp:171
iterator & operator+=(difference_type aDifference)
Definition vecarray.hpp:161
difference_type operator-(const iterator &aOther) const
Definition vecarray.hpp:184
iterator operator+(difference_type aDifference) const
Definition vecarray.hpp:181
reference operator*() const
Definition vecarray.hpp:191
vecarray::difference_type difference_type
Definition vecarray.hpp:124
bool operator<(const iterator &aOther) const
Definition vecarray.hpp:213
size_type max_size() const
Definition vecarray.hpp:444
const_reference operator[](size_type n) const
Definition vecarray.hpp:450
void resize(size_type n, const value_type &value)
Definition vecarray.hpp:621
void reserve(size_type n)
Definition vecarray.hpp:633
static constexpr bool is_fixed_size()
Definition vecarray.hpp:373
const_reference at(size_type n) const
Definition vecarray.hpp:452
std::ptrdiff_t difference_type
Definition vecarray.hpp:113
vecarray(size_type n, value_type value)
Definition vecarray.hpp:407
bool full() const
Definition vecarray.hpp:440
vecarray(InputIterator first, InputIterator last)
Definition vecarray.hpp:412
const_iterator cbegin() const
Definition vecarray.hpp:429
const T & const_reference
Definition vecarray.hpp:111
const_reverse_iterator rbegin() const
Definition vecarray.hpp:436
vecarray(std::initializer_list< T > init)
Definition vecarray.hpp:416
std::vector< value_type, allocator_type > vector_type
Definition vecarray.hpp:115
reference front()
Definition vecarray.hpp:453
void assign(size_type n, value_type value)
Definition vecarray.hpp:479
char iVector[sizeof(vector_type)]
Definition vecarray.hpp:782
reference back()
Definition vecarray.hpp:454
std::reverse_iterator< iterator > reverse_iterator
Definition vecarray.hpp:369
bool empty() const
Definition vecarray.hpp:439
reference emplace_back(Args &&... args)
Definition vecarray.hpp:553
iterator insert(const_iterator position, size_type count, const value_type &value)
Definition vecarray.hpp:498
const_reference back() const
Definition vecarray.hpp:456
const_iterator cend() const
Definition vecarray.hpp:432
std::size_t size_type
Definition vecarray.hpp:112
char iData[sizeof(T) *ArraySize]
Definition vecarray.hpp:781
void remove(value_type value, bool multiple=true)
Definition vecarray.hpp:594
size_type after(size_type position) const
Definition vecarray.hpp:445
reference operator[](size_type n)
Definition vecarray.hpp:449
iterator erase(const_iterator position)
Definition vecarray.hpp:514
vecarray(vecarray &&rhs)
Definition vecarray.hpp:384
iterator erase(const_iterator first, const_iterator last)
Definition vecarray.hpp:528
const_iterator begin() const
Definition vecarray.hpp:430
vecarray(const vecarray &rhs)
Definition vecarray.hpp:380
reference at(size_type n)
Definition vecarray.hpp:451
bool operator==(const vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs) const
Definition vecarray.hpp:649
const T * const_pointer
Definition vecarray.hpp:109
void push_back(value_type &&value)
Definition vecarray.hpp:578
bool operator!=(const vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs) const
Definition vecarray.hpp:654
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition vecarray.hpp:370
size_type size() const
Definition vecarray.hpp:441
void assign(InputIterator first, InputIterator last)
Definition vecarray.hpp:474
void push_back(const value_type &value)
Definition vecarray.hpp:566
const_reverse_iterator rend() const
Definition vecarray.hpp:438
size_type available() const
Definition vecarray.hpp:442
iterator end()
Definition vecarray.hpp:434
void resize(size_type n)
Definition vecarray.hpp:609
iterator begin()
Definition vecarray.hpp:431
vecarray(const vecarray< T2, N2 > &rhs)
Definition vecarray.hpp:399
const_reference front() const
Definition vecarray.hpp:455
reverse_iterator rend()
Definition vecarray.hpp:437
vecarray & operator=(const vecarray &rhs)
Definition vecarray.hpp:460
void swap(vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs)
Definition vecarray.hpp:639
vecarray(size_type n)
Definition vecarray.hpp:403
iterator insert(const_iterator position, value_type value)
Definition vecarray.hpp:492
std::enable_if_t<!std::is_integral< InputIterator >::value, iterator > insert(const_iterator position, InputIterator first, InputIterator last)
Definition vecarray.hpp:486
reverse_iterator rbegin()
Definition vecarray.hpp:435
const_iterator end() const
Definition vecarray.hpp:433
size_type capacity() const
Definition vecarray.hpp:443
vecarray & operator=(const vecarray< T2, N2 > &rhs)
Definition vecarray.hpp:467
void resize(size_type aSize) final
Definition vector.hpp:188
void emplace_back(Args &&... aArgs)
Definition vector.hpp:206
void push_back(abstract_value_type const &aValue) final
Definition vector.hpp:201
size_type size() const noexcept final
Definition vector.hpp:133
bool constexpr vecarray_trivial_v
Definition vecarray.hpp:75
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
Definition plf_hive.h:89
iterator_traits< it_type >::difference_type distance(const it_type first, const it_type last)
Definition plf_hive.h:107
static void test(bool aValid)
Definition vecarray.hpp:67
static void test(bool aValid)
Definition vecarray.hpp:57
virtual const char * what() const
Definition vecarray.hpp:52