23#if __has_include(<cereal/types/vector.hpp>)
24# include <cereal/types/vector.hpp>
26#if __has_include(<cereal/types/unordered_map.hpp>)
27# include <cereal/types/unordered_map.hpp>
98template <
typename key_t,
typename mapped_t,
bool mapped_t_is_context_aware = false>
102 static_assert(std::is_object_v<key_t>,
"The key type may not be a reference or have const.");
103 static_assert(std::convertible_to<key_t, std::string_view>,
104 "The key type must be std::convertible_to<std::string_view>.");
105 static_assert(std::is_object_v<mapped_t>,
"The mapped type may not be a reference or have const.");
120 detail::random_access_iterator<dictionary>>;
125 using allocator_type = void;
150 template <typename... value_type_>
151 requires((
std::convertible_to<value_type_,
value_type> && ...) && sizeof...(value_type_) > 0)
154 assign(std::forward<value_type_>(args)...);
172 template <meta::different_from<iterator> begin_it_type,
typename end_it_type>
174 std::sentinel_for<end_it_type, begin_it_type> &&
175 std::convertible_to<std::iter_reference_t<begin_it_type>,
value_type>)
186 requires(!std::same_as<iterator, const_iterator>)
205 template <meta::different_from<dictionary> other_range_t>
206 requires(std::ranges::input_range<other_range_t>)
223 template <
typename... value_type_>
227 (std::convertible_to<value_type_, value_type> && ...) && (
sizeof...(value_type_) > 0))
231 storage.reserve(
sizeof...(args));
232 (storage.push_back(std::forward<value_type_>(args)), ...);
249 template <std::ranges::input_range other_range_t>
250 requires std::convertible_to<std::ranges::range_reference_t<other_range_t>,
value_type>
272 template <meta::different_from<iterator> begin_it_type,
typename end_it_type>
274 std::sentinel_for<end_it_type, begin_it_type> &&
275 std::convertible_to<std::iter_reference_t<begin_it_type>,
value_type>)
276 void assign(begin_it_type begin_it, end_it_type end_it)
278 assign_impl(begin_it, end_it);
286 requires(!std::same_as<iterator, const_iterator>)
288 assign_impl(begin_it, end_it);
336 throw std::out_of_range{
"Trying to access element behind the last in dictionary."};
346 throw std::out_of_range{
"Trying to access element behind the last in dictionary."};
371 return reference{get<0>(storage[i]), get<1>(storage[i])};
427 return (*
this)[
size() - 1];
434 return (*
this)[
size() - 1];
442#ifdef __cpp_lib_generic_unordered_lookup
492 if (
auto it = key_to_index.
find(key); it == key_to_index.
end())
495 return begin() + get<1>(*it);
501 if (
auto it = key_to_index.
find(key); it == key_to_index.
end())
504 return begin() + get<1>(*it);
524 auto it = key_to_index.
find(key);
525 if (it == key_to_index.
end())
527 return get<1>(storage[it->second]);
533 auto it = key_to_index.
find(key);
534 if (it == key_to_index.
end())
536 return get<1>(storage[it->second]);
585 template <small_
string key>
587 requires(mapped_t_is_context_aware &&
requires { get<key>(get<1>(dict.storage[0])); })
589#ifdef __cpp_lib_generic_unordered_lookup
590 auto it = dict.key_to_index.find(key);
592 auto it = dict.key_to_index.find(
static_cast<key_t
>(key));
594 if (it == dict.key_to_index.end())
598 return std::move(get<key>(get<1>(dict.storage[it->second])));
600 return get<key>(get<1>(dict.storage[it->second]));
623 template <small_
string key>
625 requires(
requires(
dictionary d) { get<key>(d); })
627 return get<key>(*
this);
631 template <small_
string key>
633 requires(
requires(
dictionary const d) { get<key>(d); })
635 return get<key>(*
this);
639 template <small_
string key>
641 requires(
requires(
dictionary d) { get<key>(d); })
643 return get<key>(*
this);
647 template <small_
string key>
649 requires(
requires(
dictionary const d) { get<key>(d); })
651 return get<key>(*
this);
735 storage.reserve(new_cap);
770 key_to_index.
clear();
785 template <std::convertible_to<value_type> value_type_ = value_type>
788 if (key_to_index.
contains(get<0>(value)))
790 storage.push_back(std::forward<value_type_>(value));
791 key_to_index[get<0>(storage.back())] = storage.size() - 1;
807 requires(std::constructible_from<
value_type,
decltype(args)...>)
809 storage.emplace_back(
std::forward<
decltype(args)>(args)...);
810 if (key_to_index.
contains(get<0>(storage.back())))
812 key_to_index[get<0>(storage.back())] = storage.size() - 1;
832 key_to_index.
erase(get<0>(storage.back()));
865 return lhs.storage == rhs.storage;
871 return lhs.storage <=> rhs.storage;
882 using is_transparent = void;
892 using is_transparent = void;
907 void recompute_hashes()
909 key_to_index.
clear();
912 for (
auto && [key, value] : storage)
913 key_to_index[key] = i++;
914 if (key_to_index.
size() != storage.size())
915 throw std::runtime_error{
"When creating/assigning bio::ranges::dictionary, keys where not unique."};
919 void assign_impl(
auto begin_it,
auto end_it)
921 if constexpr (
requires { storage.assign(begin_it, end_it); })
923 storage.assign(begin_it, end_it);
929 if constexpr (std::sized_sentinel_for<
decltype(end_it),
decltype(begin_it)>)
930 storage.reserve(end_it - begin_it);
932 for (; begin_it != end_it; ++begin_it)
933 storage.push_back(*begin_it);
945 template <
typename archive_t>
946 void serialize(archive_t & archive)
949 archive(key_to_index);
An associative container with contiguous, predictable storage.
Definition: dictionary.hpp:100
void clear() noexcept
Removes all elements from the container.
Definition: dictionary.hpp:767
dictionary(other_range_t &&range)
Construct from a different range.
Definition: dictionary.hpp:207
void shrink_to_fit()
Reduce capacity to current size() to free unused memory.
Definition: dictionary.hpp:751
iterator end() noexcept
Returns iterator past the end.
Definition: dictionary.hpp:305
iterator begin() noexcept
Returns the begin iterator.
Definition: dictionary.hpp:296
const_iterator end() const noexcept
Returns iterator past the end.
Definition: dictionary.hpp:308
reference at(size_type const i)
Return the i-th element.
Definition: dictionary.hpp:332
const_iterator begin() const noexcept
Returns the begin iterator.
Definition: dictionary.hpp:299
const_reference front() const noexcept
Return the first element. Calling front on an empty container is undefined.
Definition: dictionary.hpp:403
size_type max_size() const noexcept
Returns the maximum number of elements the container is able to hold.
Definition: dictionary.hpp:698
detail::random_access_iterator< dictionary const > const_iterator
The const_iterator type.
Definition: dictionary.hpp:117
mapped_ref_t at(het_key_t key)
Access element by key.
Definition: dictionary.hpp:522
void assign(begin_it_type begin_it, end_it_type end_it)
Assign from pair of iterators.
Definition: dictionary.hpp:276
key_t const & het_key_t
Type used for key-based access.
Definition: dictionary.hpp:445
decltype(auto) at(meta::vtag_t< key > key_tag) const
Access element by compile-time string and implicitly call get() on it.
Definition: dictionary.hpp:632
friend decltype(auto) get(meta::decays_to< dictionary > auto &&dict)
Access element by compile-time string and implicitly call get() on it.
Definition: dictionary.hpp:586
const_reference operator[](size_type const i) const noexcept
Return the i-th element.
Definition: dictionary.hpp:375
size_t count(het_key_t key) const
The number of elements in the container with the specified key.
Definition: dictionary.hpp:476
void assign(iterator begin_it, iterator end_it)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: dictionary.hpp:282
const_reference back() const noexcept
Return the last element.
Definition: dictionary.hpp:431
bool empty() const noexcept
Checks whether the container is empty.
Definition: dictionary.hpp:669
dictionary(iterator const begin_it, iterator const end_it)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: dictionary.hpp:182
reference front() noexcept
Return the first element. Calling front on an empty container is undefined.
Definition: dictionary.hpp:396
dictionary(dictionary &&) noexcept=default
Defaulted.
const_reference at(size_type const i) const
Return the i-th element.
Definition: dictionary.hpp:342
mapped_ref_t operator[](het_key_t key)
Access element by key.
Definition: dictionary.hpp:556
std::tuple< key_t, mapped_t > value_type
The value_type type.
Definition: dictionary.hpp:112
size_type size() const noexcept
Returns the number of elements in the container.
Definition: dictionary.hpp:682
value_type extract_back()
Removes and returns the last element of the container.
Definition: dictionary.hpp:850
void reserve(size_type const new_cap)
Reserve storage in the underlying data types to accomodate for future inserts.
Definition: dictionary.hpp:733
mapped_t const & operator[](het_key_t key) const
Access element by key.
Definition: dictionary.hpp:559
dictionary()=default
Defaulted.
decltype(auto) at(meta::vtag_t< key > key_tag)
Access element by compile-time string and implicitly call get() on it.
Definition: dictionary.hpp:624
reference operator[](size_type const i) noexcept
Return the i-th element.
Definition: dictionary.hpp:368
void assign(other_range_t &&range)
Assign from a different range.
Definition: dictionary.hpp:251
dictionary(dictionary const &)=default
Defaulted.
ptrdiff_t difference_type
The difference_type type.
Definition: dictionary.hpp:115
dictionary(begin_it_type const begin_it, end_it_type const end_it)
Construct from two iterators.
Definition: dictionary.hpp:176
mapped_t const & at(het_key_t key) const
Access element by key.
Definition: dictionary.hpp:531
dictionary(const_iterator const begin_it, const_iterator const end_it)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: dictionary.hpp:185
friend bool operator<=>(dictionary const &lhs, dictionary const &rhs) noexcept
Performs element-wise comparison.
Definition: dictionary.hpp:869
friend bool operator==(dictionary const &lhs, dictionary const &rhs) noexcept
Performs element-wise comparison.
Definition: dictionary.hpp:863
iterator find(het_key_t key)
Find an element with the given key.
Definition: dictionary.hpp:490
const_iterator cend() const noexcept
Returns iterator past the end.
Definition: dictionary.hpp:311
size_t size_type
The size_type type.
Definition: dictionary.hpp:116
const_iterator cbegin() const noexcept
Returns the begin iterator.
Definition: dictionary.hpp:302
size_type capacity() const noexcept
Returns the number of elements that the container is able to hold without reallocating (see below).
Definition: dictionary.hpp:716
void push_back(value_type_ &&value)
Appends the given element value to the end of the container.
Definition: dictionary.hpp:786
void emplace_back(auto &&... args)
Constructs an element in-place at the end of the container.
Definition: dictionary.hpp:806
void pop_back()
Removes the last element of the container.
Definition: dictionary.hpp:829
void assign(const_iterator begin_it, const_iterator end_it)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: dictionary.hpp:285
reference back() noexcept
Return the last element.
Definition: dictionary.hpp:424
void assign(value_type_ &&... args)
Assign from multiple elements.
Definition: dictionary.hpp:228
bool contains(het_key_t key) const
Check whether the container has an element with the given key.
Definition: dictionary.hpp:460
const_iterator find(het_key_t key) const
Find an element with the given key.
Definition: dictionary.hpp:499
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
Provides metaprogramming utilities for integer types.
The ranges module's namespace.
Provides the bio::ranges::detail::random_access_iterator class.
Provides bio::meta::vtag.