mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-15 10:16:20 +07:00
Merge pull request #28 from BlackMATov/dev
This commit is contained in:
10
README.md
10
README.md
@@ -477,6 +477,11 @@ std::pair<iterator, bool> insert(const value_type& value);
|
|||||||
iterator insert(const_iterator hint, value_type&& value);
|
iterator insert(const_iterator hint, value_type&& value);
|
||||||
iterator insert(const_iterator hint, const value_type& value);
|
iterator insert(const_iterator hint, const value_type& value);
|
||||||
|
|
||||||
|
template < typename TT >
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type&& key, TT&& value);
|
||||||
|
template < typename TT >
|
||||||
|
std::pair<iterator, bool> insert_or_assign(const key_type& key, TT&& value);
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last);
|
void insert(InputIter first, InputIter last);
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
@@ -490,6 +495,11 @@ std::pair<iterator, bool> emplace(Args&&... args);
|
|||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
iterator emplace_hint(const_iterator hint, Args&&... args);
|
iterator emplace_hint(const_iterator hint, Args&&... args);
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
std::pair<iterator, bool> try_emplace(key_type&& key, Args&&... args);
|
||||||
|
template < typename... Args >
|
||||||
|
std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
iterator erase(const_iterator iter);
|
iterator erase(const_iterator iter);
|
||||||
iterator erase(const_iterator first, const_iterator last);
|
iterator erase(const_iterator first, const_iterator last);
|
||||||
|
|||||||
@@ -399,6 +399,28 @@ namespace flat_hpp
|
|||||||
: insert(value).first;
|
: insert(value).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename TT >
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type&& key, TT&& value) {
|
||||||
|
iterator iter = lower_bound(key);
|
||||||
|
if ( iter == end() || this->operator()(key, *iter) ) {
|
||||||
|
iter = emplace_hint(iter, std::move(key), std::forward<TT>(value));
|
||||||
|
return {iter, true};
|
||||||
|
}
|
||||||
|
(*iter).second = std::forward<TT>(value);
|
||||||
|
return {iter, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename TT >
|
||||||
|
std::pair<iterator, bool> insert_or_assign(const key_type& key, TT&& value) {
|
||||||
|
iterator iter = lower_bound(key);
|
||||||
|
if ( iter == end() || this->operator()(key, *iter) ) {
|
||||||
|
iter = emplace_hint(iter, key, std::forward<TT>(value));
|
||||||
|
return {iter, true};
|
||||||
|
}
|
||||||
|
(*iter).second = std::forward<TT>(value);
|
||||||
|
return {iter, false};
|
||||||
|
}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
insert_range_(first, last);
|
insert_range_(first, last);
|
||||||
@@ -427,6 +449,26 @@ namespace flat_hpp
|
|||||||
return insert(hint, value_type(std::forward<Args>(args)...));
|
return insert(hint, value_type(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
std::pair<iterator, bool> try_emplace(key_type&& key, Args&&... args) {
|
||||||
|
iterator iter = lower_bound(key);
|
||||||
|
if ( iter == end() || this->operator()(key, *iter) ) {
|
||||||
|
iter = emplace_hint(iter, std::move(key), std::forward<Args>(args)...);
|
||||||
|
return {iter, true};
|
||||||
|
}
|
||||||
|
return {iter, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) {
|
||||||
|
iterator iter = lower_bound(key);
|
||||||
|
if ( iter == end() || this->operator()(key, *iter) ) {
|
||||||
|
iter = emplace_hint(iter, key, std::forward<Args>(args)...);
|
||||||
|
return {iter, true};
|
||||||
|
}
|
||||||
|
return {iter, false};
|
||||||
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
noexcept(noexcept(std::declval<container_type&>().clear())) {
|
noexcept(noexcept(std::declval<container_type&>().clear())) {
|
||||||
data_.clear();
|
data_.clear();
|
||||||
@@ -508,6 +550,18 @@ namespace flat_hpp
|
|||||||
: end();
|
: end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(const key_type& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename K >
|
||||||
|
std::enable_if_t<
|
||||||
|
detail::is_transparent_v<Compare, K>,
|
||||||
|
bool>
|
||||||
|
contains(const K& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||||
const base_type& comp = *this;
|
const base_type& comp = *this;
|
||||||
return std::equal_range(begin(), end(), key, comp);
|
return std::equal_range(begin(), end(), key, comp);
|
||||||
|
|||||||
@@ -458,6 +458,18 @@ namespace flat_hpp
|
|||||||
: end();
|
: end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(const key_type& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename K >
|
||||||
|
std::enable_if_t<
|
||||||
|
detail::is_transparent_v<Compare, K>,
|
||||||
|
bool>
|
||||||
|
contains(const K& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||||
const base_type& comp = *this;
|
const base_type& comp = *this;
|
||||||
return std::equal_range(begin(), end(), key, comp);
|
return std::equal_range(begin(), end(), key, comp);
|
||||||
|
|||||||
@@ -386,6 +386,18 @@ namespace flat_hpp
|
|||||||
: end();
|
: end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(const key_type& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename K >
|
||||||
|
std::enable_if_t<
|
||||||
|
detail::is_transparent_v<Compare, K>,
|
||||||
|
bool>
|
||||||
|
contains(const K& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||||
return std::equal_range(begin(), end(), key, key_comp());
|
return std::equal_range(begin(), end(), key, key_comp());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -436,6 +436,18 @@ namespace flat_hpp
|
|||||||
: end();
|
: end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains(const key_type& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename K >
|
||||||
|
std::enable_if_t<
|
||||||
|
detail::is_transparent_v<Compare, K>,
|
||||||
|
bool>
|
||||||
|
contains(const K& key) const {
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||||
return std::equal_range(begin(), end(), key, key_comp());
|
return std::equal_range(begin(), end(), key, key_comp());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,6 +369,34 @@ TEST_CASE("flat_map") {
|
|||||||
s1.insert(sorted_range, {{1,3},{2,2},{2,2},{3,1}});
|
s1.insert(sorted_range, {{1,3},{2,2},{2,2},{3,1}});
|
||||||
REQUIRE(s1 == map_t{{1,3},{2,2},{3,1}});
|
REQUIRE(s1 == map_t{{1,3},{2,2},{3,1}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map_t s0;
|
||||||
|
auto i0 = s0.insert_or_assign(1, 4);
|
||||||
|
REQUIRE(i0 == std::make_pair(s0.begin(), true));
|
||||||
|
REQUIRE(s0 == map_t{{1,4}});
|
||||||
|
auto i1 = s0.insert_or_assign(1, 8);
|
||||||
|
REQUIRE(i1 == std::make_pair(s0.begin(), false));
|
||||||
|
REQUIRE(s0 == map_t{{1,8}});
|
||||||
|
|
||||||
|
const obj_t k0{2};
|
||||||
|
auto i2 = s0.insert_or_assign(k0, 6);
|
||||||
|
REQUIRE(i2 == std::make_pair(s0.begin() + 1, true));
|
||||||
|
REQUIRE(s0 == map_t{{1,8}, {2,6}});
|
||||||
|
auto i3 = s0.insert_or_assign(k0, 2);
|
||||||
|
REQUIRE(i3 == std::make_pair(s0.begin() + 1, false));
|
||||||
|
REQUIRE(s0 == map_t{{1,8}, {2,2}});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map_t s0;
|
||||||
|
auto i0 = s0.try_emplace(1, 4);
|
||||||
|
REQUIRE(i0 == std::make_pair(s0.begin(), true));
|
||||||
|
REQUIRE(s0 == map_t{{1,4}});
|
||||||
|
auto i1 = s0.try_emplace(1, 8);
|
||||||
|
REQUIRE(i1 == std::make_pair(s0.begin(), false));
|
||||||
|
REQUIRE(s0 == map_t{{1,4}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("erasers") {
|
SECTION("erasers") {
|
||||||
using map_t = flat_map<int, unsigned>;
|
using map_t = flat_map<int, unsigned>;
|
||||||
@@ -421,6 +449,9 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
||||||
REQUIRE(s0.find(6) == s0.end());
|
REQUIRE(s0.find(6) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
||||||
|
REQUIRE(my_as_const(s0).contains(1));
|
||||||
|
REQUIRE(my_as_const(s0).contains(3));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(0));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
map_t s0{{1,2},{2,3},{3,4},{4,5},{5,6}};
|
map_t s0{{1,2},{2,3},{3,4},{4,5},{5,6}};
|
||||||
@@ -445,6 +476,9 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||||
|
|
||||||
|
REQUIRE(my_as_const(s0).contains(std::string_view("hello")));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(std::string_view("42")));
|
||||||
|
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -423,6 +423,9 @@ TEST_CASE("flat_multimap") {
|
|||||||
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
||||||
REQUIRE(s0.find(6) == s0.end());
|
REQUIRE(s0.find(6) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
||||||
|
REQUIRE(my_as_const(s0).contains(1));
|
||||||
|
REQUIRE(my_as_const(s0).contains(3));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(0));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
map_t s0{{1,2},{2,3},{2,1},{3,4},{4,5},{5,6}};
|
map_t s0{{1,2},{2,3},{2,1},{3,4},{4,5},{5,6}};
|
||||||
@@ -447,6 +450,9 @@ TEST_CASE("flat_multimap") {
|
|||||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||||
|
|
||||||
|
REQUIRE(my_as_const(s0).contains(std::string_view("hello")));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(std::string_view("42")));
|
||||||
|
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -399,6 +399,9 @@ TEST_CASE("flat_multiset") {
|
|||||||
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
||||||
REQUIRE(s0.find(6) == s0.end());
|
REQUIRE(s0.find(6) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
||||||
|
REQUIRE(my_as_const(s0).contains(1));
|
||||||
|
REQUIRE(my_as_const(s0).contains(3));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(0));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
set_t s0{1,2,3,3,4,5};
|
set_t s0{1,2,3,3,4,5};
|
||||||
@@ -423,6 +426,9 @@ TEST_CASE("flat_multiset") {
|
|||||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||||
|
|
||||||
|
REQUIRE(my_as_const(s0).contains(std::string_view("hello")));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(std::string_view("42")));
|
||||||
|
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -397,6 +397,9 @@ TEST_CASE("flat_set") {
|
|||||||
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
REQUIRE(my_as_const(s0).find(3) == s0.cbegin() + 2);
|
||||||
REQUIRE(s0.find(6) == s0.end());
|
REQUIRE(s0.find(6) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
REQUIRE(my_as_const(s0).find(0) == s0.cend());
|
||||||
|
REQUIRE(my_as_const(s0).contains(1));
|
||||||
|
REQUIRE(my_as_const(s0).contains(3));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(0));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
set_t s0{1,2,3,4,5};
|
set_t s0{1,2,3,4,5};
|
||||||
@@ -421,6 +424,9 @@ TEST_CASE("flat_set") {
|
|||||||
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
REQUIRE(s0.find(std::string_view("42")) == s0.end());
|
||||||
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
REQUIRE(my_as_const(s0).find(std::string_view("42")) == s0.cend());
|
||||||
|
|
||||||
|
REQUIRE(my_as_const(s0).contains(std::string_view("hello")));
|
||||||
|
REQUIRE_FALSE(my_as_const(s0).contains(std::string_view("42")));
|
||||||
|
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello")) == 1);
|
||||||
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
REQUIRE(my_as_const(s0).count(std::string_view("hello_42")) == 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user