Table of Contents
Defined in header sfl/static_unordered_linear_map.hpp
namespace sfl
{
template < typename Key,
typename T,
std::size_t N,
typename KeyEqual = std::equal_to<Key> >
class static_unordered_linear_map;
}
sfl::small_unordered_linear_map is an unordered associative container that contains an unsorted collection of key-value pairs with unique keys. Underlying storage is implemented as an unsorted static_vector, which has a fixed maximum capacity defined at compile time and is backed entirely by statically allocated storage. This container does not perform any dynamic memory allocation. The number of elements in this container cannot be greater than N. Attempting to insert more than N elements into this container results in undefined behavior. This design provides a compact and cache-friendly representation optimized for use cases where the maximum size is known in advance. It is also well-suited for bare-metal embedded development where predictable memory usage and no dynamic allocation are critical.
Complexity of search, insert and remove operations is O(N).
Elements of this container are always stored contiguously in the memory.
Iterators to elements are random access iterators and they meet the requirements of LegacyRandomAccessIterator.
sfl::static_unordered_linear_map meets the requirements of Container and ContiguousContainer. The requirements of UnorderedAssociativeContainer are partionally met (this container doesn't use Hash).
sfl::static_unordered_linear_map can be used in C++20 constant expressions.
Note: Support for C++20 constant expressions is not fully mature in the major compilers (GCC, Clang, MSVC), so the following limitations apply:
- The
data()member function cannot be used in constant expressions. - On GCC, it is not possible to declare
constexprobjects ofstatic_unordered_linear_map. Clang and MSVC allow this, so this is a compiler-specific limitation (possibly a bug).
-
typename KeyKey type.
-
typename TValue type.
-
std::size_t NSize of the internal statically allocated array, i.e. the maximal number of elements that this container can contain.
-
typename KeyEqualFunction for comparing keys.
| Member Type | Definition |
|---|---|
key_type |
Key |
mapped_type |
T |
value_type |
std::pair<Key, T> |
size_type |
Unsigned integer type |
difference_type |
Signed integer type |
key_equal |
KeyEqual |
reference |
value_type& |
const_reference |
const value_type& |
pointer |
Pointer to value_type |
const_pointer |
Pointer to const value_type |
iterator |
LegacyRandomAccessIterator and LegacyContiguousIterator to value_type |
const_iterator |
LegacyRandomAccessIterator and LegacyContiguousIterator to const value_type |
class value_equal
{
public:
bool operator()(const value_type& x, const value_type& y) const;
};
static constexpr size_type static_capacity = N;
-
static_unordered_linear_map() noexcept(std::is_nothrow_default_constructible<KeyEqual>::value) -
explicit static_unordered_linear_map(const KeyEqual& equal) noexcept(std::is_nothrow_copy_constructible<KeyEqual>::value)Effects: Constructs an empty container.
-
template <typename InputIt> static_unordered_linear_map(InputIt first, InputIt last); -
template <typename InputIt> static_unordered_linear_map(InputIt first, InputIt last, const KeyEqual& equal);Preconditions:
std::distance(first, last) <= capacity()Effects: Constructs the container with the contents of the range
[first, last).If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
Note: These overloads participate in overload resolution only if
InputItsatisfies requirements of LegacyInputIterator.Complexity: Linear in
std::distance(first, last). -
static_unordered_linear_map(std::initializer_list<value_type> ilist); -
static_unordered_linear_map(std::initializer_list<value_type> ilist, const KeyEqual& equal);Preconditions:
ilist.size() <= capacity()Effects: Constructs the container with the contents of the initializer list
ilist.If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
Complexity: Linear in
ilist.size(). -
static_unordered_linear_map(const static_unordered_linear_map& other);Effects: Copy constructor. Constructs the container with the copy of the contents of
other.Complexity: Linear in size.
-
static_unordered_linear_map(static_unordered_linear_map&& other);Effects: Move constructor. Constructs the container with the contents of
otherusing move semantics.otheris not guaranteed to be empty after the move.otheris in a valid but unspecified state after the move.Complexity: Linear in size.
-
template <typename Range> static_unordered_linear_map(sfl::from_range_t, Range&& range); -
template <typename Range> static_unordered_linear_map(sfl::from_range_t, Range&& range, const KeyEqual& equal);Effects: Constructs the container with the contents of
range.If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
Note: It is available in C++11. In C++20 are used proper C++20 range concepts.
-
~static_unordered_linear_map();Effects: Destructs the container. The destructors of the elements are called and the used storage is deallocated.
Complexity: Linear in size.
-
static_unordered_linear_map& operator=(const static_unordered_linear_map& other);Effects: Copy assignment operator. Replaces the contents with a copy of the contents of
other.Returns:
*this().Complexity: Linear in size.
-
static_unordered_linear_map& operator=(static_unordered_linear_map&& other);Effects: Move assignment operator. Replaces the contents with those of
otherusing move semantics.otheris not guaranteed to be empty after the move.otheris in a valid but unspecified state after the move.Returns:
*this().Complexity: Linear in size.
-
static_unordered_linear_map& operator=(std::initializer_list<value_type> ilist);Preconditions:
ilist.size() <= capacity()Effects: Replaces the contents with those identified by initializer list
ilist.Returns:
*this().Complexity: Linear in size.
-
key_equal key_eq() const;Effects: Returns the function object that compares keys for equality, which is a copy of this container's constructor argument
equal.Complexity: Constant.
-
value_equal value_eq() const;Effects: Returns a function object that compares objects of type
value_type.Complexity: Constant.
-
iterator begin() noexcept; -
const_iterator begin() const noexcept; -
const_iterator cbegin() const noexcept;Effects: Returns an iterator to the first element of the container. If the container is empty, the returned iterator will be equal to
end().Complexity: Constant.
-
iterator end() noexcept; -
const_iterator end() const noexcept; -
const_iterator cend() const noexcept;Effects: Returns an iterator to the element following the last element of the container. This element acts as a placeholder; attempting to access it results in undefined behavior.
Complexity: Constant.
-
iterator nth(size_type pos) noexcept; -
const_iterator nth(size_type pos) const noexcept;Preconditions:
pos <= size()Effects: Returns an iterator to the element at position
pos.If
pos == size(), the returned iterator is equal toend().Complexity: Constant.
-
size_type index_of(const_iterator pos) const noexcept;Preconditions:
cbegin() <= pos && pos <= cend()Effects: Returns position of the element pointed by iterator
pos, i.e.std::distance(begin(), pos).If
pos == end(), the returned value is equal tosize().Complexity: Constant.
-
bool empty() const noexcept;Effects: Returns
trueif the container has no elements, i.e. whetherbegin() == end().Complexity: Constant.
-
bool full() const noexcept;Effects: Returns
trueif the container is full, i.e. whethersize() == capacity().Complexity: Constant.
-
size_type size() const noexcept;Effects: Returns the number of elements in the container, i.e.
std::distance(begin(), end()).Complexity: Constant.
-
static constexpr size_type max_size() const noexcept;Effects: Returns the maximum number of elements the container is able to hold, i.e.
N.Complexity: Constant.
-
static constexpr size_type capacity() const noexcept;Effects: Returns the maximum number of elements the container is able to hold, i.e.
N.Complexity: Constant.
-
size_type available() const noexcept;Effects: Returns the number of elements that can be inserted into the container, i.e.
capacity() - size().Complexity: Constant.
-
void clear() noexcept;Effects: Erases all elements from the container. After this call,
size()returns zero andcapacity()remains unchanged.Complexity: Linear in
size().
-
template <typename... Args> std::pair<iterator, bool> emplace(Args&&... args);Preconditions:
!full()Effects: Inserts new element into the container if the container doesn't already contain an element with an equivalent key.
New element is constructed as
value_type(std::forward<Args>(args)...).The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.
Returns: The iterator component points to the inserted element or to the already existing element. The
boolcomponent istrueif insertion happened andfalseif it did not.
-
template <typename... Args> iterator emplace_hint(const_iterator hint, Args&&... args);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: Inserts new element into the container if the container doesn't already contain an element with an equivalent key.
New element is constructed as
value_type(std::forward<Args>(args)...).The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.
Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. This overload exists just to have this container compatible with standard C++ containers as much as possible.Returns: Iterator to the inserted element or to the already existing element.
-
std::pair<iterator, bool> insert(const value_type& value);Preconditions:
!full()Effects: Inserts copy of
valueif the container doesn't already contain an element with an equivalent key.Returns: The iterator component points to the inserted element or to the already existing element. The
boolcomponent istrueif insertion happened andfalseif it did not. -
std::pair<iterator, bool> insert(value_type&& value);Preconditions:
!full()Effects: Inserts
valueusing move semantics if the container doesn't already contain an element with an equivalent key.Returns: The iterator component points to the inserted element or to the already existing element. The
boolcomponent istrueif insertion happened andfalseif it did not. -
template <typename P> std::pair<iterator, bool> insert(P&& value);Preconditions:
!full()Effects: Inserts new element into the container if the container doesn't already contain an element with an equivalent key.
New element is constructed as
value_type(std::forward<P>(value)).Note: This overload participates in overload resolution only if
std::is_constructible<value_type, P&&>::valueistrue.Returns: The iterator component points to the inserted element or to the already existing element. The
boolcomponent istrueif insertion happened andfalseif it did not. -
iterator insert(const_iterator hint, const value_type& value);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: Inserts copy of
valueif the container doesn't already contain an element with an equivalent key.Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. This overload exists just to have this container compatible with standard C++ containers as much as possible.Returns: Iterator to the inserted element or to the already existing element.
-
iterator insert(const_iterator hint, value_type&& value);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: Inserts
valueusing move semantics if the container doesn't already contain an element with an equivalent key.Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. This overload exists just to have this container compatible with standard C++ containers as much as possible.Returns: Iterator to the inserted element or to the already existing element.
-
template <typename P> iterator insert(const_iterator hint, P&& value);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: Inserts new element into the container if the container doesn't already contain an element with an equivalent key.
New element is constructed as
value_type(std::forward<P>(value)).Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. This overload exists just to have this container compatible with standard C++ containers as much as possible.Note: This overload participates in overload resolution only if
std::is_constructible<value_type, P&&>::valueistrue.Returns: Iterator to the inserted element or to the already existing element.
-
template <typename InputIt> void insert(InputIt first, InputIt last);Preconditions:
std::distance(first, last) <= available()Effects: Inserts elements from range
[first, last)if the container doesn't already contain an element with an equivalent key.If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
The call to this function is equivalent to:
while (first != last) { insert(*first); ++first; }Note: This overload participates in overload resolution only if
InputItsatisfies requirements of LegacyInputIterator. -
void insert(std::initializer_list<value_type> ilist);Preconditions:
ilist.size() <= available()Effects: Inserts elements from initializer list
ilistif the container doesn't already contain an element with an equivalent key.If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
The call to this function is equivalent to
insert(ilist.begin(), ilist.end()).
-
template <typename Range> void insert_range(Range&& range);Effects: Inserts elements from
rangeif the container doesn't already contain an element with an equivalent key.If multiple elements in the range have keys that compare equivalent, then the first element is inserted.
Note: It is available in C++11. In C++20 are used proper C++20 range concepts.
-
template <typename M> std::pair<iterator, bool> insert_or_assign(const Key& key, M&& obj); -
template <typename M> std::pair<iterator, bool> insert_or_assign(Key&& key, M&& obj); -
template <typename K, typename M> std::pair<iterator, bool> insert_or_assign(K&& key, M&& obj);Preconditions:
!full()Effects: If a key equivalent to
keyalready exists in the container, assignsstd::forward<M>(obj)to the mapped type corresponding to the keykey. If the key does not exist, inserts the new element.-
Overload (1): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if
std::is_assignable_v<mapped_type&, M&&>istrue. -
Overload (2): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if
std::is_assignable_v<mapped_type&, M&&>istrue. -
Overload (3): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(std::forward<K>(key)), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if all following conditions are satisfied:
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.std::is_assignable_v<mapped_type&, M&&>istrue.
Returns: The iterator component points to the inserted element or to the updated element. The
boolcomponent istrueif insertion took place andfalseif assignment took place. -
-
template <typename M> iterator insert_or_assign(const_iterator hint, const Key& key, M&& obj); -
template <typename M> iterator insert_or_assign(const_iterator hint, Key&& key, M&& obj); -
template <typename K, typename M> iterator insert_or_assign(const_iterator hint, K&& key, M&& obj);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: If a key equivalent to
keyalready exists in the container, assignsstd::forward<M>(obj)to the mapped type corresponding to the keykey. If the key does not exist, inserts the new element.Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. These overloads exist just to have this container compatible with standard C++ containers as much as possible.-
Overload (4): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if
std::is_assignable_v<mapped_type&, M&&>istrue. -
Overload (5): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if
std::is_assignable_v<mapped_type&, M&&>istrue. -
Overload (6): New element is constructed as
value_type( std::piecewise_construct, std::forward_as_tuple(std::forward<K>(key)), std::forward_as_tuple(std::forward<M>(obj)) )Note: This overload participates in overload resolution only if all following conditions are satisfied:
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.std::is_assignable_v<mapped_type&, M&&>istrue.
Returns: Iterator to the element that was inserted or updated.
-
template <typename... Args> std::pair<iterator, bool> try_emplace(const Key& key, Args&&... args); -
template <typename... Args> std::pair<iterator, bool> try_emplace(Key&& key, Args&&... args); -
template <typename K, typename... Args> std::pair<iterator, bool> try_emplace(K&& key, Args&&... args);Preconditions:
!full()Effects: If a key equivalent to
keyalready exists in the container, does nothing. Otherwise, inserts a new element into the container.-
Overload (1): Behaves like
emplaceexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<Args>(args)...) ) -
Overload (2): Behaves like
emplaceexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::forward_as_tuple(std::forward<Args>(args)...) ) -
Overload (3): Behaves like
emplaceexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(std::forward<K>(key)), std::forward_as_tuple(std::forward<Args>(args)...) )Note: This overload participates in overload resolution only if all following conditions are satisfied:
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.std::is_convertible_v<K&&, iterator>isfalse.std::is_convertible_v<K&&, const_iterator>isfalse.
Returns: The iterator component points to the inserted element or to the already existing element. The
boolcomponent istrueif insertion happened andfalseif it did not. -
-
template <typename... Args> iterator try_emplace(const_iterator hint, const Key& key, Args&&... args); -
template <typename... Args> iterator try_emplace(const_iterator hint, Key&& key, Args&&... args); -
template <typename K, typename... Args> iterator try_emplace(const_iterator hint, K&& key, Args&&... args);Preconditions:
!full()cbegin() <= hint && hint <= cend()
Effects: If a key equivalent to
keyalready exists in the container, does nothing. Otherwise, inserts a new element into the container.Iterator
hintis used as a suggestion where to start to search insert position.Iterator
hintis ignored due to container's underlying storage implementation. These overloads exist just to have this container compatible with standard C++ containers as much as possible.-
Overload (4): Behaves like
emplace_hintexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(std::forward<Args>(args)...) ) -
Overload (5): Behaves like
emplace_hintexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::forward_as_tuple(std::forward<Args>(args)...) ) -
Overload (6): Behaves like
emplace_hintexcept that the element is constructed asvalue_type( std::piecewise_construct, std::forward_as_tuple(std::forward<K>(key)), std::forward_as_tuple(std::forward<Args>(args)...) )Note: This overload participates in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.
Returns: Iterator to the inserted element or to the already existing element.
-
iterator erase(iterator pos); -
iterator erase(const_iterator pos);Preconditions:
cbegin() <= pos && pos < cend()Effects: Removes the element at
pos.Returns: Iterator following the last removed element.
-
iterator erase(const_iterator first, const_iterator last);Preconditions:
cbegin() <= first && first <= last && last <= cend()Effects: Removes the elements in the range
[first, last).Returns: Iterator following the last removed element.
-
size_type erase(const Key& key); -
template <typename K> size_type erase(K&& x);Effects: Removes the element (if one exists) with the key equivalent to
keyorx.Note: Overload (5) participates in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.Returns: Number of elements removed (0 or 1).
-
void swap(small_unordered_linear_map& other);Effects: Exchanges the contents of the container with those of
other.Complexity: Linear in size.
-
iterator find(const Key& key); -
const_iterator find(const Key& key) const; -
template <typename K> iterator find(const K& x); -
template <typename K> const_iterator find(const K& x) const;Effects: Returns an iterator pointing to the element with key equivalent to
keyorx. Returnsend()if no such element is found.Note: Overloads (3) and (4) participate in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling these functions without constructing an instance ofKey.Complexity: Constant in the best case. Linear in
size()in the worst case.
-
size_type count(const Key& key) const; -
template <typename K> size_type count(const K& x) const;Effects: Returns the number of elements with key equivalent to
keyorx, which is either 1 or 0 since this container does not allow duplicates.Note: Overload (2) participates in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.Complexity: Constant in the best case. Linear in
size()in the worst case.
-
bool contains(const Key& key) const; -
template <typename K> bool contains(const K& x) const;Effects: Returns
trueif the container contains an element with key equivalent tokeyorx, otherwise returnsfalse.Note: Overload (2) participates in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.Complexity: Constant in the best case. Linear in
size()in the worst case.
-
T& at(const Key& key); -
const T& at(const Key& key) const; -
template <typename K> T& at(const K& x); -
template <typename K> const T& at(const K& x) const;Effects: Returns a reference to the mapped value of the element with key equivalent to
keyorx. If no such element exists, an exception of typestd::out_of_rangeis thrown.Note: Overloads (3) and (4) participate in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling these functions without constructing an instance ofKey.Complexity: Linear in
size().Exceptions:
std::out_of_rangeif the container does not have an element with the specified key.
-
T& operator[](const Key& key); -
T& operator[](Key&& key); -
template <typename K> T& operator[](K&& x);Preconditions:
!full()Effects: Returns a reference to the value that is mapped to a key equivalent to
keyorx, performing an insertion if such key does not already exist.-
Overload (1) is equivalent to
return try_emplace(key).first->second; -
Overload (2) is equivalent to
return try_emplace(std::move(key)).first->second; -
Overload (3) is equivalent to
return try_emplace(std::forward<K>(x)).first->second;
Note: Overload (3) participates in overload resolution only if
KeyEqual::is_transparentexists and is a valid type. It allows calling this function without constructing an instance ofKey.Complexity: Linear in
size(). -
-
value_type* data() noexcept; -
const value_type* data() const noexcept;Effects: Returns pointer to the underlying array serving as element storage. The pointer is such that range
[data(), data() + size())is always a valid range, even if the container is empty.data()is not dereferenceable if the container is empty.Complexity: Constant.
-
template <typename K, typename T, std::size_t N, typename E> bool operator== ( const static_unordered_linear_map<K, T, N, E>& x, const static_unordered_linear_map<K, T, N, E>& y );Effects: Checks if the contents of
xandyare equal.The contents of
xandyare equal if the following conditions hold:x.size() == y.size()- For each element in
xthere is equal element iny.
The comparison is performed by
std::is_permutation. This comparison ignores the container'sKeyEqualfunction.Returns:
trueif the contents of thexandyare equal,falseotherwise.
-
template <typename K, typename T, std::size_t N, typename E> bool operator!= ( const static_unordered_linear_map<K, T, N, E>& x, const static_unordered_linear_map<K, T, N, E>& y );Effects: Checks if the contents of
xandyare equal.For details see
operator==.Returns:
trueif the contents of thexandyare not equal,falseotherwise.
-
template <typename K, typename T, std::size_t N, typename E> void swap ( static_unordered_linear_map<K, T, N, E>& x, static_unordered_linear_map<K, T, N, E>& y );Effects: Swaps the contents of
xandy. Callsx.swap(y).
-
template <typename K, typename T, std::size_t N, typename E, typename Predicate> typename static_unordered_linear_map<K, T, N, E>::size_type erase_if(static_unordered_linear_map<K, T, N, E>& c, Predicate pred);Effects: Erases all elements that satisfy the predicate
predfrom the container.predis unary predicate which returnstrueif the element should be removed.Returns: The number of erased elements.
Complexity: Linear.
End of document.