Add support for temporary spans in absl::c_sort and absl::c_stable_sort. PiperOrigin-RevId: 995481340 Change-Id: I8fd2902823a6d4994dcb8823bf5685a5cf4039b0
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 9d2b48e..5c2d376 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h
@@ -1169,7 +1169,9 @@ // Container-based version of the <algorithm> `std::sort()` function // to sort elements in ascending order of their values. template <typename C> -constexpr void c_sort(C& c) { +constexpr std::enable_if_t< + container_algorithm_internal::IsPermissibleDestinationRange<C>::value, void> +c_sort(C&& c) { std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c)); } @@ -1177,7 +1179,9 @@ // Overload of c_sort() for performing a `comp` comparison other than the // default `operator<`. template <typename C, typename LessThan> -constexpr void c_sort(C& c, LessThan&& comp) { +constexpr std::enable_if_t< + container_algorithm_internal::IsPermissibleDestinationRange<C>::value, void> +c_sort(C&& c, LessThan&& comp) { std::sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp)); @@ -1189,7 +1193,9 @@ // to sort elements in ascending order of their values, preserving the order // of equivalents. template <typename C> -void c_stable_sort(C& c) { +std::enable_if_t< + container_algorithm_internal::IsPermissibleDestinationRange<C>::value, void> +c_stable_sort(C&& c) { std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c)); } @@ -1197,7 +1203,9 @@ // Overload of c_stable_sort() for performing a `comp` comparison other than the // default `operator<`. template <typename C, typename LessThan> -void c_stable_sort(C& c, LessThan&& comp) { +std::enable_if_t< + container_algorithm_internal::IsPermissibleDestinationRange<C>::value, void> +c_stable_sort(C&& c, LessThan&& comp) { std::stable_sort(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp));
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc index e025382..50a621e 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc
@@ -1338,6 +1338,18 @@ EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); } +TEST(MutatingTest, SortTemporarySpan) { + std::vector<int> test_vector = {2, 3, 1, 4}; + absl::c_sort(absl::MakeSpan(test_vector)); + EXPECT_THAT(test_vector, ElementsAre(1, 2, 3, 4)); +} + +TEST(MutatingTest, SortTemporarySpanWithPredicate) { + std::vector<int> test_vector = {2, 3, 1, 4}; + absl::c_sort(absl::MakeSpan(test_vector), std::greater<int>()); + EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); +} + // For absl::c_stable_sort tests. Needs an operator< that does not cover all // fields so that the test can check the sort preserves order of equal elements. struct Element { @@ -1374,6 +1386,24 @@ IsElement(1, 1), IsElement(1, 0))); } +TEST(MutatingTest, StableSortTemporarySpan) { + std::vector<Element> test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; + absl::c_stable_sort(absl::MakeSpan(test_vector)); + EXPECT_THAT(test_vector, + ElementsAre(IsElement(1, 1), IsElement(1, 0), IsElement(2, 1), + IsElement(2, 0), IsElement(2, 2))); +} + +TEST(MutatingTest, StableSortTemporarySpanWithPredicate) { + std::vector<Element> test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; + absl::c_stable_sort( + absl::MakeSpan(test_vector), + [](const Element& e1, const Element& e2) { return e2 < e1; }); + EXPECT_THAT(test_vector, + ElementsAre(IsElement(2, 1), IsElement(2, 0), IsElement(2, 2), + IsElement(1, 1), IsElement(1, 0))); +} + TEST(MutatingTest, ReplaceCopyIf) { const std::vector<int> initial = {1, 2, 3, 4, 5}; const std::vector<int> expected = {0, 2, 0, 4, 0};