72template<
typename Tp,
typename Alloc = std::allocator<Tp> >
75 static_assert(std::is_standard_layout<Tp>(),
"A uvector can only hold classes with standard layout");
106#if __cplusplus > 201402L
107 typedef typename std::allocator_traits<allocator_type>::is_always_equal
148 std::uninitialized_fill_n<Tp*,size_t>(
_begin, n, val);
156 template<
class InputIterator>
160 construct_from_range<InputIterator>(
first, last, std::is_integral<InputIterator>());
169 Alloc(
std::allocator_traits<Alloc>::select_on_container_copy_construction(static_cast<
allocator_type>(other))),
194 Alloc(std::move(other)),
199 other._begin =
nullptr;
200 other._end =
nullptr;
201 other._endOfStorage =
nullptr;
214 other._begin =
nullptr;
215 other._end =
nullptr;
216 other._endOfStorage =
nullptr;
230 for(
typename std::initializer_list<Tp>::const_iterator i=initlist.begin(); i!=initlist.end(); ++i)
249 return assign_copy_from(other,
typename std::allocator_traits<Alloc>::propagate_on_container_copy_assignment());
257 std::allocator_traits<Alloc>::propagate_on_container_move_assignment::value||
258 allocator_is_always_equal::value)
260 return assign_move_from(std::move(other),
typename std::allocator_traits<Alloc>::propagate_on_container_move_assignment());
303 size_t max_size() const noexcept {
return Alloc::max_size(); }
339 size_t oldSize =
size();
350 std::uninitialized_fill<Tp*,size_t>(
_begin + oldSize,
_end, val);
373 const size_t curSize =
size();
378 _end = newStorage + curSize;
391 const size_t curSize =
size();
404 _end = newStorage + curSize;
427 const Tp&
at(
size_t index)
const
443 const Tp&
back() const noexcept {
return *(
_end - 1); }
457 template<
class InputIterator>
460 assign_from_range<InputIterator>(
first, last, std::is_integral<InputIterator>());
478 std::uninitialized_fill_n<Tp*,size_t>(
_begin, n, val);
486 void assign(std::initializer_list<Tp> initlist)
497 for(
typename std::initializer_list<Tp>::const_iterator i=initlist.begin(); i!=initlist.end(); ++i)
527 *
_end = std::move(item);
549 size_t index = position -
_begin;
551 position =
_begin + index;
557 *
const_cast<iterator>(position) = item;
558 return const_cast<iterator>(position);
574 size_t index = position -
_begin;
576 position =
_begin + index;
582 std::uninitialized_fill_n<Tp*,size_t>(
const_cast<iterator>(position), n, val);
583 return const_cast<iterator>(position);
595 template <
class InputIterator>
598 return insert_from_range<InputIterator>(position,
first, last, std::is_integral<InputIterator>());
617 size_t index = position -
_begin;
619 position =
_begin + index;
625 *
const_cast<iterator>(position) = std::move(item);
626 return const_cast<iterator>(position);
641 size_t index = position -
_begin;
643 position =
_begin + index;
646 std::move_backward(
const_cast<iterator>(position),
_end,
_end+initlist.size());
647 _end += initlist.size();
650 for(
typename std::initializer_list<Tp>::const_iterator i=initlist.begin(); i!=initlist.end(); ++i)
655 return const_cast<iterator>(position);
668 return const_cast<iterator>(position);
698 swap(other,
typename std::allocator_traits<Alloc>::propagate_on_container_swap());
715 template<
typename... Args>
720 size_t index = position -
_begin;
722 position =
_begin + index;
728 *
const_cast<iterator>(position) = Tp(std::forward<Args>(args)...);
729 return const_cast<iterator>(position);
736 template<
typename... Args>
741 *
_end = Tp(std::forward<Args>(args)...);
767 size_t index = position -
_begin;
769 position =
_begin + index;
775 return const_cast<iterator>(position);
785 template <
class InputIterator>
788 push_back_range<InputIterator>(
first, last, std::is_integral<InputIterator>());
804 std::uninitialized_fill_n<Tp*,size_t>(
_end, n, val);
820 for(
typename std::initializer_list<Tp>::iterator i = initlist.begin(); i != initlist.end(); ++i)
842 return Alloc::allocate(n);
853 Alloc::deallocate(
begin, n);
856 template<
typename InputIterator>
859 construct_from_range<InputIterator>(
first, last,
typename std::iterator_traits<InputIterator>::iterator_category());
862 template<
typename Integral>
868 std::uninitialized_fill_n<Tp*,size_t>(
_begin, n, val);
871 template<
typename InputIterator>
874 size_t n = std::distance(
first, last);
886 template<
typename InputIterator>
889 assign_from_range<InputIterator>(
first, last,
typename std::iterator_traits<InputIterator>::iterator_category());
894 template<
typename Integral>
905 std::uninitialized_fill_n<Tp*,size_t>(
_begin, n, val);
908 template<
typename InputIterator>
911 size_t n = std::distance(
first, last);
928 template<
typename InputIterator>
931 return insert_from_range<InputIterator>(position,
first, last,
932 typename std::iterator_traits<InputIterator>::iterator_category());
935 template<
typename Integral>
940 size_t index = position -
_begin;
942 position =
_begin + index;
948 std::uninitialized_fill_n<Tp*,size_t>(
const_cast<iterator>(position), n, val);
949 return const_cast<iterator>(position);
952 template<
typename InputIterator>
955 size_t n = std::distance(
first, last);
958 size_t index = position -
_begin;
960 position =
_begin + index;
966 Tp* destIter =
const_cast<iterator>(position);
972 return const_cast<iterator>(position);
978 throw std::out_of_range(
"Access to element in uvector past end");
983 return size() + std::max(
size(), extra_space_needed);
999 std::copy(
_begin,
_begin + insert_position, newStorage);
1000 std::copy(
_begin + insert_position,
_end, newStorage + insert_position + insert_count);
1002 _end = newStorage +
size() + insert_count;
1010 const size_t n = other.
size();
1030 const size_t n = other.
size();
1037 Alloc::operator=(
static_cast<Alloc&
>(other));
1045 if(allocator_is_always_equal::value ||
static_cast<Alloc&
>(other) ==
static_cast<Alloc&
>(*this))
1051 other._begin =
nullptr;
1052 other._end =
nullptr;
1053 other._endOfStorage =
nullptr;
1069 Alloc::operator=(std::move(
static_cast<Alloc&
>(other)));
1073 other._begin =
nullptr;
1074 other._end =
nullptr;
1075 other._endOfStorage =
nullptr;
1082 std::swap(
_begin, other._begin);
1083 std::swap(
_end, other._end);
1085 std::swap(
static_cast<Alloc&
>(other),
static_cast<Alloc&
>(*
this));
1091 std::swap(
_begin, other._begin);
1092 std::swap(
_end, other._end);
1117 template<
typename InputIterator>
1120 push_back_range<InputIterator>(
first, last,
typename std::iterator_traits<InputIterator>::iterator_category());
1125 template<
typename Integral>
1132 std::uninitialized_fill_n<Tp*,size_t>(
_end, n, val);
1136 template<
typename InputIterator>
1139 size_t n = std::distance(
first, last);
1144 while(
first != last)
1155template<
class Tp,
class Alloc>
1158 return lhs.size()==rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
1162template<
class Tp,
class Alloc>
1165 return !(lhs == rhs);
1172template <
class Tp,
class Alloc>
1175 const size_t minSize = std::min(lhs.size(), rhs.size());
1176 for(
size_t i=0; i!=minSize; ++i)
1180 else if(lhs[i] > rhs[i])
1183 return lhs.size() < rhs.size();
1190template <
class Tp,
class Alloc>
1193 const size_t minSize = std::min(lhs.size(), rhs.size());
1194 for(
size_t i=0; i!=minSize; ++i)
1198 else if(lhs[i] > rhs[i])
1201 return lhs.size() <= rhs.size();
1208template <
class Tp,
class Alloc>
1218template <
class Tp,
class Alloc>
1234template <
class Tp,
class Alloc>
A container similar to std::vector, but one that allows construction without initializing its element...
const Tp * const_iterator
Iterator type of constant elements.
void assign_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
iterator insert_uninitialized(const_iterator position, size_t n)
— NON STANDARD METHODS —
~uvector() noexcept
Destructor.
void deallocate() noexcept
Tp * data() noexcept
Get pointer to internal storage.
void shrink_to_fit()
Change the capacity of the container such that no extra space is hold.
uvector(const allocator_type &allocator=Alloc()) noexcept
Construct an empty uvector.
void push_back_uninitialized(size_t n)
Add elements at the end without initializing them.
void push_back(std::initializer_list< Tp > initlist)
Add elements from an initializer list to the end of the container.
Tp & operator[](size_t index) noexcept
Get a reference to the element at the given index.
void push_back_range(InputIterator first, InputIterator last, std::false_type)
const_reverse_iterator crend() const noexcept
Get constant reverse iterator to element before first element.
const Tp & const_reference
Constant reference to element type.
void deallocate(pointer begin, size_t n) noexcept
const_reverse_iterator rbegin() const noexcept
Get constant reverse iterator to last element.
const Tp * data() const noexcept
Get constant pointer to internal storage.
uvector & assign_copy_from(const uvector< Tp, Alloc > &other, std::true_type)
implementation of operator=(const&) with propagate_on_container_copy_assignment
uvector(const uvector< Tp, Alloc > &other, const allocator_type &allocator)
Copy construct a uvector with custom allocator.
uvector(uvector< Tp, Alloc > &&other) noexcept
Move construct a uvector.
uvector & assign_move_from(uvector< Tp, Alloc > &&other, std::false_type) noexcept(allocator_is_always_equal::value)
implementation of operator=() without propagate_on_container_move_assignment
size_t capacity() const noexcept
Get the number of elements the container can currently hold without reallocating storage.
size_t size() const noexcept
Get number of elements in container.
void push_back_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
Tp & at(size_t index)
Get a reference to the element at the given index with bounds checking.
void construct_from_range(InputIterator first, InputIterator last, std::false_type)
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator type.
void resize(size_t n)
Change the number of elements in the container.
iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
void assign_from_range(Integral n, Integral val, std::true_type)
This function is called from assign(iter,iter) when Tp is an integral.
void swap(uvector< Tp, Alloc > &other, std::false_type) noexcept
implementation of swap without propagate_on_container_swap
const_iterator cbegin() const noexcept
Get constant iterator to first element.
Tp * pointer
Pointer to element type.
void push_back_range(Integral n, Integral val, std::true_type)
This function is called from push_back(iter,iter) when Tp is an integral.
reverse_iterator rend() noexcept
Get reverse iterator to element before first element.
void push_back(size_t n, const Tp &val)
Add elements at the end and initialize them with a value.
Tp * iterator
Iterator type.
uvector & operator=(uvector< Tp, Alloc > &&other) noexcept(std::allocator_traits< Alloc >::propagate_on_container_move_assignment::value||allocator_is_always_equal::value)
Assign another uvector to this uvector.
void reserve(size_t n)
Reserve space for a number of elements, to prevent the overhead of extra reallocations.
const_reverse_iterator rend() const noexcept
Get constant reverse iterator to element before first element.
void assign(std::initializer_list< Tp > initlist)
Assign this container to an initializer list.
Tp & reference
Reference to element type.
Tp & back() noexcept
Get reference to last element in container.
const Tp * const_pointer
Pointer to constant element type.
uvector & assign_move_from(uvector< Tp, Alloc > &&other, std::true_type) noexcept
implementation of operator=() with propagate_on_container_move_assignment
Alloc allocator_type
Type of allocator used to allocate and deallocate space.
void enlarge(size_t newSize)
void assign(size_t n, const Tp &val)
Resize the container and assign the given value to all elements.
Tp value_type
Element type.
iterator begin() noexcept
Get iterator to first element.
const_iterator begin() const noexcept
Get constant iterator to first element.
uvector(InputIterator first, InputIterator last, const allocator_type &allocator=Alloc())
Construct a vector by copying elements from a range.
iterator insert(const_iterator position, InputIterator first, InputIterator last)
Insert elements at a given position and initialize them from a range.
void clear()
Remove all elements from the container.
bool empty() const noexcept
Determine if the container is currently empty.
iterator erase(const_iterator position)
Delete an element from the container.
void resize(size_t n, const Tp &val)
Change the number of elements in the container.
const_iterator cend() const noexcept
Get constant iterator to element past last element.
iterator insert_from_range(const_iterator position, Integral n, Integral val, std::true_type)
iterator insert(const_iterator position, std::initializer_list< Tp > initlist)
Insert elements at a given position and initialize them from a initializer list.
std::false_type allocator_is_always_equal
void swap(uvector< Tp, Alloc > &other, std::true_type) noexcept
implementation of swap with propagate_on_container_swap
iterator end() noexcept
Get iterator to element past last element.
void emplace_back(Args &&... args)
Add the given value to the end of the container by constructing it in place.
const Tp & at(size_t index) const
Get a constant reference to the element at the given index with bounds checking.
const_iterator end() const noexcept
Get constant iterator to element past last element.
pointer allocate(size_t n)
iterator insert(const_iterator position, size_t n, const Tp &val)
Insert elements at a given position and initialize them with a value.
const Tp & front() const noexcept
Get constant reference to first element in container.
size_t enlarge_size(size_t extra_space_needed) const noexcept
void pop_back()
Remove the last element from the container.
const Tp & back() const noexcept
Get constant reference to last element in container.
iterator insert(const_iterator position, Tp &&item)
Insert an element at a given position by moving it in.
const Tp & operator[](size_t index) const noexcept
Get a constant reference to the element at the given index.
void enlarge_for_insert(size_t newSize, size_t insert_position, size_t insert_count)
uvector(const uvector< Tp, Alloc > &other)
Copy construct a uvector.
void push_back(InputIterator first, InputIterator last)
Add a range of items to the end of the container.
uvector & assign_copy_from(const uvector< Tp, Alloc > &other, std::false_type)
implementation of operator=(const&) without propagate_on_container_copy_assignment
reverse_iterator rbegin() noexcept
Get reverse iterator to last element.
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator of constant elements.
uvector(std::initializer_list< Tp > initlist, const allocator_type &allocator=Alloc())
Construct a uvector from a initializer list.
void assign(InputIterator first, InputIterator last)
Assign this container to be equal to the given range.
const_reverse_iterator crbegin() const noexcept
Get constant reverse iterator to last element.
Tp & front() noexcept
Get reference to first element in container.
void construct_from_range(Integral n, Integral val, std::true_type)
uvector & operator=(const uvector< Tp, Alloc > &other)
Assign another uvector to this uvector.
void assign_from_range(InputIterator first, InputIterator last, std::false_type)
iterator erase(const_iterator first, const_iterator last)
Delete a range of elements from the container.
void push_back(const Tp &item)
Add the given value to the end of the container.
void swap(uvector< Tp, Alloc > &other) noexcept
Swap the contents of this uvector with the given uvector.
std::ptrdiff_t difference_type
Difference between to iterators.
void push_back(Tp &&item)
Add the given value to the end of the container by moving it in.
void construct_from_range(InputIterator first, InputIterator last, std::forward_iterator_tag)
uvector(size_t n)
Construct a vector with given amount of elements, without initializing these.
uvector(size_t n, const value_type &val, const allocator_type &allocator=Alloc())
Construct a vector with given amount of elements and set these to a specific value.
size_t max_size() const noexcept
Get maximum number of elements that this container can hold.
allocator_type get_allocator() const noexcept
Get a copy of the allocator.
iterator emplace(const_iterator position, Args &&... args)
Insert an element at a given position by constructing it in place.
void check_bounds(size_t index) const
std::size_t size_t
Type used for indexing elements.
iterator insert(const_iterator position, const Tp &item)
Insert an element at a given position.
uvector(uvector< Tp, Alloc > &&other, const allocator_type &allocator) noexcept
Move construct a uvector with custom allocator.
iterator insert_from_range(const_iterator position, InputIterator first, InputIterator last, std::false_type)
std::size_t size_type
Type used for indexing elements.
bool operator==(const uvector< Tp, Alloc > &lhs, const uvector< Tp, Alloc > &rhs) noexcept
Compare two uvectors for equality.
void swap(uvector< Tp, Alloc > &x, uvector< Tp, Alloc > &y)
Swap the contents of the two uvectors.
bool operator!=(const uvector< Tp, Alloc > &lhs, const uvector< Tp, Alloc > &rhs) noexcept
Compare two uvectors for inequality.
Define real & complex conjugation for non-complex types and put comparisons into std namespace.