[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