mirror of
https://github.com/BlackMATov/flat.hpp.git
synced 2025-12-16 14:09:01 +07:00
add custom operator=, extend insert functions
This commit is contained in:
57
flat_map.hpp
57
flat_map.hpp
@@ -133,6 +133,33 @@ namespace flat_hpp
|
|||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flat_map(flat_map&& other)
|
||||||
|
: data_(std::move(other.data_))
|
||||||
|
, compare_(std::move(other.compare_)) {}
|
||||||
|
|
||||||
|
flat_map(const flat_map& other)
|
||||||
|
: data_(other.data_)
|
||||||
|
, compare_(other.compare_) {}
|
||||||
|
|
||||||
|
flat_map& operator=(flat_map&& other) {
|
||||||
|
if ( this != &other ) {
|
||||||
|
flat_map(std::move(other)).swap(*this);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
flat_map& operator=(const flat_map& other) {
|
||||||
|
if ( this != &other ) {
|
||||||
|
flat_map(other).swap(*this);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
flat_map& operator=(std::initializer_list<value_type> ilist) {
|
||||||
|
flat_map(ilist).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
allocator_type get_allocator() const {
|
allocator_type get_allocator() const {
|
||||||
return data_.get_allocator();
|
return data_.get_allocator();
|
||||||
}
|
}
|
||||||
@@ -166,15 +193,21 @@ namespace flat_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
mapped_type& operator[](key_type&& key) {
|
mapped_type& operator[](key_type&& key) {
|
||||||
return insert(value_type(std::move(key), mapped_type())).first->second;
|
const iterator iter = find(key);
|
||||||
|
return iter != end()
|
||||||
|
? iter->second
|
||||||
|
: emplace(std::move(key), mapped_type()).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped_type& operator[](const key_type& key) {
|
mapped_type& operator[](const key_type& key) {
|
||||||
return insert(value_type(key, mapped_type())).first->second;
|
const iterator iter = find(key);
|
||||||
|
return iter != end()
|
||||||
|
? iter->second
|
||||||
|
: emplace(key, mapped_type()).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapped_type& at(const key_type& key) {
|
mapped_type& at(const key_type& key) {
|
||||||
const auto iter = find(key);
|
const iterator iter = find(key);
|
||||||
if ( iter != end() ) {
|
if ( iter != end() ) {
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
@@ -182,13 +215,20 @@ namespace flat_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapped_type& at(const key_type& key) const {
|
const mapped_type& at(const key_type& key) const {
|
||||||
const auto iter = find(key);
|
const const_iterator iter = find(key);
|
||||||
if ( iter != end() ) {
|
if ( iter != end() ) {
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
throw std::out_of_range("flat_map::at: key not found");
|
throw std::out_of_range("flat_map::at: key not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<iterator, bool> insert(value_type&& value) {
|
||||||
|
const iterator iter = lower_bound(value.first);
|
||||||
|
return iter == end() || compare_(value.first, iter->first)
|
||||||
|
? std::make_pair(data_.insert(iter, std::move(value)), true)
|
||||||
|
: std::make_pair(iter, false);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<iterator, bool> insert(const value_type& value) {
|
std::pair<iterator, bool> insert(const value_type& value) {
|
||||||
const iterator iter = lower_bound(value.first);
|
const iterator iter = lower_bound(value.first);
|
||||||
return iter == end() || compare_(value.first, iter->first)
|
return iter == end() || compare_(value.first, iter->first)
|
||||||
@@ -196,13 +236,20 @@ namespace flat_hpp
|
|||||||
: std::make_pair(iter, false);
|
: std::make_pair(iter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, const value_type& value) {
|
iterator insert(const_iterator hint, value_type&& value) {
|
||||||
return (hint == begin() || compare_((hint - 1)->first, value.first))
|
return (hint == begin() || compare_((hint - 1)->first, value.first))
|
||||||
&& (hint == end() || compare_(value.first, hint->first))
|
&& (hint == end() || compare_(value.first, hint->first))
|
||||||
? data_.insert(hint, std::move(value))
|
? data_.insert(hint, std::move(value))
|
||||||
: insert(std::move(value)).first;
|
: insert(std::move(value)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator hint, const value_type& value) {
|
||||||
|
return (hint == begin() || compare_((hint - 1)->first, value.first))
|
||||||
|
&& (hint == end() || compare_(value.first, hint->first))
|
||||||
|
? data_.insert(hint, value)
|
||||||
|
: insert(value).first;
|
||||||
|
}
|
||||||
|
|
||||||
template < typename InputIter >
|
template < typename InputIter >
|
||||||
void insert(InputIter first, InputIter last) {
|
void insert(InputIter first, InputIter last) {
|
||||||
while ( first != last ) {
|
while ( first != last ) {
|
||||||
|
|||||||
@@ -145,6 +145,32 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(s0.get_allocator().i == 0);
|
REQUIRE(s0.get_allocator().i == 0);
|
||||||
REQUIRE(s1.get_allocator().i == 42);
|
REQUIRE(s1.get_allocator().i == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s0 = map_t{{0,1}, {1,2}};
|
||||||
|
auto s1 = s0;
|
||||||
|
REQUIRE(s0 == map_t{{0,1}, {1,2}});
|
||||||
|
REQUIRE(s1 == map_t{{0,1}, {1,2}});
|
||||||
|
auto s2 = std::move(s1);
|
||||||
|
REQUIRE(s1.empty());
|
||||||
|
REQUIRE(s2 == map_t{{0,1}, {1,2}});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s0 = map_t{{0,1}, {1,2}};
|
||||||
|
map_t s1;
|
||||||
|
s1 = s0;
|
||||||
|
REQUIRE(s0 == map_t{{0,1}, {1,2}});
|
||||||
|
REQUIRE(s1 == map_t{{0,1}, {1,2}});
|
||||||
|
map_t s2;
|
||||||
|
s2 = std::move(s1);
|
||||||
|
REQUIRE(s0 == map_t{{0,1}, {1,2}});
|
||||||
|
REQUIRE(s1.empty());
|
||||||
|
REQUIRE(s2 == map_t{{0,1}, {1,2}});
|
||||||
|
map_t s3;
|
||||||
|
s3 = {{0,1}, {1,2}};
|
||||||
|
REQUIRE(s3 == map_t{{0,1}, {1,2}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("capacity") {
|
SECTION("capacity") {
|
||||||
using map_t = flat_map<int, unsigned>;
|
using map_t = flat_map<int, unsigned>;
|
||||||
@@ -173,15 +199,34 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
REQUIRE(s0.max_size() == std::allocator<std::pair<int,unsigned>>().max_size());
|
||||||
}
|
}
|
||||||
SECTION("access") {
|
SECTION("access") {
|
||||||
using map_t = flat_map<int, unsigned>;
|
struct obj_t {
|
||||||
|
obj_t(int i) : i(i) {}
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bool operator<(const obj_t& o) const {
|
||||||
|
return i < o.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const obj_t& o) const {
|
||||||
|
return i == o.i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using map_t = flat_map<obj_t, unsigned>;
|
||||||
map_t s0;
|
map_t s0;
|
||||||
s0[1] = 42;
|
|
||||||
|
obj_t k1(1);
|
||||||
|
|
||||||
|
s0[k1] = 42;
|
||||||
|
REQUIRE(s0[k1] == 42);
|
||||||
REQUIRE(s0 == map_t{{1,42}});
|
REQUIRE(s0 == map_t{{1,42}});
|
||||||
|
|
||||||
s0[1] = 84;
|
s0[1] = 84;
|
||||||
|
REQUIRE(s0[1] == 84);
|
||||||
REQUIRE(s0 == map_t{{1,84}});
|
REQUIRE(s0 == map_t{{1,84}});
|
||||||
|
|
||||||
REQUIRE(s0.at(1) == 84);
|
REQUIRE(s0.at(1) == 84);
|
||||||
REQUIRE(my_as_const(s0).at(1) == 84);
|
REQUIRE(my_as_const(s0).at(k1) == 84);
|
||||||
REQUIRE_THROWS_AS(s0.at(0), std::out_of_range);
|
REQUIRE_THROWS_AS(s0.at(0), std::out_of_range);
|
||||||
REQUIRE_THROWS_AS(my_as_const(s0).at(0), std::out_of_range);
|
REQUIRE_THROWS_AS(my_as_const(s0).at(0), std::out_of_range);
|
||||||
}
|
}
|
||||||
@@ -199,12 +244,15 @@ TEST_CASE("flat_map") {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using map_t = flat_map<int, obj_t>;
|
using map_t = flat_map<obj_t, obj_t>;
|
||||||
|
|
||||||
{
|
{
|
||||||
map_t s0;
|
map_t s0;
|
||||||
|
|
||||||
auto i0 = s0.insert(std::make_pair(1, 42));
|
auto k1_42 = std::make_pair(1, 42);
|
||||||
|
auto k3_84 = std::make_pair(3, 84);
|
||||||
|
|
||||||
|
auto i0 = s0.insert(k1_42);
|
||||||
REQUIRE(s0 == map_t{{1,42}});
|
REQUIRE(s0 == map_t{{1,42}});
|
||||||
REQUIRE(i0 == std::make_pair(s0.begin(), true));
|
REQUIRE(i0 == std::make_pair(s0.begin(), true));
|
||||||
|
|
||||||
@@ -216,7 +264,7 @@ TEST_CASE("flat_map") {
|
|||||||
REQUIRE(s0 == map_t{{1,42},{2,42}});
|
REQUIRE(s0 == map_t{{1,42},{2,42}});
|
||||||
REQUIRE(i2 == std::make_pair(s0.begin() + 1, true));
|
REQUIRE(i2 == std::make_pair(s0.begin() + 1, true));
|
||||||
|
|
||||||
auto i3 = s0.insert(s0.cend(), std::make_pair(3, 84));
|
auto i3 = s0.insert(s0.cend(), k3_84);
|
||||||
REQUIRE(i3 == s0.begin() + 2);
|
REQUIRE(i3 == s0.begin() + 2);
|
||||||
|
|
||||||
s0.insert(s0.cend(), std::make_pair(4, obj_t(84)));
|
s0.insert(s0.cend(), std::make_pair(4, obj_t(84)));
|
||||||
|
|||||||
27
flat_set.hpp
27
flat_set.hpp
@@ -111,6 +111,33 @@ namespace flat_hpp
|
|||||||
insert(ilist);
|
insert(ilist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flat_set(flat_set&& other)
|
||||||
|
: data_(std::move(other.data_))
|
||||||
|
, compare_(std::move(other.compare_)) {}
|
||||||
|
|
||||||
|
flat_set(const flat_set& other)
|
||||||
|
: data_(other.data_)
|
||||||
|
, compare_(other.compare_) {}
|
||||||
|
|
||||||
|
flat_set& operator=(flat_set&& other) {
|
||||||
|
if ( this != &other ) {
|
||||||
|
flat_set(std::move(other)).swap(*this);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
flat_set& operator=(const flat_set& other) {
|
||||||
|
if ( this != &other ) {
|
||||||
|
flat_set(other).swap(*this);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
flat_set& operator=(std::initializer_list<value_type> ilist) {
|
||||||
|
flat_set(ilist).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
allocator_type get_allocator() const {
|
allocator_type get_allocator() const {
|
||||||
return data_.get_allocator();
|
return data_.get_allocator();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,32 @@ TEST_CASE("flat_set") {
|
|||||||
REQUIRE(s0.get_allocator().i == 0);
|
REQUIRE(s0.get_allocator().i == 0);
|
||||||
REQUIRE(s1.get_allocator().i == 42);
|
REQUIRE(s1.get_allocator().i == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s0 = set_t{0,1,2};
|
||||||
|
auto s1 = s0;
|
||||||
|
REQUIRE(s0 == set_t{0,1,2});
|
||||||
|
REQUIRE(s1 == set_t{0,1,2});
|
||||||
|
auto s2 = std::move(s1);
|
||||||
|
REQUIRE(s1.empty());
|
||||||
|
REQUIRE(s2 == set_t{0,1,2});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s0 = set_t{0,1,2};
|
||||||
|
set_t s1;
|
||||||
|
s1 = s0;
|
||||||
|
REQUIRE(s0 == set_t{0,1,2});
|
||||||
|
REQUIRE(s1 == set_t{0,1,2});
|
||||||
|
set_t s2;
|
||||||
|
s2 = std::move(s1);
|
||||||
|
REQUIRE(s0 == set_t{0,1,2});
|
||||||
|
REQUIRE(s1.empty());
|
||||||
|
REQUIRE(s2 == set_t{0,1,2});
|
||||||
|
set_t s3;
|
||||||
|
s3 = {1,2,3};
|
||||||
|
REQUIRE(s3 == set_t{1,2,3});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECTION("capacity") {
|
SECTION("capacity") {
|
||||||
using set_t = flat_set<int>;
|
using set_t = flat_set<int>;
|
||||||
|
|||||||
Reference in New Issue
Block a user