[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