[gcc r17-3431] libstdc++: Make std::stack constexpr.
Tomasz Kaminski
tkaminsk@gcc.gnu.org
Wed Aug 19 15:40:37 GMT 2026
https://gcc.gnu.org/g:77cb5aed66c500758bde3a9edc4f4bff5bfce6ba
commit r17-3431-g77cb5aed66c500758bde3a9edc4f4bff5bfce6ba
Author: Tomasz Kamiński <tkaminsk@redhat.com>
Date: Mon Aug 10 09:26:14 2026 +0200
libstdc++: Make std::stack constexpr.
This patch make stack and it's formatter constexpr, implementing
corresponding part of P3372, "constexpr containers and adaptors",
and final parts of P3391R2, "constexpr format".
libstdc++-v3/ChangeLog:
* include/bits/stl_stack.h (std::stack): Declare members as
_GLIBCXX26_CONSTEXPR.
(std::operator==, std::operator!=, std::operator<, std::operator>)
(std::operator<=, std::operator>=, std::operator<=>, std::swap):
Declare as _GLIBCXX26_CONSTEXPR.
* include/bits/version.def (constexpr_stack): Define.
* include/bits/version.h: Regenerate.
* include/std/stack (__cpp_lib_constexpr_stack): Define.
* (formatter<stack<....>, _CharT>::format)
[__glibcxx_constexpr_format]: Declare as constexpr.
* testsuite/23_containers/headers/stack/synopsis.cc:
Update declarations.
* testsuite/std/format/ranges/adaptors.cc: Expand test to stack.
* testsuite/23_containers/stack/constexpr.cc: New test derived
from 23_containers/queue/constexpr.cc.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Diff:
---
libstdc++-v3/include/bits/stl_stack.h | 58 +++--
libstdc++-v3/include/bits/version.def | 9 +
libstdc++-v3/include/bits/version.h | 10 +
libstdc++-v3/include/std/stack | 4 +
.../23_containers/headers/stack/synopsis.cc | 30 ++-
.../testsuite/23_containers/stack/constexpr.cc | 241 +++++++++++++++++++++
.../testsuite/std/format/ranges/adaptors.cc | 1 +
7 files changed, 317 insertions(+), 36 deletions(-)
diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index 94b057760498..fd29579e21a0 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -117,16 +117,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _Tp1, typename _Seq1>
- friend bool
+ friend _GLIBCXX26_CONSTEXPR bool
operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
template<typename _Tp1, typename _Seq1>
- friend bool
+ friend _GLIBCXX26_CONSTEXPR bool
operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
#if __cpp_lib_three_way_comparison
template<typename _Tp1, three_way_comparable _Seq1>
- friend compare_three_way_result_t<_Seq1>
+ friend _GLIBCXX26_CONSTEXPR compare_three_way_result_t<_Seq1>
operator<=>(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
#endif
@@ -167,20 +167,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#else
template<typename _Seq = _Sequence, typename _Requires = typename
enable_if<is_default_constructible<_Seq>::value>::type>
+ _GLIBCXX26_CONSTEXPR
stack()
: c() { }
- explicit
+ explicit _GLIBCXX26_CONSTEXPR
stack(const _Sequence& __c)
: c(__c) { }
- explicit
+ explicit _GLIBCXX26_CONSTEXPR
stack(_Sequence&& __c)
: c(std::move(__c)) { }
#ifdef __glibcxx_adaptor_iterator_pair_constructor // C++ >= 23 && HOSTED
template<typename _InputIterator,
typename = _RequireInputIter<_InputIterator>>
+ _GLIBCXX26_CONSTEXPR
stack(_InputIterator __first, _InputIterator __last)
: c(__first, __last) { }
#endif
@@ -191,6 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @since C++23
*/
template<__detail::__container_compatible_range<_Tp> _Rg>
+ _GLIBCXX26_CONSTEXPR
stack(from_range_t, _Rg&& __rg)
: c(ranges::to<_Sequence>(std::forward<_Rg>(__rg)))
{ }
@@ -201,29 +204,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<__detail::__container_compatible_range<_Tp> _Rg,
typename _Alloc>
+ _GLIBCXX26_CONSTEXPR
stack(from_range_t, _Rg&& __rg, const _Alloc& __a)
: c(ranges::to<_Sequence>(std::forward<_Rg>(__rg), __a))
{ }
#endif
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
- explicit
+ explicit _GLIBCXX26_CONSTEXPR
stack(const _Alloc& __a)
: c(__a) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
+ _GLIBCXX26_CONSTEXPR
stack(const _Sequence& __c, const _Alloc& __a)
: c(__c, __a) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
+ _GLIBCXX26_CONSTEXPR
stack(_Sequence&& __c, const _Alloc& __a)
: c(std::move(__c), __a) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
+ _GLIBCXX26_CONSTEXPR
stack(const stack& __q, const _Alloc& __a)
: c(__q.c, __a) { }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
+ _GLIBCXX26_CONSTEXPR
stack(stack&& __q, const _Alloc& __a)
: c(std::move(__q.c), __a) { }
@@ -231,6 +239,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator, typename _Alloc,
typename = _RequireInputIter<_InputIterator>,
typename = _Uses<_Alloc>>
+ _GLIBCXX26_CONSTEXPR
stack(_InputIterator __first, _InputIterator __last, const _Alloc& __a)
: c(__first, __last, __a) { }
#endif
@@ -239,13 +248,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* Returns true if the %stack is empty.
*/
- _GLIBCXX_NODISCARD bool
+ _GLIBCXX_NODISCARD
+ _GLIBCXX26_CONSTEXPR bool
empty() const
{ return c.empty(); }
/** Returns the number of elements in the %stack. */
_GLIBCXX_NODISCARD
- size_type
+ _GLIBCXX26_CONSTEXPR size_type
size() const
{ return c.size(); }
@@ -254,7 +264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* element of the %stack.
*/
_GLIBCXX_NODISCARD
- reference
+ _GLIBCXX26_CONSTEXPR reference
top()
{
__glibcxx_requires_nonempty();
@@ -266,7 +276,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* element of the %stack.
*/
_GLIBCXX_NODISCARD
- const_reference
+ _GLIBCXX26_CONSTEXPR const_reference
top() const
{
__glibcxx_requires_nonempty();
@@ -282,18 +292,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* to it. The time complexity of the operation depends on the
* underlying sequence.
*/
- void
+ _GLIBCXX26_CONSTEXPR void
push(const value_type& __x)
{ c.push_back(__x); }
#if __cplusplus >= 201103L
- void
+ _GLIBCXX26_CONSTEXPR void
push(value_type&& __x)
{ c.push_back(std::move(__x)); }
#if __cplusplus > 201402L
template<typename... _Args>
- decltype(auto)
+ _GLIBCXX26_CONSTEXPR decltype(auto)
emplace(_Args&&... __args)
{ return c.emplace_back(std::forward<_Args>(__args)...); }
#else
@@ -306,7 +316,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __glibcxx_containers_ranges // C++ >= 23
template<__detail::__container_compatible_range<_Tp> _Rg>
- void
+ _GLIBCXX26_CONSTEXPR void
push_range(_Rg&& __rg)
{
if constexpr (requires { c.append_range(std::forward<_Rg>(__rg)); })
@@ -327,7 +337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* data is needed, it should be retrieved before pop() is
* called.
*/
- void
+ _GLIBCXX26_CONSTEXPR void
pop()
{
__glibcxx_requires_nonempty();
@@ -335,7 +345,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if __cplusplus >= 201103L
- void
+ _GLIBCXX26_CONSTEXPR void
swap(stack& __s)
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
noexcept(__is_nothrow_swappable<_Sequence>::value)
@@ -405,7 +415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __x.c == __y.c; }
@@ -424,49 +434,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __x.c < __y.c; }
/// Based on operator==
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Tp, typename _Seq>
_GLIBCXX_NODISCARD
- inline bool
+ inline _GLIBCXX26_CONSTEXPR bool
operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return !(__x < __y); }
#if __cpp_lib_three_way_comparison
template<typename _Tp, three_way_comparable _Seq>
[[nodiscard]]
- inline compare_three_way_result_t<_Seq>
+ inline _GLIBCXX26_CONSTEXPR compare_three_way_result_t<_Seq>
operator<=>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y)
{ return __x.c <=> __y.c; }
#endif
#if __cplusplus >= 201103L
template<typename _Tp, typename _Seq>
- inline
+ inline _GLIBCXX26_CONSTEXPR
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
// Constrained free swap overload, see p0185r1
typename enable_if<__is_swappable<_Seq>::value>::type
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index b7349fdef639..81bbf0ea63ab 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1481,6 +1481,15 @@ ftms = {
};
};
+ftms = {
+ name = constexpr_stack;
+ values = {
+ v = 202502;
+ cxxmin = 26;
+ hosted = yes;
+ };
+};
+
ftms = {
name = constrained_equality;
values = {
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 142d550279f2..786db34d6be7 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1616,6 +1616,16 @@
#endif /* !defined(__cpp_lib_constexpr_queue) */
#undef __glibcxx_want_constexpr_queue
+#if !defined(__cpp_lib_constexpr_stack)
+# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
+# define __glibcxx_constexpr_stack 202502L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constexpr_stack)
+# define __cpp_lib_constexpr_stack 202502L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_constexpr_stack) */
+#undef __glibcxx_want_constexpr_stack
+
#if !defined(__cpp_lib_constrained_equality)
# if (__cplusplus > 202002L) && (__glibcxx_three_way_comparison)
# define __glibcxx_constrained_equality 202411L
diff --git a/libstdc++-v3/include/std/stack b/libstdc++-v3/include/std/stack
index b7f9d589b376..2ace5a732fde 100644
--- a/libstdc++-v3/include/std/stack
+++ b/libstdc++-v3/include/std/stack
@@ -63,6 +63,7 @@
#define __glibcxx_want_adaptor_iterator_pair_constructor
#define __glibcxx_want_containers_ranges
+#define __glibcxx_want_constexpr_stack
#include <bits/version.h>
#include <deque>
@@ -96,6 +97,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Standard declares this as template accepting unconstrained
// FormatContext type.
template<typename _Out>
+#ifdef __glibcxx_constexpr_format // C++ >= 26 && HOSTED && CXX11 string
+ constexpr
+#endif
typename basic_format_context<_Out, _CharT>::iterator
format(__maybe_const_adaptor& __a,
basic_format_context<_Out, _CharT>& __fc) const
diff --git a/libstdc++-v3/testsuite/23_containers/headers/stack/synopsis.cc b/libstdc++-v3/testsuite/23_containers/headers/stack/synopsis.cc
index 39be405d4bd6..25e6229034c8 100644
--- a/libstdc++-v3/testsuite/23_containers/headers/stack/synopsis.cc
+++ b/libstdc++-v3/testsuite/23_containers/headers/stack/synopsis.cc
@@ -20,30 +20,36 @@
#include <stack>
+#if __cplusplus > 202302L
+# define CONSTEXPR constexpr
+#else
+# define CONSTEXPR
+#endif
+
namespace std {
template <class T, class Container> class stack;
template <class T, class Container>
- bool operator==(const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator==(const stack<T, Container>& x, const stack<T, Container>& y);
template <class T, class Container>
- bool operator< (const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator<(const stack<T, Container>& x, const stack<T, Container>& y);
template <class T, class Container>
- bool operator!=(const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator!=(const stack<T, Container>& x, stack<T, Container>& y);
template <class T, class Container>
- bool operator> (const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator>(const stack<T, Container>& x, const stack<T, Container>& y);
template <class T, class Container>
- bool operator>=(const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
template <class T, class Container>
- bool operator<=(const stack<T, Container>& x,
- const stack<T, Container>& y);
+ CONSTEXPR bool
+ operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
}
diff --git a/libstdc++-v3/testsuite/23_containers/stack/constexpr.cc b/libstdc++-v3/testsuite/23_containers/stack/constexpr.cc
new file mode 100644
index 000000000000..c4c96e7b5375
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/stack/constexpr.cc
@@ -0,0 +1,241 @@
+// { dg-do compile { target c++26 } }
+
+#include <stack>
+
+#ifndef __cpp_lib_constexpr_stack
+# error "Feature test macro for __cpp_lib_constexpr_stack is missing in <stack>"
+#elif __cpp_lib_constexpr_stack != 202502L
+# error "Feature test macro for __cpp_lib_constexpr_stack has wrong value in <stack>"
+#endif
+
+#include <ranges>
+#include <functional>
+#include <vector>
+#include <numeric>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_allocator.h>
+
+using namespace __gnu_test;
+
+template<typename Cont>
+constexpr bool
+ctor_tests()
+{
+ using Tp = typename Cont::value_type;
+ using Alloc = typename Cont::allocator_type;
+
+ auto es = [] (std::stack<Tp, Cont> l, std::span<Tp> r) {
+ if (l.size() != r.size())
+ return false;
+
+ std::vector<Tp> s(r.begin(), r.end());
+ for (size_t i = s.size(); i > 0; --i) {
+ if (s[i-1] != l.top())
+ return false;
+ l.pop();
+ }
+ return true;
+ };
+
+ Cont c0;
+ Alloc alloc0;
+
+ std::stack<Tp, Cont> s1(c0);
+ VERIFY( s1.size() == 0 && s1.empty() );
+ s1.push(1);
+ s1.push(2);
+ VERIFY( s1.size() == 2 );
+
+ Cont c1{1, 2};
+ std::stack<Tp, Cont> s2(c1);
+ VERIFY ( s2 == s1 );
+ std::stack<Tp, Cont> s3(std::move(c1));
+ VERIFY ( s3 == s1 );
+
+ std::stack<Tp, Cont> s4(s1);
+ std::stack<Tp, Cont> s5(std::move(s1));
+ VERIFY ( s4 == s5 );
+
+ Tp rg[4] = {2, 3, 5, 7};
+ std::stack<Tp, Cont> s6(std::begin(rg), std::end(rg));
+ VERIFY ( es(s6, rg) );
+
+ VERIFY( s6.size() == std::size(rg));
+ VERIFY( s6.top() == 7 );
+ s6.pop();
+ VERIFY( s6.top() == 5 );
+ s6.pop();
+ VERIFY( s6.top() == 3 );
+ s6.pop();
+ VERIFY( s6.top() == 2 );
+ s6.pop();
+
+ std::stack<Tp, Cont> s7(alloc0);
+ s7.push(1);
+ s7.push(2);
+ VERIFY( s7.size() == 2 );
+
+ Cont c2{1, 2};
+ std::stack<Tp, Cont> s8(c2, alloc0);
+ VERIFY( s8 == s7 );
+ std::stack<Tp, Cont> s9(std::move(c2), alloc0);
+ VERIFY( s9 == s7 );
+ VERIFY( c2.empty() );
+
+ std::stack<Tp, Cont> s10(s7, alloc0);
+ VERIFY( s10 == s7 );
+ VERIFY( s10.size() == s7.size() );
+ VERIFY( s10.top() == s7.top() );
+
+ std::stack<Tp, Cont> s11(std::move(s7), alloc0);
+ VERIFY( s11 == s10 );
+ VERIFY( s11.size() == s10.size() );
+ VERIFY( s7.empty() );
+
+ std::stack<Tp, Cont> s12(std::begin(rg), std::end(rg), alloc0);
+ VERIFY ( es(s12, rg) );
+ VERIFY( s12.size() == std::size(rg));
+ VERIFY( s12.top() == 7 );
+ s12.pop();
+ VERIFY( s12.top() == 5 );
+ s12.pop();
+ VERIFY( s12.top() == 3 );
+ s12.pop();
+ VERIFY( s12.top() == 2 );
+ s12.pop();
+
+ std::stack<Tp, Cont> s13(std::from_range, rg);
+ VERIFY( es(s13, rg) );
+ std::stack<Tp, Cont> s14(std::from_range, rg, alloc0);
+ VERIFY( es(s14, rg) );
+
+ return true;
+}
+static_assert( ctor_tests<std::vector<int>>() );
+static_assert( ctor_tests<std::vector<int, SimpleAllocator<int>>>() );
+static_assert( ctor_tests<std::deque<int>>() );
+static_assert( ctor_tests<std::deque<int, SimpleAllocator<int>>>() );
+
+template<typename Range, typename Cont>
+constexpr void
+do_ranges_tests_a()
+{
+ using Tp = typename Cont::value_type;
+ typename Cont::allocator_type alloc;
+ Tp a[] {2, 3, 5, 7};
+
+ auto es = [&] (auto l, auto r) {
+ if (l.size() != r.size())
+ return false;
+
+ while (!l.empty()) {
+ if (l.top() != r.top())
+ return false;
+ l.pop();
+ r.pop();
+ }
+ return true;
+ };
+
+ std::stack<Tp, Cont> s1(std::from_range, Range(a, a+4));
+ std::stack<Tp> s2;
+ s2.push_range(Range(a, a+4));
+ VERIFY( es(s1, s2) );
+
+ std::stack<Tp, Cont> s3(std::from_range, Range(a, a+4), alloc);
+ std::stack<Tp, Cont> s4(std::from_range, Range(a, a+4));
+ VERIFY( es(s3, s4) );
+}
+
+template<typename Cont>
+constexpr bool
+ranges_tests()
+{
+ using Tp = typename Cont::value_type;
+
+ do_ranges_tests_a<test_forward_range<Tp>, Cont>();
+ do_ranges_tests_a<test_forward_sized_range<Tp>, Cont>();
+ do_ranges_tests_a<
+ test_sized_range_sized_sent<Tp, forward_iterator_wrapper>, Cont>();
+
+ do_ranges_tests_a<test_input_range<Tp>, Cont>();
+ do_ranges_tests_a<test_input_sized_range<Tp>, Cont>();
+ do_ranges_tests_a<
+ test_sized_range_sized_sent<Tp, forward_iterator_wrapper>, Cont>();
+
+ do_ranges_tests_a<
+ test_range<Tp, input_iterator_wrapper_nocopy>, Cont>();
+ do_ranges_tests_a<
+ test_sized_range<Tp, input_iterator_wrapper_nocopy>, Cont>();
+ do_ranges_tests_a<
+ test_sized_range_sized_sent<Tp, input_iterator_wrapper_nocopy>, Cont>();
+ return true;
+}
+static_assert( ranges_tests<std::vector<int>>() );
+static_assert( ranges_tests<std::vector<int, SimpleAllocator<int>>>() );
+
+constexpr bool
+push_and_pop_test()
+{
+ std::stack<int> a;
+ a.push(2);
+ a.push(4);
+ VERIFY( a.top() == 4 );
+ a.pop();
+ VERIFY( a.top() == 2 );
+ a.pop();
+ VERIFY( a.empty() );
+ return true;
+}
+static_assert( push_and_pop_test() );
+
+constexpr bool
+swap_test()
+{
+ std::stack<int> a,b;
+ a.push(1);
+ b.push(2);
+ std::swap(a, b);
+ VERIFY( a.top() == 2 );
+ VERIFY( b.top() == 1 );
+ return true;
+}
+static_assert( swap_test() );
+
+constexpr bool
+emplace_test()
+{
+ struct S
+ {
+ int foo;
+ constexpr S(int i, int j) : foo{i + j} {}
+ };
+
+ std::stack<S> a;
+ const S& s = a.emplace(196883, 1);
+ VERIFY( a.size() == 1 );
+ VERIFY( a.top().foo == 196884 );
+ return true;
+}
+static_assert( emplace_test() );
+
+constexpr bool
+operator_test()
+{
+ std::stack<int> a, b;
+ a.push(1);
+ b.push(1);
+ VERIFY( a == b );
+ VERIFY( a <= b );
+ VERIFY( a >= b );
+ b.pop();
+ b.push(2);
+ VERIFY( a < b );
+ VERIFY( !(a > b) );
+ VERIFY( a <= b );
+ VERIFY( !(a >= b) );
+ VERIFY( a != b );
+ return true;
+}
+static_assert( operator_test() );
diff --git a/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc
index 968ac00b63e1..188a6092ac75 100644
--- a/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc
+++ b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc
@@ -167,6 +167,7 @@ test_compare()
CONSTEXPR bool
test_all()
{
+ test_adaptor<std::stack>();
test_adaptor<std::queue>();
test_adaptor<std::priority_queue>();
test_compare<char>();
More information about the Libstdc++-cvs
mailing list