59#ifndef TPL_SMALL_VECTOR_H
60#define TPL_SMALL_VECTOR_H
63#include <initializer_list>
116template <
typename T,
size_t N = 8>
119 static_assert(
N > 0,
"SmallVector requires a positive inline capacity");
120 static_assert(std::is_move_constructible_v<T>,
121 "SmallVector requires a move-constructible element type");
137 return reinterpret_cast<const T *
>(
storage_);
142 return std::allocator<T>().allocate(
m);
147 std::allocator<T>().deallocate(p,
m);
159 ::new (
static_cast<void *
>(
np + i))
T(std::move_if_noexcept(
ptr_[i]));
163 std::destroy(
np,
np + i);
181 <<
"SmallVector::grow(): capacity overflow";
192 if constexpr (std::is_nothrow_move_constructible_v<T>)
194 for (;
n_ <
o.n_; ++
n_)
201 for (;
n_ <
o.n_; ++
n_)
210 std::destroy(
o.ptr_,
o.ptr_ +
o.n_);
218 o.ptr_ =
o.inline_ptr();
252 requires std::is_copy_constructible_v<T>
274 requires std::is_copy_constructible_v<T>
300 template <std::input_iterator It>
305 for (; first != last; ++first)
317 requires std::is_copy_constructible_v<T>
324 for (;
n_ < v.n_; ++
n_)
347 requires std::is_copy_constructible_v<T>
354 for (;
n_ < v.n_; ++
n_)
385 std::swap(
ptr_, v.ptr_);
387 std::swap(
cap_, v.cap_);
391 *
this = std::move(v);
535 template <
class...
Args>
545 ::new (
static_cast<void *
>(
ptr_ +
n_))
T(std::forward<Args>(
args)...);
556 requires std::is_copy_constructible_v<T>
614 requires std::is_copy_constructible_v<T>
619 <<
"SmallVector::append_range(): null source pointer";
626 <<
"SmallVector::append_range(): count overflows size_t when added "
627 "to the current size";
630 if constexpr (std::is_trivially_copyable_v<T>)
642 std::uninitialized_copy_n(first,
count,
ptr_ +
n_);
650 for (; i <
count; ++i)
664 requires std::is_copy_constructible_v<T>
672 return append(std::move(item));
684 std::destroy_at(
ptr_ + --
n_);
695 std::destroy_at(
ptr_ + --
n_);
707 requires std::is_move_assignable_v<T>
714 ::new (
static_cast<void *
>(
ptr_ +
n_))
T(std::move(item));
718 for (
size_t i =
n_ - 1; i > pos; --i)
720 ptr_[pos] = std::move(item);
731 requires std::is_move_assignable_v<T>
734 for (
size_t i = pos; i + 1 <
n_; ++i)
736 std::destroy_at(
ptr_ + --
n_);
786 template <
class Operation>
789 for (
size_t i = 0; i <
n_; ++i)
800 template <
class Operation>
803 for (
size_t i = 0; i <
n_; ++i)
821 for (
size_t i = 0; i <
n_; ++i)
831 return not (*
this == v);
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
size_t size_t int32_t value
Generic filter iterator wrapper.
size_t size() const noexcept
Count the number of elements of the list.
Contiguous dynamic array with N elements of inline storage.
const_iterator end() const noexcept
Const iterator past the last element. O(1).
void relocate(const size_t new_cap)
static void deallocate(T *p, size_t m) noexcept
T & push_back(const T &item)
STL-style alias of append(const T &).
size_t size_type
STL convention: size type.
size_t capacity() const noexcept
Return the current capacity (inline or heap). O(1).
size_t size() const noexcept
Return the number of stored elements. O(1).
void reserve(const size_t cap)
Reserve capacity for at least cap elements.
T & get_last()
Last element (checked).
const T * const_iterator
Random-access const iterator.
SmallVector(It first, It last)
Construct from an iterator range.
SmallVector(const SmallVector &v)
Copy constructor (requires copyable T).
T & emplace_back(Args &&...args)
Construct an element in place at the end.
const_iterator cend() const noexcept
Const iterator past the last element. O(1).
const_iterator begin() const noexcept
Const iterator to the first element. O(1).
void append_range(const T *first, const size_t count)
Append count copies from [first, first + count), in order.
T & append(const T &item)
Append a copy of item.
SmallVector() noexcept
Construct an empty vector using the inline storage. Never allocates.
void empty() noexcept
Destroy all elements (Aleph convention).
iterator end() noexcept
Iterator past the last element. O(1).
void steal(SmallVector &&o) noexcept(std::is_nothrow_move_constructible_v< T >)
bool traverse(Operation operation) const
Const traversal in order while operation returns true.
SmallVector(const size_t n, const T &value)
Construct with n copies of value.
static T * allocate(size_t m)
T * data() noexcept
Pointer to the contiguous element storage. O(1).
T & operator()(size_t i) noexcept
Unchecked access to the i-th element (must be < size()).
bool traverse(Operation operation)
Traverse elements in order while operation returns true.
void swap(SmallVector &v) noexcept(std::is_nothrow_move_constructible_v< T >)
Swap contents with v.
const T & get_first() const
bool is_small() const noexcept
Return true while the elements still live in the inline buffer. O(1).
T & append(T &&item)
Append item by moving.
T * inline_ptr() noexcept
T remove_last()
Remove and return the last element.
T & get_first()
First element (checked).
T value_type
STL convention: value type.
bool operator==(const SmallVector< T, M > &v) const
Equality: same size and pairwise equal elements.
std::byte storage_[N *sizeof(T)]
SmallVector & operator=(const SmallVector &v)
Copy assignment (requires copyable T).
T & insert(size_t pos, T item)
Insert an element at position pos, shifting the tail right.
void pop_back()
Remove the last element (STL style).
const T * data() const noexcept
SmallVector(SmallVector &&v) noexcept(std::is_nothrow_move_constructible_v< T >)
Move constructor.
iterator begin() noexcept
Iterator to the first element. O(1).
T & operator[](size_t i)
Checked access to the i-th element.
bool operator!=(const SmallVector< T, M > &v) const
Inequality: negation of operator==.
const T * inline_ptr() const noexcept
void erase(const size_t pos)
Remove the element at position pos, shifting the tail left.
bool is_empty() const noexcept
Return true if no elements are stored. O(1).
SmallVector(std::initializer_list< T > l)
Construct from an initializer list.
T * iterator
Random-access iterator.
const_iterator cbegin() const noexcept
Const iterator to the first element. O(1).
T & push_back(T &&item)
STL-style alias of append(T &&).
void grow(const size_t min_cap)
void clear() noexcept
Destroy all elements. Alias of empty(). Capacity is kept.
T Item_Type
Aleph convention: element type.
const T & get_last() const
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)