[PATCH] libstdc++: Make std::stack conxtexpr.

Jonathan Wakely jwakely@redhat.com
Wed Aug 19 10:37:03 GMT 2026


Typo of "constexpr" in the subject line


On Mon, 10 Aug 2026 at 10:00, Tomasz Kamiński wrote:
>
> 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.
> ---
> Updated also stack, so I will not forgget about updating the formatter
> later (and I could reuse the test).
>
> Tested on x86_64-linux. *format/ranges/adaptors.cc* and *stack* also
> tested in all standard modes, debug and -m32. OK for trunk?
>
>  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 ++-
>  .../23_containers/stack/constexpr.cc          | 241 ++++++++++++++++++
>  .../testsuite/std/format/ranges/adaptors.cc   |   1 +
>  7 files changed, 317 insertions(+), 36 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/23_containers/stack/constexpr.cc
>
> diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
> index 94b05776049..fd29579e21a 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

Elsewhere we have the ugly NODISCARD and CONSTEXPR macros on the same
line, and the return type on a separate line. See for example
std::string and std::vector. I think it's more readable that way.

OK for trunk with the typo fixed and those whitepace changes.


>        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 b7349fdef63..81bbf0ea63a 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 142d550279f..786db34d6be 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 b7f9d589b37..2ace5a732fd 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 39be405d4bd..25e6229034c 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 00000000000..c4c96e7b537
> --- /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 968ac00b63e..188a6092ac7 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>();
> --
> 2.55.0
>



More information about the Libstdc++ mailing list