aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Liu <winner245@hotmail.com>2025-03-19 12:28:11 -0400
committerGitHub <noreply@github.com>2025-03-19 12:28:11 -0400
commitb350bc2c0b88488f6c4eb84aadd4e74c67ca9b06 (patch)
treef54cb6477ec1f9ec2c5bd513b635efbf1b795cec
parent9a078a372ea69eb2d3f0700dfa14809648e78a88 (diff)
downloadllvm-b350bc2c0b88488f6c4eb84aadd4e74c67ca9b06.zip
llvm-b350bc2c0b88488f6c4eb84aadd4e74c67ca9b06.tar.gz
llvm-b350bc2c0b88488f6c4eb84aadd4e74c67ca9b06.tar.bz2
[libc++] Verify forward_list self-merging is a no-op (#129985)
https://wg21.link/LWG3088 requires that `forward_list::merge()` is a no-op when passed `*this`, which aligns with the behavior of `list::merge`. Although libc++'s implementation of `forward_list::merge()` already meets this requirement, there were no tests to verify this behavior. This patch adds the necessary tests to ensure that self-merging remains a no-op and prevents any future regressions on this. Closes #104942.
-rw-r--r--libcxx/docs/Status/Cxx23Issues.csv2
-rw-r--r--libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp7
-rw-r--r--libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp7
-rw-r--r--libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp7
-rw-r--r--libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp7
5 files changed, 29 insertions, 1 deletions
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index 9ae6322..8cfc250 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -137,7 +137,7 @@
"`LWG3593 <https://wg21.link/LWG3593>`__","Several iterators' ``base() const &`` and ``lazy_split_view::outer-iterator::value_type::end()`` missing ``noexcept``","2021-10 (Virtual)","","",""
"`LWG3595 <https://wg21.link/LWG3595>`__","Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","2021-10 (Virtual)","|Complete|","14",""
"","","","","",""
-"`LWG3088 <https://wg21.link/LWG3088>`__","``forward_list::merge`` behaviour unclear when passed ``*this``","2022-02 (Virtual)","","",""
+"`LWG3088 <https://wg21.link/LWG3088>`__","``forward_list::merge`` behaviour unclear when passed ``*this``","2022-02 (Virtual)","|Complete|","Yes",""
"`LWG3471 <https://wg21.link/LWG3471>`__","``polymorphic_allocator::allocate`` does not satisfy ``Cpp17Allocator`` requirements","2022-02 (Virtual)","","",""
"`LWG3525 <https://wg21.link/LWG3525>`__","``uses_allocator_construction_args`` fails to handle types convertible to ``pair``","2022-02 (Virtual)","","",""
"`LWG3598 <https://wg21.link/LWG3598>`__","``system_category().default_error_condition(0)`` is underspecified","2022-02 (Virtual)","","",""
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp
index 6e73b2f..9a16278 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue.pass.cpp
@@ -109,5 +109,12 @@ int main(int, char**) {
}
#endif
+ { // LWG3088: Make sure self-merging does nothing.
+ int a[] = {1, 2, 3, 4, 5};
+ std::forward_list<int> c(std::begin(a), std::end(a));
+ c.merge(c);
+ assert(c == std::forward_list<int>(std::begin(a), std::end(a)));
+ }
+
return 0;
}
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp
index fddf9f9..4e181404 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_lvalue_pred.pass.cpp
@@ -110,5 +110,12 @@ int main(int, char**) {
}
#endif
+ { // LWG3088: Make sure self-merging does nothing.
+ int a[] = {5, 4, 3, 2, 1};
+ std::forward_list<int> c(std::begin(a), std::end(a));
+ c.merge(c, std::greater<int>());
+ assert(c == std::forward_list<int>(std::begin(a), std::end(a)));
+ }
+
return 0;
}
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp
index d5084ec..acfa014 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue.pass.cpp
@@ -102,5 +102,12 @@ int main(int, char**) {
assert(c1 == c3);
}
+ { // LWG3088: Make sure self-merging does nothing.
+ int a[] = {1, 2, 3, 4, 5};
+ std::forward_list<int> c(std::begin(a), std::end(a));
+ c.merge(std::move(c));
+ assert(c == std::forward_list<int>(std::begin(a), std::end(a)));
+ }
+
return 0;
}
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp
index 235707c..41b56ce 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/merge_rvalue_pred.pass.cpp
@@ -103,5 +103,12 @@ int main(int, char**) {
assert(c1 == c3);
}
+ { // LWG3088: Make sure self-merging does nothing.
+ int a[] = {5, 4, 3, 2, 1};
+ std::forward_list<int> c(std::begin(a), std::end(a));
+ c.merge(std::move(c), std::greater<int>());
+ assert(c == std::forward_list<int>(std::begin(a), std::end(a)));
+ }
+
return 0;
}