52 virtual const char*
what()
const throw() {
return "neolib::vecarray_overflow"; }
57 inline static void test(
bool aValid)
64 template <
typename Exception>
67 inline static void test(
bool aValid)
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)
82 std::uninitialized_copy(first1, last1, dest1);
85 std::uninitialized_copy(first2, last2, dest2);
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)
99 template<
typename T, std::
size_t ArraySize, std::
size_t MaxVectorSize = ArraySize,
typename CheckPolicy = check<vecarray_overflow>,
typename Alloc = std::allocator<T> >
105 enum iterator_type_e { ArrayIterator, VectorIterator };
129 iterator() : iType(ArrayIterator), iArrayPtr(0), iVectorIter()
132 iterator(
const iterator& aOther) : iType(aOther.iType), iArrayPtr(aOther.iArrayPtr), iVectorIter(aOther.iVectorIter)
135 iterator(T* aPtr) : iType(ArrayIterator), iArrayPtr(aPtr), iVectorIter()
138 iterator(
typename vector_type::iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
145 if (iType == ArrayIterator)
153 if (iType == ArrayIterator)
165 if (iType == ArrayIterator)
166 iArrayPtr += aDifference;
168 iVectorIter += aDifference;
175 if (iType == ArrayIterator)
176 iArrayPtr -= aDifference;
178 iVectorIter -= aDifference;
186 if (iType == ArrayIterator)
187 return iArrayPtr - aOther.iArrayPtr;
189 return iVectorIter - aOther.iVectorIter;
193 if (iType == ArrayIterator)
201 if (iType == ArrayIterator)
202 return iArrayPtr == aOther.iArrayPtr;
204 return iVectorIter == aOther.iVectorIter;
208 if (iType == ArrayIterator)
209 return iArrayPtr != aOther.iArrayPtr;
211 return iVectorIter != aOther.iVectorIter;
215 if (iType == ArrayIterator)
216 return iArrayPtr < aOther.iArrayPtr;
218 return iVectorIter < aOther.iVectorIter;
223 if (iType == ArrayIterator)
230 if (iType == VectorIterator)
236 iterator_type_e iType;
238 typename vector_type::iterator iVectorIter;
259 const_iterator(
const T* aPtr) : iType(ArrayIterator), iArrayPtr(aPtr), iVectorIter()
262 const_iterator(
typename vector_type::const_iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
265 const_iterator(
typename vector_type::iterator aIter) : iType(VectorIterator), iArrayPtr(0), iVectorIter(aIter)
272 if (iType == ArrayIterator)
280 if (iType == ArrayIterator)
292 if (iType == ArrayIterator)
293 iArrayPtr += aDifference;
295 iVectorIter += aDifference;
302 if (iType == ArrayIterator)
303 iArrayPtr -= aDifference;
305 iVectorIter -= aDifference;
313 if (iType == ArrayIterator)
314 return iArrayPtr - aOther.iArrayPtr;
316 return iVectorIter - aOther.iVectorIter;
320 if (iType == ArrayIterator)
328 if (iType == ArrayIterator)
329 return iArrayPtr == aOther.iArrayPtr;
331 return iVectorIter == aOther.iVectorIter;
335 if (iType == ArrayIterator)
336 return iArrayPtr != aOther.iArrayPtr;
338 return iVectorIter != aOther.iVectorIter;
342 if (iType == ArrayIterator)
343 return iArrayPtr < aOther.iArrayPtr;
345 return iVectorIter < aOther.iVectorIter;
351 if (iType == ArrayIterator)
358 if (iType == VectorIterator)
365 iterator_type_e iType;
367 typename vector_type::const_iterator iVectorIter;
373 static constexpr bool is_fixed_size() {
return ArraySize == MaxVectorSize; }
388 vector() = std::move(rhs.vector());
393 for (
auto&& element : rhs)
398 template <
typename T2, std::
size_t N2>
411 template<
typename InputIterator>
412 vecarray(InputIterator first, InputIterator last) : iSize{ 0 }
416 vecarray(std::initializer_list<T> init) : iSize{ 0 }
440 bool full()
const {
return size() == MaxVectorSize; }
466 template<
typename T2, std::
size_t N2>
469 if (
static_cast<const void*
>(&rhs) !=
static_cast<const void*
>(
this))
473 template <
typename InputIterator>
474 void assign(InputIterator first, InputIterator last)
484 template <
class InputIterator>
485 typename std::enable_if_t<!std::is_integral<InputIterator>::value,
iterator>
489 position = do_insert(position, first, last);
495 insert(position, 1, value);
500 need(count, position);
520 auto garbage = std::copy(std::make_move_iterator(
std::next(dest)), std::make_move_iterator(
end()), dest);
521 (*garbage).~value_type();
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)
542 iSize -= (last - first);
552 template<
class... Args >
555 CheckPolicy::test(
size() < MaxVectorSize);
568 CheckPolicy::test(
size() < MaxVectorSize);
580 CheckPolicy::test(
size() < MaxVectorSize);
635 if (n > ArraySize && n >
size())
638 template<
typename T2, std::
size_t ArraySize2, std::
size_t MaxVectorSize2,
typename CheckPolicy2,
typename Alloc2>
648 template<
typename T2, std::
size_t ArraySize2, std::
size_t MaxVectorSize2,
typename CheckPolicy2,
typename Alloc2>
653 template<
typename T2, std::
size_t ArraySize2, std::
size_t MaxVectorSize2,
typename CheckPolicy2,
typename Alloc2>
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
665 template <std::
size_t ArraySize2 = ArraySize, std::
size_t MaxVectorSize2 = MaxVectorSize>
666 typename std::enable_if<ArraySize2 != MaxVectorSize2, bool>::type using_array()
const
668 return iSize != USING_VECTOR;
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
675 template <std::
size_t ArraySize2 = ArraySize, std::
size_t MaxVectorSize2 = MaxVectorSize>
676 typename std::enable_if<ArraySize2 != MaxVectorSize2, bool>::type using_vector()
const
678 return iSize == USING_VECTOR;
682 return reinterpret_cast<vector_type&
>(iAlignedBuffer.iVector);
686 return reinterpret_cast<const vector_type&
>(iAlignedBuffer.iVector);
690 if (using_array() &&
size() + aAmount > ArraySize)
693 template <
typename Iter>
694 void need(
size_type aAmount, Iter& aIter)
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)
700 if constexpr (std::is_same_v<Iter, const_iterator>)
706 else if constexpr (std::is_same_v<Iter, iterator>)
710 aIter =
begin() + index;
719 copy.reserve(std::max(ArraySize * 2,
size() + aExtra));
720 copy.insert(copy.begin(), std::make_move_iterator(
begin()), std::make_move_iterator(
end()));
722 new (iAlignedBuffer.iVector)
vector_type{ std::move(copy) };
723 iSize = USING_VECTOR;
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)
731 CheckPolicy::test(
size() + n <= MaxVectorSize);
735 auto pos =
const_cast<pointer>(position.array_ptr());
736 const_iterator theEnd =
end();
742 std::uninitialized_copy(theEnd - n, theEnd,
const_cast<pointer>(theEnd.array_ptr()));
744 std::copy_backward(position, theEnd - n,
const_cast<pointer>(theEnd.array_ptr()));
745 std::copy(first, last, pos);
749 detail::uninitialized_copy2(theEnd - t, theEnd,
const_cast<pointer>((theEnd + (n - t)).array_ptr()), first + t, last,
const_cast<pointer>(theEnd.array_ptr()));
751 std::copy(first, first + t, pos);
756 std::uninitialized_copy(first, last, pos);
763 return vector().insert(position.vector_iter(), first, last);
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)
770 iterator
next = position;
771 while (first != last)
781 alignas(T)
char iData[
sizeof(T) * ArraySize];
iterator insert(const const_iterator &aPosition, const value_type &aValue)
iterator erase(const const_iterator &aPosition)
const_iterator(typename vector_type::const_iterator aIter)
const T * array_ptr() const
const_pointer operator->() const
const_iterator(typename vector_type::iterator aIter)
vecarray::const_reference reference
const_iterator operator-(difference_type aDifference) const
const_reference operator*() const
const_iterator(const typename vecarray::iterator &aOther)
const_iterator operator+(difference_type aDifference) const
bool operator==(const const_iterator &aOther) const
std::random_access_iterator_tag iterator_category
vecarray::value_type value_type
const_iterator & operator++()
const_reference operator[](difference_type aDifference) const
vecarray::const_pointer pointer
difference_type operator-(const const_iterator &aOther) const
const_iterator operator--(int)
const_iterator & operator-=(difference_type aDifference)
const_iterator & operator+=(difference_type aDifference)
const_iterator & operator--()
vecarray::difference_type difference_type
const_iterator operator++(int)
const_iterator(const const_iterator &aOther)
bool operator!=(const const_iterator &aOther) const
const_iterator(const T *aPtr)
vector_type::const_iterator vector_iter() const
bool operator<(const const_iterator &aOther) const
vecarray::reference reference
bool operator!=(const iterator &aOther) const
vecarray::pointer pointer
iterator(const iterator &aOther)
std::random_access_iterator_tag iterator_category
pointer operator->() const
vecarray::value_type value_type
bool operator==(const iterator &aOther) const
reference operator[](difference_type aDifference) const
iterator(typename vector_type::iterator aIter)
iterator operator-(difference_type aDifference) const
vector_type::iterator vector_iter() const
iterator & operator-=(difference_type aDifference)
iterator & operator+=(difference_type aDifference)
difference_type operator-(const iterator &aOther) const
iterator operator+(difference_type aDifference) const
reference operator*() const
vecarray::difference_type difference_type
bool operator<(const iterator &aOther) const
size_type max_size() const
const_reference operator[](size_type n) const
void resize(size_type n, const value_type &value)
void reserve(size_type n)
static constexpr bool is_fixed_size()
const_reference at(size_type n) const
std::ptrdiff_t difference_type
vecarray(size_type n, value_type value)
vecarray(InputIterator first, InputIterator last)
const_iterator cbegin() const
const T & const_reference
const_reverse_iterator rbegin() const
vecarray(std::initializer_list< T > init)
std::vector< value_type, allocator_type > vector_type
void assign(size_type n, value_type value)
char iVector[sizeof(vector_type)]
std::reverse_iterator< iterator > reverse_iterator
reference emplace_back(Args &&... args)
iterator insert(const_iterator position, size_type count, const value_type &value)
const_reference back() const
const_iterator cend() const
char iData[sizeof(T) *ArraySize]
void remove(value_type value, bool multiple=true)
size_type after(size_type position) const
reference operator[](size_type n)
iterator erase(const_iterator position)
iterator erase(const_iterator first, const_iterator last)
const_iterator begin() const
vecarray(const vecarray &rhs)
reference at(size_type n)
bool operator==(const vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs) const
void push_back(value_type &&value)
bool operator!=(const vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs) const
std::reverse_iterator< const_iterator > const_reverse_iterator
void assign(InputIterator first, InputIterator last)
void push_back(const value_type &value)
const_reverse_iterator rend() const
size_type available() const
vecarray(const vecarray< T2, N2 > &rhs)
const_reference front() const
vecarray & operator=(const vecarray &rhs)
void swap(vecarray< T2, ArraySize2, MaxVectorSize2, CheckPolicy2, Alloc2 > &rhs)
iterator insert(const_iterator position, value_type value)
std::enable_if_t<!std::is_integral< InputIterator >::value, iterator > insert(const_iterator position, InputIterator first, InputIterator last)
reverse_iterator rbegin()
const_iterator end() const
size_type capacity() const
vecarray & operator=(const vecarray< T2, N2 > &rhs)
void resize(size_type aSize) final
void emplace_back(Args &&... aArgs)
void push_back(abstract_value_type const &aValue) final
size_type size() const noexcept final
bool constexpr vecarray_trivial_v
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
iterator_traits< it_type >::difference_type distance(const it_type first, const it_type last)
static void test(bool aValid)
static void test(bool aValid)
virtual const char * what() const