From d4e85987778674236a94a268873b0c729a22c473 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 4 May 2019 13:49:34 +0700 Subject: [PATCH] map access interface --- flat_map.hpp | 75 +++++++++++++++++++++++++++++++++++----------- flat_map_tests.cpp | 18 ++++++++--- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/flat_map.hpp b/flat_map.hpp index 6b47b63..c223ad5 100644 --- a/flat_map.hpp +++ b/flat_map.hpp @@ -135,18 +135,43 @@ namespace flat_hpp return data_.max_size(); } - template < typename P - , typename = std::enable_if_t::value> > - std::pair insert(P&& p) { - //TODO(BlackMat): implme - return std::make_pair(end(), false); + mapped_type& operator[](key_type&& key) { + return insert(value_type(std::move(key), mapped_type())).first->second; } - template < typename P - , typename = std::enable_if_t::value> > - std::pair insert(const_iterator hint, P&& p) { + mapped_type& operator[](const key_type& key) { + return insert(value_type(key, mapped_type())).first->second; + } + + mapped_type& at(const key_type& key) { + const auto iter = find(key); + if ( iter != end() ) { + return iter->second; + } + throw std::out_of_range("flat_map::at: key not found"); + } + + const mapped_type& at(const key_type& key) const { + const auto iter = find(key); + if ( iter != end() ) { + return iter->second; + } + throw std::out_of_range("flat_map::at: key not found"); + } + + std::pair insert(const value_type& value) { + bool found = true; + iterator iter = lower_bound(value.first); + if ( iter == end() || compare_(value.first, iter->first) ) { + iter = data_.insert(iter, value); + found = false; + } + return std::make_pair(iter, !found); + } + + std::pair insert(const_iterator hint, const value_type& value) { //TODO(BlackMat): implme - return std::make_pair(end(), false); + return insert(value); } template < typename InputIter > @@ -165,7 +190,7 @@ namespace flat_hpp template < typename... Args > std::pair emplace_hint(const_iterator hint, Args&&... args) { //TODO(BlackMat): implme - return insert(value_type(std::forward(args)...)); + return insert(hint, value_type(std::forward(args)...)); } void clear() noexcept { @@ -197,13 +222,19 @@ namespace flat_hpp } iterator find(const key_type& key) { - //TODO(BlackMat): implme - return end(); + iterator iter = lower_bound(key); + if ( iter != end() && compare_(key, iter->first) ) { + iter = end(); + } + return iter; } const_iterator find(const key_type& key) const { - //TODO(BlackMat): implme - return end(); + const_iterator iter = lower_bound(key); + if ( iter != end() && compare_(key, iter->first) ) { + iter = end(); + } + return iter; } std::pair equal_range(const key_type& key) { @@ -218,22 +249,30 @@ namespace flat_hpp iterator lower_bound(const key_type& key) { //TODO(BlackMat): implme - return end(); + return std::lower_bound(begin(), end(), key, [this](const value_type& l, const key_type& r){ + return compare_(l.first, r); + }); } const_iterator lower_bound(const key_type& key) const { //TODO(BlackMat): implme - return end(); + return std::lower_bound(begin(), end(), key, [this](const value_type& l, const key_type& r){ + return compare_(l.first, r); + }); } iterator upper_bound(const key_type& key) { //TODO(BlackMat): implme - return end(); + return std::upper_bound(begin(), end(), key, [this](const key_type& l, const value_type& r){ + return compare_(l, r.first); + }); } const_iterator upper_bound(const key_type& key) const { //TODO(BlackMat): implme - return end(); + return std::upper_bound(begin(), end(), key, [this](const key_type& l, const value_type& r){ + return compare_(l, r.first); + }); } key_compare key_comp() const { diff --git a/flat_map_tests.cpp b/flat_map_tests.cpp index 287578c..aab7a16 100644 --- a/flat_map_tests.cpp +++ b/flat_map_tests.cpp @@ -18,13 +18,12 @@ namespace using value_type = T; T* allocate(std::size_t n) { - (void)n; - return nullptr; + return static_cast(std::malloc(sizeof(T) * n)); } void deallocate(T* p, std::size_t n) { - (void)p; (void)n; + std::free(p); } }; @@ -87,7 +86,7 @@ TEST_CASE("flat_map") { } { - std::vector> v; + std::vector> v; auto s0 = map_t(v.cbegin(), v.cend()); auto s1 = map_t(v.cbegin(), v.cend(), alloc_t()); auto s2 = map_t(v.cbegin(), v.cend(), std::less()); @@ -108,10 +107,21 @@ TEST_CASE("flat_map") { s0.size(); s0.max_size(); } + SECTION("access") { + using map_t = flat_map; + map_t s0; + s0[1] = 42; + s0.at(1); + my_as_const(s0).at(1); + } SECTION("inserts") { struct obj_t { obj_t(int i) : i(i) {} int i; + + bool operator<(const obj_t& o) const { + return i < o.i; + } }; using map_t = flat_map;