7#include <initializer_list>
13 template <
typename Strategy>
15 std::default_initializable<Strategy> &&
16 noexcept(Strategy()) &&
17 requires(Strategy strategy, std::size_t num) {
18 { strategy(num) } -> std::same_as<std::size_t>;
24 return oldCapacity + oldCapacity / 2 + 1;
30 return oldCapacity * 2 + 1;
39 std::size_t n3 =
n1 +
n2;
42 }
while (
n2 <= oldCapacity);
48 template <
typename T,
typename Allocator = PolymorphicAllocator<T>, GrowthStrategy Strategy = VectorGrowthStrategy::GoldenExpand>
111 :
Vector(std::move(rhs), rhs.get_allocator()) {
122 if (rhs.get_allocator() == allocator) {
126 Vector rhsCopy(rhs, allocator);
127 swap(*this, rhsCopy);
136 template <std::input_iterator It>
140 size_(std::distance(first, last)),
185 noexcept(std::is_nothrow_swappable_v<Vector>) {
191 assert(i <
size_ &&
"index out of bound");
196 assert(i <
size_ &&
"index out of bound");
225 constexpr std::size_t
size() const noexcept {
237 constexpr bool empty() const noexcept {
244 assert(0 <
size_ &&
"access empty Vector front");
250 constexpr const T&
front() const noexcept {
251 assert(0 <
size_ &&
"access empty Vector front");
258 assert(0 <
size_ &&
"access empty Vector back");
264 constexpr const T&
back() const noexcept {
265 assert(0 <
size_ &&
"access empty Vector back");
313 template <
typename ...Args>
324 assert(0 <
size_ &&
"can not pop back from an empty vector");
333 assert(
begin() <= pos && pos <
end() &&
"can not erase before begin() or at the end()");
334 std::move(pos + 1,
end(), pos);
344 assert(
begin() <= first && last <=
end() &&
"can not erase before begin() or past the end()");
345 assert(first <= last &&
"first must be before last");
347 iterator afterMoved = std::move(last,
end(), first);
349 size_ -= last - first;
356 template <
typename ...Args>
368 std::move_backward(pos,
end() - 1,
end());
369 *pos = T(std::forward<Args>(args)...);
373 std::size_t index = pos -
buffer_;
375 allocator_trait::construct(
allocator_,
buffer_ + index, std::forward<Args>(args)...);
391 emplace(pos, std::move(value));
408 template <std::input_iterator It>
410 const std::size_t insertedElementsSize = std::distance(first, last);
411 const std::size_t requiredSize =
size_ + insertedElementsSize;
415 std::size_t index = pos -
begin();
422 const std::size_t shiftedElementSize =
end() - pos;
423 const std::size_t conflictedRangeSize = std::min(insertedElementsSize, shiftedElementSize);
424 const std::size_t shiftedElementsInboundSize = shiftedElementSize - conflictedRangeSize;
425 const std::size_t insertedElementsOutboundSize = insertedElementsSize - conflictedRangeSize;
433 std::move_backward(pos, pos + shiftedElementsInboundSize,
end());
437 for (std::size_t i = 0; i < conflictedRangeSize; ++i, ++first, ++pos) {
447 size_ = requiredSize;
454 insert(pos, list.begin(), list.end());
468 assert(
capacity_ <
capacity &&
"new capacity is no larger than the old capacity");
477 assert(
capacity_ <
capacity &&
"new capacity is no larger than the old capacity");
485 template <
typename ...U>
487 static_assert(
sizeof...(optionalValue) <= 1,
"no fill value or exactly one copy");
505 swap(lhs.allocator_, rhs.allocator_);
506 swap(lhs.growthStrategy_, rhs.growthStrategy_);
507 swap(lhs.size_, rhs.size_);
508 swap(lhs.capacity_, rhs.capacity_);
509 swap(lhs.buffer_, rhs.buffer_);
516 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
521 return !(lhs == rhs);
Iterator that returns a constant value a fixed number of times. Useful for creating a virtual range o...
void insert(iterator pos, It first, It last)
Inserts a range of elements at the specified position. Does not support self-insertion.
allocator_type get_allocator() const noexcept
void emplaceBack(Args &&... args)
Constructs an element in-place at the end of the vector.
constexpr std::size_t size() const noexcept
Returns the number of elements in the vector.
constexpr Vector(Vector &&rhs) noexcept
Move-constructs a vector with the same allocator as the source.
iterator erase(iterator first, iterator last) noexcept
Removes elements in the range [first, last).
constexpr const T & back() const noexcept
Returns a reference to the last element.
constexpr Vector(Vector &&rhs, const allocator_type &allocator)
Move-constructs a vector with a custom allocator.
void pushBack(const T &value)
Adds an element to the end of the vector.
iterator begin() noexcept
void relocateBufferWithHoles(std::size_t capacity, iterator pos, std::size_t holeSize)
constexpr Vector(const Vector &rhs)
Copy-constructs a vector using the same allocator as the source.
constexpr std::size_t capacity() const noexcept
Returns the total allocated capacity.
VectorGrowthStrategy::GoldenExpand growthStrategy_
void emplace(iterator pos, Args &&... args)
Constructs an element in-place at the specified iterator position.
constexpr Vector(std::size_t count, const allocator_type &allocator={})
Constructs a vector with count default-initialized elements.
iterator erase(iterator pos) noexcept
Removes an element at the specified iterator position.
std::allocator_traits< Allocator > allocator_trait
void pushBack(T &&value)
Adds an element to the end of the vector.
void insert(iterator pos, T &&value)
Inserts a moved element at the specified iterator position.
T & operator[](std::size_t i) noexcept
constexpr Vector(std::size_t count, const T &value, const allocator_type &allocator={})
Constructs a vector with count copies of a given value.
void resize(std::size_t size, const T &value)
Resizes the vector and fills new elements with a given value.
constexpr Vector(const allocator_type &allocator) noexcept(noexcept(allocator_type(allocator)))
Constructs an empty vector with a specific allocator.
void resizeImp(std::size_t size, const U &... optionalValue)
const T & operator[](std::size_t i) const noexcept
void relocateBuffer(std::size_t capacity)
void updateBuffer(T *buffer, std::size_t capacity)
constexpr const T & front() const noexcept
Returns a reference to the first element.
constexpr Vector(It first, It last, const allocator_type &allocator={})
Constructs a vector from an iterator range.
T & front() noexcept
Returns a reference to the first element.
void resize(std::size_t size)
Resizes the vector to contain the given number of default constructed elements.
const T & const_reference
void insert(iterator pos, std::size_t count, const T &value)
Inserts multiple copies of a value at the specified position.
void insert(iterator pos, std::initializer_list< T > list)
Inserts an initializer list of elements at the specified position.
friend void swap(Vector &lhs, Vector &rhs) noexcept
T & back() noexcept
Returns a reference to the last element.
allocator_type allocator_
Vector & operator=(Vector rhs) noexcept(std::is_nothrow_swappable_v< Vector >)
constexpr bool empty() const noexcept
Checks whether the vector is empty.
constexpr const_iterator end() const noexcept
std::ptrdiff_t difference_type
constexpr Vector(std::initializer_list< T > list, const allocator_type &allocator={})
Constructs a vector from an initializer list.
void popBack() noexcept
Removes the last element of the vector.
void clear() noexcept
Clears the contents of the vector.
constexpr Vector(const Vector &rhs, const allocator_type &allocator)
Copy-constructs a vector with a custom allocator.
constexpr Vector() noexcept
Constructs an empty vector with default allocator and growth strategy.
constexpr const_iterator begin() const noexcept
void reserve(std::size_t capacity)
Ensures the vector can hold at least the given capacity without reallocating.
void insert(iterator pos, const T &value)
Inserts a copy of an element at the specified iterator position.
bool operator!=(const flow::Vector< T > &lhs, const flow::Vector< T > &rhs) noexcept
bool operator==(const flow::Vector< T > &lhs, const flow::Vector< T > &rhs) noexcept
OutputIt uninitializedEmplace(AllocatorType &allocator, OutputIt first, OutputIt last, const Args &... args)
Constructs objects in uninitialized memory by copying arguments to their constructor....
void destroyElements(AllocatorType &allocator, InputIt first, InputIt last) noexcept
Destroys a range of constructed objects in memory.
void destroyElementsN(AllocatorType &allocator, InputIt first, std::size_t count) noexcept
Destroys count objects in a range.
OutputIt uninitializedMove(AllocatorType &allocator, InputIt first, InputIt last, OutputIt dest) noexcept
Moves elements from a source range to uninitialized memory.
OutputIt uninitializedFillN(AllocatorType &allocator, OutputIt first, std::size_t count, const T &value)
Fills count elements in uninitialized memory with a value.
OutputIt uninitializedForwardN(AllocatorType &allocator, InputIt first, std::size_t count, OutputIt dest)
Forward count elements from a source range to uninitialized memory.
OutputIt uninitializedForward(AllocatorType &allocator, InputIt first, InputIt last, OutputIt dest)
Forward elements from a source range to uninitialized memory.
void deleteBuffer(AllocatorType &allocator, T *buffer, std::size_t size, std::size_t capacity) noexcept
Destroys and deallocates the buffer.
OutputIt uninitializedEmplaceN(AllocatorType &allocator, OutputIt first, std::size_t count, const Args &... args)
Constructs a specified number of objects in uninitialized memory by copying constructor arguments....
std::size_t operator()(std::size_t oldCapacity) const
std::size_t operator()(std::size_t oldCapacity)
std::size_t operator()(std::size_t oldCapacity) const