diff options
Diffstat (limited to 'libs/kstd/kstd/flat_map.hpp')
| -rw-r--r-- | libs/kstd/kstd/flat_map.hpp | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/libs/kstd/kstd/flat_map.hpp b/libs/kstd/kstd/flat_map.hpp index af269c6a..b9b05366 100644 --- a/libs/kstd/kstd/flat_map.hpp +++ b/libs/kstd/kstd/flat_map.hpp @@ -81,10 +81,13 @@ namespace kstd template<bool IsConst> struct flat_map_iterator { - using iterator_category = std::random_access_iterator_tag; + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; using value_type = std::pair<KeyType, MappedType>; using difference_type = std::ptrdiff_t; using reference = std::pair<KeyType const &, std::conditional_t<IsConst, MappedType const, MappedType> &>; + using rvalue_reference = std::pair<std::conditional_t<IsConst, KeyType const &&, KeyType &&>, + std::conditional_t<IsConst, MappedType const &&, MappedType &&>>; struct pointer { @@ -104,7 +107,7 @@ namespace kstd , m_index{it.m_index} {} - [[nodiscard]] constexpr auto operator*() const noexcept -> reference + [[nodiscard]] constexpr auto operator*() const -> reference { if (m_index >= m_containers->keys.size()) { @@ -113,12 +116,12 @@ namespace kstd return {m_containers->keys[m_index], m_containers->values[m_index]}; } - [[nodiscard]] constexpr auto operator->() const noexcept -> pointer + [[nodiscard]] constexpr auto operator->() const -> pointer { return {operator*()}; } - [[nodiscard]] constexpr auto operator[](difference_type offset) const noexcept -> reference + [[nodiscard]] constexpr auto operator[](difference_type offset) const -> reference { return *(*this + offset); } @@ -191,6 +194,24 @@ namespace kstd [[nodiscard]] constexpr auto friend operator<=>(flat_map_iterator const &, flat_map_iterator const &) noexcept = default; + [[nodiscard]] constexpr auto friend iter_move(flat_map_iterator const & it) -> rvalue_reference + { + if (it.m_index >= it.m_containers->keys.size()) + { + os::panic("[kstd::flat_map] Iterator out of range"); + } + + return rvalue_reference{static_cast<rvalue_reference::first_type>(it.m_containers->keys[it.m_index]), + static_cast<rvalue_reference::second_type>(it.m_containers->values[it.m_index])}; + } + + constexpr auto friend iter_swap(flat_map_iterator const & lhs, flat_map_iterator const & rhs) -> void + requires(!IsConst) + { + std::ranges::swap(lhs.m_containers->keys[lhs.m_index], rhs.m_containers->keys[rhs.m_index]); + std::ranges::swap(lhs.m_containers->values[lhs.m_index], rhs.m_containers->values[rhs.m_index]); + } + private: friend struct flat_map; friend flat_map_iterator<!IsConst>; @@ -557,7 +578,8 @@ namespace kstd //! Try to insert a new key-value pair into the map. //! //! @param args Arguments to use for constructing the key-value pair. - //! @return A pair of an iterator to the inserted element and a boolean indicating whether the insertion took place. + //! @return A pair of an iterator to the inserted element and a boolean indicating whether the insertion took + //! place. template<typename... Args> auto emplace(Args &&... args) -> std::pair<iterator, bool> requires std::constructible_from<value_type, Args...> @@ -745,6 +767,58 @@ namespace kstd return find(key) != cend(); } + //! Get an iterator to the first element not less than the given key. + //! + //! @param key The key to look for. + //! @return An iterator to the first element not less than the given key iff. such an element exists, the end + //! iterator otherwise. + [[nodiscard]] constexpr auto lower_bound(key_type const & key) noexcept -> iterator + { + auto found = std::ranges::lower_bound(m_containers.keys, key, m_comparator); + auto offset = static_cast<std::size_t>(std::ranges::distance(m_containers.keys.begin(), found)); + return iterator{m_containers, offset}; + } + + //! Get an iterator to the first element not less than the given key. + //! + //! @param key The key to look for. + //! @return An iterator to the first element not less than the given key iff. such an element exists, the end + //! iterator otherwise. + [[nodiscard]] constexpr auto lower_bound(key_type const & key) const noexcept -> const_iterator + { + auto found = std::ranges::lower_bound(m_containers.keys, key, m_comparator); + auto offset = static_cast<std::size_t>(std::ranges::distance(m_containers.keys.begin(), found)); + return const_iterator{m_containers, offset}; + } + + //! Get an iterator to the first element not less than the given key. + //! + //! @param key The key to look for. + //! @return An iterator to the first element not less than the given key iff. such an element exists, the end + //! iterator otherwise. + template<typename K> + requires requires { typename key_compare::is_transparent; } + [[nodiscard]] constexpr auto lower_bound(K const & key) noexcept -> iterator + { + auto found = std::ranges::lower_bound(m_containers.keys, key, m_comparator); + auto offset = static_cast<std::size_t>(std::ranges::distance(m_containers.keys.begin(), found)); + return iterator{m_containers, offset}; + } + + //! Get an iterator to the first element not less than the given key. + //! + //! @param key The key to look for. + //! @return An iterator to the first element not less than the given key iff. such an element exists, the end + //! iterator otherwise. + template<typename K> + requires requires { typename key_compare::is_transparent; } + [[nodiscard]] constexpr auto lower_bound(K const & key) const noexcept -> const_iterator + { + auto found = std::ranges::lower_bound(m_containers.keys, key, m_comparator); + auto offset = static_cast<std::size_t>(std::ranges::distance(m_containers.keys.begin(), found)); + return const_iterator{m_containers, offset}; + } + //! Get the key comparator of this flat map. //! //! @return The key comparator of this flat map. |
