Commit b90498bc authored by Mark Logan's avatar Mark Logan Committed by Facebook Github Bot

Add ContainerT&& ctors to sorted_vector_map and sorted_vector_set.

Summary:
Add ContainerT&& ctors to sorted_vector_map and sorted_vector_set,
to support more efficient bulk-construction of these containers. With the
prior constructors, the only way to do bulk-construction efficiently was
by using the iterator constructors with a pre-sorted range. If you didn't
have a presorted range, you would need to make a temporary container in
order to get a sorted range. Repeatedly calling insert() without a sorted
range is quadratic, hence not an option.

Reviewed By: yfeldblum

Differential Revision: D4491299

fbshipit-source-id: 041c546578f44ee6928c5506e8d8191092143b12
parent 3ffcb010
...@@ -253,6 +253,22 @@ public: ...@@ -253,6 +253,22 @@ public:
insert(list.begin(), list.end()); insert(list.begin(), list.end());
} }
// Construct a sorted_vector_set by stealing the storage of a prefilled
// container. The container need not be sorted already. This supports
// bulk construction of sorted_vector_set with zero allocations, not counting
// those performed by the caller. (The iterator range constructor performs at
// least one allocation).
//
// Note that `sorted_vector_set(const ContainerT& container)` is not provided,
// since the purpose of this constructor is to avoid an unnecessary copy.
explicit sorted_vector_set(
ContainerT&& container,
const Compare& comp = Compare())
: m_(comp, container.get_allocator()) {
std::sort(container.begin(), container.end(), value_comp());
m_.cont_.swap(container);
}
key_compare key_comp() const { return m_; } key_compare key_comp() const { return m_; }
value_compare value_comp() const { return m_; } value_compare value_comp() const { return m_; }
...@@ -490,6 +506,22 @@ public: ...@@ -490,6 +506,22 @@ public:
insert(list.begin(), list.end()); insert(list.begin(), list.end());
} }
// Construct a sorted_vector_map by stealing the storage of a prefilled
// container. The container need not be sorted already. This supports
// bulk construction of sorted_vector_map with zero allocations, not counting
// those performed by the caller. (The iterator range constructor performs at
// least one allocation).
//
// Note that `sorted_vector_map(const ContainerT& container)` is not provided,
// since the purpose of this constructor is to avoid an unnecessary copy.
explicit sorted_vector_map(
ContainerT&& container,
const Compare& comp = Compare())
: m_(value_compare(comp), container.get_allocator()) {
std::sort(container.begin(), container.end(), value_comp());
m_.cont_.swap(container);
}
key_compare key_comp() const { return m_; } key_compare key_comp() const { return m_; }
value_compare value_comp() const { return m_; } value_compare value_comp() const { return m_; }
......
...@@ -504,3 +504,22 @@ TEST(SortedVectorTypes, TestBulkInsertionMovableTypes) { ...@@ -504,3 +504,22 @@ TEST(SortedVectorTypes, TestBulkInsertionMovableTypes) {
vmap.insert( vmap.insert(
std::make_move_iterator(s.begin()), std::make_move_iterator(s.end())); std::make_move_iterator(s.begin()), std::make_move_iterator(s.end()));
} }
TEST(SortedVectorTypes, TestSetCreationFromVector) {
std::vector<int> vec = {3, 1, -1, 5, 0};
sorted_vector_set<int> vset(std::move(vec));
check_invariant(vset);
EXPECT_THAT(vset, testing::ElementsAreArray({-1, 0, 1, 3, 5}));
}
TEST(SortedVectorTypes, TestMapCreationFromVector) {
std::vector<std::pair<int, int>> vec = {
{3, 1}, {1, 5}, {-1, 2}, {5, 3}, {0, 3}};
sorted_vector_map<int, int> vmap(std::move(vec));
check_invariant(vmap);
auto contents = std::vector<std::pair<int, int>>(vmap.begin(), vmap.end());
auto expected_contents = std::vector<std::pair<int, int>>({
{-1, 2}, {0, 3}, {1, 5}, {3, 1}, {5, 3},
});
EXPECT_EQ(contents, expected_contents);
}
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