Skip to content

Commit

Permalink
Allow moving container out of SortedVector and HeapVector
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Gaurav Mogre authored and facebook-github-bot committed Feb 25, 2025
1 parent 5560132 commit 431af35
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
16 changes: 16 additions & 0 deletions folly/container/heap_vector_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,22 @@ class heap_vector_container : growth_policy_wrapper<GrowthPolicy> {

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

/**
* Directly swap the container. Similar to swap()
*/
void swap_container(Container& newContainer) {
heap_vector_detail::as_sorted_unique(newContainer, value_comp());
heap_vector_detail::heapify(newContainer);
using std::swap;
swap(m_.cont_, newContainer);
}
void swap_container(sorted_unique_t, Container& newContainer) {
assert(heap_vector_detail::is_sorted_unique(newContainer, value_comp()));
heap_vector_detail::heapify(newContainer);
using std::swap;
swap(m_.cont_, newContainer);
}

heap_vector_container& operator=(const heap_vector_container& other) =
default;

Expand Down
30 changes: 30 additions & 0 deletions folly/container/sorted_vector_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,21 @@ class sorted_vector_set : detail::growth_policy_wrapper<GrowthPolicy> {
m_.cont_, value_comp(), /* range_is_sorted_unique */ false};
}

/**
* Directly swap the container. Similar to swap()
*/
void swap_container(Container& newContainer) {
detail::as_sorted_unique(newContainer, value_comp());
using std::swap;
swap(m_.cont_, newContainer);
}
void swap_container(sorted_unique_t, Container& newContainer) {
assert(detail::is_sorted_unique(
newContainer.begin(), newContainer.end(), value_comp()));
using std::swap;
swap(m_.cont_, newContainer);
}

sorted_vector_set& operator=(const sorted_vector_set& other) = default;

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

/**
* Directly swap the container. Similar to swap()
*/
void swap_container(Container& newContainer) {
detail::as_sorted_unique(newContainer, value_comp());
using std::swap;
swap(m_.cont_, newContainer);
}
void swap_container(sorted_unique_t, Container& newContainer) {
assert(detail::is_sorted_unique(
newContainer.begin(), newContainer.end(), value_comp()));
using std::swap;
swap(m_.cont_, newContainer);
}

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

sorted_vector_map& operator=(sorted_vector_map&& other) = default;
Expand Down
28 changes: 28 additions & 0 deletions folly/container/test/heap_vector_types_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1772,3 +1772,31 @@ TEST(HeapVectorTypes, TestGetContainer) {
heap_vector_set<int> s;
EXPECT_TRUE(s.get_container().empty());
}

TEST(HeapVectorTypes, TestSwapContainer) {
heap_vector_set<int> set{1, 2, 3};
std::vector<int> swapped{6, 5, 4};
set.swap_container(swapped);
EXPECT_EQ(swapped, (std::vector<int>{2, 1, 3}));
EXPECT_EQ(set.get_container(), (std::vector<int>{5, 4, 6}));
swapped = {1, 3, 5};
set.swap_container(folly::sorted_unique, swapped);
EXPECT_EQ(swapped, (std::vector<int>{5, 4, 6}));
EXPECT_EQ(set.get_container(), (std::vector<int>{3, 1, 5}));

heap_vector_map<int, int> map{{1, 1}, {2, 2}, {3, 3}};
std::vector<std::pair<int, int>> swappedMap{{6, 6}, {5, 5}, {4, 4}};
map.swap_container(swappedMap);
EXPECT_EQ(
swappedMap, (std::vector<std::pair<int, int>>{{2, 2}, {1, 1}, {3, 3}}));
EXPECT_EQ(
map.get_container(),
(std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {6, 6}}));
swappedMap = {{1, 1}, {3, 3}, {5, 5}};
map.swap_container(folly::sorted_unique, swappedMap);
EXPECT_EQ(
swappedMap, (std::vector<std::pair<int, int>>{{5, 5}, {4, 4}, {6, 6}}));
EXPECT_EQ(
map.get_container(),
(std::vector<std::pair<int, int>>{{3, 3}, {1, 1}, {5, 5}}));
}
27 changes: 27 additions & 0 deletions folly/container/test/sorted_vector_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1645,3 +1645,30 @@ TEST(SortedVectorTypes, Comparisons) {
EXPECT_EQ(map2 <=> map1, std::strong_ordering::greater);
#endif
}

TEST(SortedVectorTypes, TestSwapContainer) {
sorted_vector_set<int> set{1, 2, 3};
std::vector<int> swapped{6, 5, 4};
set.swap_container(swapped);
EXPECT_EQ(swapped, (std::vector<int>{1, 2, 3}));
EXPECT_EQ(set.get_container(), (std::vector<int>{4, 5, 6}));
swapped = {1, 3};
set.swap_container(folly::sorted_unique, swapped);
EXPECT_EQ(swapped, (std::vector<int>{4, 5, 6}));
EXPECT_EQ(set.get_container(), (std::vector<int>{1, 3}));

sorted_vector_map<int, int> map{{1, 1}, {2, 2}, {3, 3}};
std::vector<std::pair<int, int>> swappedMap{{6, 6}, {5, 5}, {4, 4}};
map.swap_container(swappedMap);
EXPECT_EQ(
swappedMap, (std::vector<std::pair<int, int>>{{1, 1}, {2, 2}, {3, 3}}));
EXPECT_EQ(
map.get_container(),
(std::vector<std::pair<int, int>>{{4, 4}, {5, 5}, {6, 6}}));
swappedMap = {{1, 1}, {3, 3}};
map.swap_container(folly::sorted_unique, swappedMap);
EXPECT_EQ(
swappedMap, (std::vector<std::pair<int, int>>{{4, 4}, {5, 5}, {6, 6}}));
EXPECT_EQ(
map.get_container(), (std::vector<std::pair<int, int>>{{1, 1}, {3, 3}}));
}

0 comments on commit 431af35

Please sign in to comment.