Commit cb838d11 authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook Github Bot

improve sorted_vector_{map,set} compatibility with std::{map,set}

Summary:
This diff fixes a few rough edges in the folly::sorted_vector_set
and folly::sorted_vector_map APIs. It makes the default constructor
implicit; it adds emplace to sorted_vector_set; and it adds bulk insertion
via std::initializer_list to sorted_vector_set and sorted_vector_map.
This doesn't fix all incompatibilities. It also changes sorted_vector_set
and sorted_vector_map insertion so that they do not copy a value_type
const& argument if the key is already in the container.

Reviewed By: yfeldblum

Differential Revision: D13255279

fbshipit-source-id: dc5a16ea729e2a32a77f82ec0eacaeaf7854cd1a
parent 0895c3af
......@@ -255,8 +255,10 @@ class sorted_vector_set : detail::growth_policy_wrapper<GrowthPolicy> {
typedef typename Container::reverse_iterator reverse_iterator;
typedef typename Container::const_reverse_iterator const_reverse_iterator;
sorted_vector_set() : m_(Compare(), Allocator()) {}
explicit sorted_vector_set(
const Compare& comp = Compare(),
const Compare& comp,
const Allocator& alloc = Allocator())
: m_(comp, alloc) {}
......@@ -381,7 +383,12 @@ class sorted_vector_set : detail::growth_policy_wrapper<GrowthPolicy> {
}
std::pair<iterator, bool> insert(const value_type& value) {
return insert(std::move(value_type(value)));
iterator it = lower_bound(value);
if (it == end() || value_comp()(value, *it)) {
it = get_growth_policy().increase_capacity(m_.cont_, it);
return std::make_pair(m_.cont_.insert(it, value), true);
}
return std::make_pair(it, false);
}
std::pair<iterator, bool> insert(value_type&& value) {
......@@ -407,6 +414,26 @@ class sorted_vector_set : detail::growth_policy_wrapper<GrowthPolicy> {
detail::bulk_insert(*this, m_.cont_, first, last);
}
void insert(std::initializer_list<value_type> ilist) {
insert(ilist.begin(), ilist.end());
}
// emplace isn't better than insert for sorted_vector_set, but aids
// compatibility
template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) {
value_type v(std::forward<Args>(args)...);
return insert(std::move(v));
}
std::pair<iterator, bool> emplace(const value_type& value) {
return insert(value);
}
std::pair<iterator, bool> emplace(value_type&& value) {
return insert(std::move(value));
}
size_type erase(const key_type& key) {
iterator it = find(key);
if (it == end()) {
......@@ -641,8 +668,10 @@ class sorted_vector_map : detail::growth_policy_wrapper<GrowthPolicy> {
typedef typename Container::reverse_iterator reverse_iterator;
typedef typename Container::const_reverse_iterator const_reverse_iterator;
sorted_vector_map() : m_(value_compare(Compare()), Allocator()) {}
explicit sorted_vector_map(
const Compare& comp = Compare(),
const Compare& comp,
const Allocator& alloc = Allocator())
: m_(value_compare(comp), alloc) {}
......@@ -765,7 +794,12 @@ class sorted_vector_map : detail::growth_policy_wrapper<GrowthPolicy> {
}
std::pair<iterator, bool> insert(const value_type& value) {
return insert(std::move(value_type(value)));
iterator it = lower_bound(value.first);
if (it == end() || value_comp()(value, *it)) {
it = get_growth_policy().increase_capacity(m_.cont_, it);
return std::make_pair(m_.cont_.insert(it, value), true);
}
return std::make_pair(it, false);
}
std::pair<iterator, bool> insert(value_type&& value) {
......@@ -791,6 +825,10 @@ class sorted_vector_map : detail::growth_policy_wrapper<GrowthPolicy> {
detail::bulk_insert(*this, m_.cont_, first, last);
}
void insert(std::initializer_list<value_type> ilist) {
insert(ilist.begin(), ilist.end());
}
size_type erase(const key_type& key) {
iterator it = find(key);
if (it == end()) {
......
......@@ -183,6 +183,15 @@ TEST(SortedVectorTypes, SimpleSetTest) {
EXPECT_TRUE(s != cpy);
EXPECT_TRUE(s != cpy2);
EXPECT_TRUE(cpy2 == cpy);
sorted_vector_set<int> s3 = {};
s3.insert({1, 2, 3});
s3.emplace(4);
EXPECT_EQ(s3.size(), 4);
sorted_vector_set<std::string> s4;
s4.emplace("foobar", 3);
EXPECT_EQ(s4.count("foo"), 1);
}
TEST(SortedVectorTypes, TransparentSetTest) {
......@@ -308,6 +317,10 @@ TEST(SortedVectorTypes, SimpleMapTest) {
// Bad insert hint.
m.insert(m.begin() + 3, std::make_pair(1 << 15, 1.0f));
check_invariant(m);
sorted_vector_map<int, float> m4 = {};
m4.insert({{1, 1.0f}, {2, 2.0f}, {1, 2.0f}});
EXPECT_EQ(m4.at(2), 2.0f);
}
TEST(SortedVectorTypes, TransparentMapTest) {
......@@ -650,7 +663,7 @@ TEST(SortedVectorTypes, TestSetInsertionDupsOneByOne) {
vset.insert(elem);
}
check_invariant(vset);
EXPECT_EQ(vset.rbegin()->count_, 3);
EXPECT_EQ(vset.rbegin()->count_, 2);
EXPECT_THAT(
extractValues(vset), testing::ElementsAreArray({2, 4, 5, 6, 8, 10}));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment