[libcxx-commits] [libcxx] [libc++] Add coverage for push_range on stack/queue with non-default underlying containers (PR #210730)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jul 20 07:18:02 PDT 2026
https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/210730
This increases the test coverage for stack/queue and actually caught an issue in list::__invariants which was previously dead code.
>From 74b45c5affab26399e4bf08156be896c6fb652bc Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 20 Jul 2026 10:13:31 -0400
Subject: [PATCH] [libc++] Add coverage for push_range on stack/queue with
non-default underlying containers
This increases the test coverage for stack/queue and actually caught an
issue in list::__invariants which was previously dead code.
---
libcxx/include/list | 2 +-
.../priqueue.members/push_range.pass.cpp | 4 ++--
.../push_range_container_adaptors.h | 14 +++++++-------
.../queue/queue.cons/from_range.pass.cpp | 3 +++
.../queue/queue.defn/push_range.pass.cpp | 3 +++
.../stack/stack.cons/from_range.pass.cpp | 5 +++++
.../stack/stack.defn/push_range.pass.cpp | 5 +++++
7 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/list b/libcxx/include/list
index b4fb9191cd7f7..3b4eb05cbbc6a 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -1710,7 +1710,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::reverse() _NOEXCEPT {
template <class _Tp, class _Alloc>
_LIBCPP_CONSTEXPR_SINCE_CXX26 bool list<_Tp, _Alloc>::__invariants() const {
- return size() == std::distance(begin(), end());
+ return size() == static_cast<size_type>(std::distance(begin(), end()));
}
template <class _Tp, class _Alloc>
diff --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.members/push_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.members/push_range.pass.cpp
index 26ce56ff5daf6..f2d6496954997 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.members/push_range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.members/push_range.pass.cpp
@@ -18,10 +18,10 @@
int main(int, char**) {
for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
- test_push_range<std::priority_queue<int, std::vector<int, Alloc>>, Iter, Sent>(/*is_result_heapified=*/true);
+ test_push_range<std::priority_queue<int, std::vector<int, Alloc>>, Iter, Sent, /*IsResultHeapified=*/true>();
});
test_push_range_move_only<std::priority_queue>();
- test_push_range_inserter_choice<std::priority_queue, int>(/*is_result_heapified=*/true);
+ test_push_range_inserter_choice<std::priority_queue, int, /*IsResultHeapified=*/true>();
static_assert(test_constraints_push_range<std::priority_queue, int, double>());
diff --git a/libcxx/test/std/containers/container.adaptors/push_range_container_adaptors.h b/libcxx/test/std/containers/container.adaptors/push_range_container_adaptors.h
index adf439081a355..48eceaae88b3c 100644
--- a/libcxx/test/std/containers/container.adaptors/push_range_container_adaptors.h
+++ b/libcxx/test/std/containers/container.adaptors/push_range_container_adaptors.h
@@ -98,8 +98,8 @@ constexpr TestCase<T> FullContainer_LongRange{
// Container adaptors tests.
-template <class Adaptor, class Iter, class Sent>
-constexpr void test_push_range(bool is_result_heapified = false) {
+template <class Adaptor, class Iter, class Sent, bool IsResultHeapified = false>
+constexpr void test_push_range() {
using T = typename Adaptor::value_type;
auto test = [&](auto& test_case) {
@@ -110,7 +110,7 @@ constexpr void test_push_range(bool is_result_heapified = false) {
UnwrapAdaptor<Adaptor> unwrap_adaptor(std::move(adaptor));
auto& c = unwrap_adaptor.get_container();
- if (is_result_heapified) {
+ if constexpr (IsResultHeapified) {
assert(std::ranges::is_heap(c));
return std::ranges::is_permutation(c, test_case.expected);
} else {
@@ -207,8 +207,8 @@ struct Container {
friend bool operator==(const Container&, const Container&) = default;
};
-template <template <class...> class AdaptorT, class T>
-void test_push_range_inserter_choice(bool is_result_heapified = false) {
+template <template <class...> class AdaptorT, class T, bool IsResultHeapified = false>
+void test_push_range_inserter_choice() {
{ // `append_range` is preferred if available.
using BaseContainer = Container<T, InserterChoice::AppendRange>;
using Adaptor = AdaptorT<T, BaseContainer>;
@@ -220,7 +220,7 @@ void test_push_range_inserter_choice(bool is_result_heapified = false) {
UnwrapAdaptor<Adaptor> unwrap_adaptor(std::move(adaptor));
auto& c = unwrap_adaptor.get_container();
assert(c.inserter_choice == InserterChoice::AppendRange);
- if (is_result_heapified) {
+ if constexpr (IsResultHeapified) {
assert(std::ranges::is_heap(c));
assert(std::ranges::is_permutation(c, in));
} else {
@@ -239,7 +239,7 @@ void test_push_range_inserter_choice(bool is_result_heapified = false) {
UnwrapAdaptor<Adaptor> unwrap_adaptor(std::move(adaptor));
auto& c = unwrap_adaptor.get_container();
assert(c.inserter_choice == InserterChoice::PushBack);
- if (is_result_heapified) {
+ if constexpr (IsResultHeapified) {
assert(std::ranges::is_heap(c));
assert(std::ranges::is_permutation(c, in));
} else {
diff --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/from_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/from_range.pass.cpp
index d2b21e16c2461..23a67e6b9c230 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/from_range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/from_range.pass.cpp
@@ -8,6 +8,7 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+#include <list>
#include <queue>
#include "../../from_range_container_adaptors.h"
@@ -20,6 +21,8 @@
int main(int, char**) {
for_all_iterators_and_allocators<int>([]<class Iter, class Sent, class Alloc>() {
test_container_adaptor<std::queue, std::deque, int, Iter, Sent, Alloc>();
+ // Also cover a non-random-access (forward-iterator-only) underlying container.
+ test_container_adaptor<std::queue, std::list, int, Iter, Sent, Alloc>();
});
test_container_adaptor_move_only<std::queue>();
diff --git a/libcxx/test/std/containers/container.adaptors/queue/queue.defn/push_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.defn/push_range.pass.cpp
index 4ddfe59662499..ae830ba958a8a 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.defn/push_range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.defn/push_range.pass.cpp
@@ -12,6 +12,7 @@
// template<container-compatible-range<T> R>
// void push_range(R&& rg); // C++23
+#include <list>
#include <queue>
#include "../../push_range_container_adaptors.h"
@@ -20,6 +21,8 @@
int main(int, char**) {
for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
test_push_range<std::queue<int, std::deque<int, Alloc>>, Iter, Sent>();
+ // Also cover a non-random-access (forward-iterator-only) underlying container.
+ test_push_range<std::queue<int, std::list<int, Alloc>>, Iter, Sent>();
});
test_push_range_move_only<std::queue>();
test_push_range_inserter_choice<std::queue, int>();
diff --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/from_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/from_range.pass.cpp
index 90f43dc56e499..2d9e6002862ba 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/from_range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/from_range.pass.cpp
@@ -8,7 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+#include <list>
#include <stack>
+#include <vector>
#include "../../from_range_container_adaptors.h"
#include "test_macros.h"
@@ -20,6 +22,9 @@
int main(int, char**) {
for_all_iterators_and_allocators<int>([]<class Iter, class Sent, class Alloc>() {
test_container_adaptor<std::stack, std::deque, int, Iter, Sent, Alloc>();
+ // Also cover other valid underlying containers, including a non-random-access one.
+ test_container_adaptor<std::stack, std::vector, int, Iter, Sent, Alloc>();
+ test_container_adaptor<std::stack, std::list, int, Iter, Sent, Alloc>();
});
test_container_adaptor_move_only<std::stack>();
diff --git a/libcxx/test/std/containers/container.adaptors/stack/stack.defn/push_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.defn/push_range.pass.cpp
index 0466fc7867859..cef9b98b6ced7 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.defn/push_range.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.defn/push_range.pass.cpp
@@ -12,7 +12,9 @@
// template<container-compatible-range<T> R>
// void push_range(R&& rg); // C++23
+#include <list>
#include <stack>
+#include <vector>
#include "../../push_range_container_adaptors.h"
#include "test_macros.h"
@@ -20,6 +22,9 @@
int main(int, char**) {
for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
test_push_range<std::stack<int, std::deque<int, Alloc>>, Iter, Sent>();
+ // Also cover other valid underlying containers, including a non-random-access one.
+ test_push_range<std::stack<int, std::vector<int, Alloc>>, Iter, Sent>();
+ test_push_range<std::stack<int, std::list<int, Alloc>>, Iter, Sent>();
});
test_push_range_move_only<std::stack>();
test_push_range_inserter_choice<std::stack, int>();
More information about the libcxx-commits
mailing list