Skip to content

Commit 431af35

Browse files
Gaurav Mogrefacebook-github-bot
authored andcommitted
Allow moving container out of SortedVector and HeapVector
Summary: PROBLEM There is a way to create a `SortedVector` or `HeapVector` type in folly by passing it a container. But there is no easy way to get that container back out. While `SortedVector::get_container_for_direct_mutation` could work, it involves a bunch more steps to execute. SOLUTION Create a new `swap_container` method for the 2 containers. Reviewed By: yfeldblum Differential Revision: D69144172 fbshipit-source-id: 100c17b58e7b651dbcda723c0da75f186390d129
1 parent 5560132 commit 431af35

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

folly/container/heap_vector_types.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,22 @@ class heap_vector_container : growth_policy_wrapper<GrowthPolicy> {
994994

995995
const Container& get_container() const noexcept { return m_.cont_; }
996996

997+
/**
998+
* Directly swap the container. Similar to swap()
999+
*/
1000+
void swap_container(Container& newContainer) {
1001+
heap_vector_detail::as_sorted_unique(newContainer, value_comp());
1002+
heap_vector_detail::heapify(newContainer);
1003+
using std::swap;
1004+
swap(m_.cont_, newContainer);
1005+
}
1006+
void swap_container(sorted_unique_t, Container& newContainer) {
1007+
assert(heap_vector_detail::is_sorted_unique(newContainer, value_comp()));
1008+
heap_vector_detail::heapify(newContainer);
1009+
using std::swap;
1010+
swap(m_.cont_, newContainer);
1011+
}
1012+
9971013
heap_vector_container& operator=(const heap_vector_container& other) =
9981014
default;
9991015

folly/container/sorted_vector_types.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,21 @@ class sorted_vector_set : detail::growth_policy_wrapper<GrowthPolicy> {
434434
m_.cont_, value_comp(), /* range_is_sorted_unique */ false};
435435
}
436436

437+
/**
438+
* Directly swap the container. Similar to swap()
439+
*/
440+
void swap_container(Container& newContainer) {
441+
detail::as_sorted_unique(newContainer, value_comp());
442+
using std::swap;
443+
swap(m_.cont_, newContainer);
444+
}
445+
void swap_container(sorted_unique_t, Container& newContainer) {
446+
assert(detail::is_sorted_unique(
447+
newContainer.begin(), newContainer.end(), value_comp()));
448+
using std::swap;
449+
swap(m_.cont_, newContainer);
450+
}
451+
437452
sorted_vector_set& operator=(const sorted_vector_set& other) = default;
438453

439454
sorted_vector_set& operator=(sorted_vector_set&& other) = default;
@@ -1086,6 +1101,21 @@ class sorted_vector_map : detail::growth_policy_wrapper<GrowthPolicy> {
10861101
m_.cont_, value_comp(), /* range_is_sorted_unique */ false};
10871102
}
10881103

1104+
/**
1105+
* Directly swap the container. Similar to swap()
1106+
*/
1107+
void swap_container(Container& newContainer) {
1108+
detail::as_sorted_unique(newContainer, value_comp());
1109+
using std::swap;
1110+
swap(m_.cont_, newContainer);
1111+
}
1112+
void swap_container(sorted_unique_t, Container& newContainer) {
1113+
assert(detail::is_sorted_unique(
1114+
newContainer.begin(), newContainer.end(), value_comp()));
1115+
using std::swap;
1116+
swap(m_.cont_, newContainer);
1117+
}
1118+
10891119
sorted_vector_map& operator=(const sorted_vector_map& other) = default;
10901120

10911121
sorted_vector_map& operator=(sorted_vector_map&& other) = default;

folly/container/test/heap_vector_types_test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,3 +1772,31 @@ TEST(HeapVectorTypes, TestGetContainer) {
17721772
heap_vector_set<int> s;
17731773
EXPECT_TRUE(s.get_container().empty());
17741774
}
1775+
1776+
TEST(HeapVectorTypes, TestSwapContainer) {
1777+
heap_vector_set<int> set{1, 2, 3};
1778+
std::vector<int> swapped{6, 5, 4};
1779+
set.swap_container(swapped);
1780+
EXPECT_EQ(swapped, (std::vector<int>{2, 1, 3}));
1781+
EXPECT_EQ(set.get_container(), (std::vector<int>{5, 4, 6}));
1782+
swapped = {1, 3, 5};
1783+
set.swap_container(folly::sorted_unique, swapped);
1784+
EXPECT_EQ(swapped, (std::vector<int>{5, 4, 6}));
1785+
EXPECT_EQ(set.get_container(), (std::vector<int>{3, 1, 5}));
1786+
1787+
heap_vector_map<int, int> map{{1, 1}, {2, 2}, {3, 3}};
1788+
std::vector<std::pair<int, int>> swappedMap{{6, 6}, {5, 5}, {4, 4}};
1789+
map.swap_container(swappedMap);
1790+
EXPECT_EQ(
1791+
swappedMap, (std::vector<std::pair<int, int>>{{2, 2}, {1, 1}, {3, 3}}));
1792+
EXPECT_EQ(
1793+
map.get_container(),
1794+
(std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {6, 6}}));
1795+
swappedMap = {{1, 1}, {3, 3}, {5, 5}};
1796+
map.swap_container(folly::sorted_unique, swappedMap);
1797+
EXPECT_EQ(
1798+
swappedMap, (std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {6, 6}}));
1799+
EXPECT_EQ(
1800+
map.get_container(),
1801+
(std::vector<std::pair<int, int>>{{3, 3}, {1, 1}, {5, 5}}));
1802+
}

folly/container/test/sorted_vector_test.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,3 +1645,30 @@ TEST(SortedVectorTypes, Comparisons) {
16451645
EXPECT_EQ(map2 <=> map1, std::strong_ordering::greater);
16461646
#endif
16471647
}
1648+
1649+
TEST(SortedVectorTypes, TestSwapContainer) {
1650+
sorted_vector_set<int> set{1, 2, 3};
1651+
std::vector<int> swapped{6, 5, 4};
1652+
set.swap_container(swapped);
1653+
EXPECT_EQ(swapped, (std::vector<int>{1, 2, 3}));
1654+
EXPECT_EQ(set.get_container(), (std::vector<int>{4, 5, 6}));
1655+
swapped = {1, 3};
1656+
set.swap_container(folly::sorted_unique, swapped);
1657+
EXPECT_EQ(swapped, (std::vector<int>{4, 5, 6}));
1658+
EXPECT_EQ(set.get_container(), (std::vector<int>{1, 3}));
1659+
1660+
sorted_vector_map<int, int> map{{1, 1}, {2, 2}, {3, 3}};
1661+
std::vector<std::pair<int, int>> swappedMap{{6, 6}, {5, 5}, {4, 4}};
1662+
map.swap_container(swappedMap);
1663+
EXPECT_EQ(
1664+
swappedMap, (std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {3, 3}}));
1665+
EXPECT_EQ(
1666+
map.get_container(),
1667+
(std::vector<std::pair<int, int>>{{4, 4}, {5, 5}, {6, 6}}));
1668+
swappedMap = {{1, 1}, {3, 3}};
1669+
map.swap_container(folly::sorted_unique, swappedMap);
1670+
EXPECT_EQ(
1671+
swappedMap, (std::vector<std::pair<int, int>>{{4, 4}, {5, 5}, {6, 6}}));
1672+
EXPECT_EQ(
1673+
map.get_container(), (std::vector<std::pair<int, int>>{{1, 1}, {3, 3}}));
1674+
}

0 commit comments

Comments
 (0)