aboutsummaryrefslogtreecommitdiff
path: root/libs/kstd/kstd/flat_map.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/kstd/kstd/flat_map.hpp')
-rw-r--r--libs/kstd/kstd/flat_map.hpp84
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.