diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-06-26 16:15:20 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-06-26 16:15:20 +0200 |
commit | 29c7661c6f92d80f63a9a3cc37f3dc790a161f3f (patch) | |
tree | 8aaa22d294e8790757a52568d043fd05208225f7 /libstdc++-v3/testsuite | |
parent | f8f7ace4f20829f2fad87662f5163c9b13427e39 (diff) | |
download | gcc-29c7661c6f92d80f63a9a3cc37f3dc790a161f3f.zip gcc-29c7661c6f92d80f63a9a3cc37f3dc790a161f3f.tar.gz gcc-29c7661c6f92d80f63a9a3cc37f3dc790a161f3f.tar.bz2 |
c++, libstdc++: Implement C++26 P2830R10 - Constexpr Type Ordering
The following patch attempts to implement the C++26 P2830R10 - Constexpr Type
Ordering paper, with a minor change that std::type_order<T, U> class template
doesn't derive from integer_constant, because std::strong_ordering is not
a structural type (except in MSVC), so instead it is just a class template
with static constexpr strong_ordering value member and also value_type,
type and 2 operators.
The paper mostly talks about using something other than mangled names for
the ordering, but given that the mangler is part of the GCC C++ FE, using
the mangler seems to be the best ordering choice to me.
2025-06-26 Jakub Jelinek <jakub@redhat.com>
gcc/cp/
* cp-trait.def: Implement C++26 P2830R10 - Constexpr Type Ordering.
(TYPE_ORDER): New.
* method.cc (type_order_value): Define.
* cp-tree.h (type_order_value): Declare.
* semantics.cc (trait_expr_value): Use gcc_unreachable also
for CPTK_TYPE_ORDER, adjust comment.
(finish_trait_expr): Handle CPTK_TYPE_ORDER.
* constraint.cc (diagnose_trait_expr): Likewise.
gcc/testsuite/
* g++.dg/cpp26/type-order1.C: New test.
* g++.dg/cpp26/type-order2.C: New test.
* g++.dg/cpp26/type-order3.C: New test.
libstdc++-v3/
* include/bits/version.def (type_order): New.
* include/bits/version.h: Regenerate.
* libsupc++/compare: Define __glibcxx_want_type_order before
including bits/version.h.
(std::type_order, std::type_order_v): New trait and template variable.
* src/c++23/std.cc.in (std::type_order, std::type_order_v): Export.
* testsuite/18_support/comparisons/type_order/1.cc: New test.
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r-- | libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc b/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc new file mode 100644 index 0000000..b510494 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/type_order/1.cc @@ -0,0 +1,95 @@ +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do compile { target c++26 } } + +#include <compare> + +#if __cpp_lib_type_order != 202506L +# error "__cpp_lib_type_order != 202506" +#endif + +static_assert (std::is_same_v <decltype (std::type_order <int, int>::value), + const std::strong_ordering>); +static_assert (std::is_same_v <decltype (std::type_order_v <char, short>), + const std::strong_ordering>); +struct S; +struct T; +template <typename T> +struct U +{ +}; +typedef int int2; +struct V {}; +namespace +{ + struct W {}; +} + +template <typename T, typename U> +struct eq +{ + constexpr eq () + { + static_assert (std::type_order <T, U>::value == std::strong_ordering::equal); + static_assert (std::type_order <U, T>::value == std::strong_ordering::equal); + static_assert (std::type_order_v <T, U> == std::strong_ordering::equal); + static_assert (std::type_order_v <U, T> == std::strong_ordering::equal); + } +}; +template <typename T, typename U> +struct ne +{ + constexpr ne () + { + static_assert (std::type_order <T, U>::value != std::strong_ordering::equal); + static_assert (std::type_order <U, T>::value != std::strong_ordering::equal); + static_assert (std::type_order <T, U>::value == std::strong_ordering::greater + ? std::type_order <U, T>::value == std::strong_ordering::less + : std::type_order <U, T>::value == std::strong_ordering::greater); + static_assert (std::type_order_v <T, U> != std::strong_ordering::equal); + static_assert (std::type_order_v <U, T> != std::strong_ordering::equal); + static_assert (std::type_order_v <T, U> == std::strong_ordering::greater + ? std::type_order_v <U, T> == std::strong_ordering::less + : std::type_order_v <U, T> == std::strong_ordering::greater); + } +}; + +constexpr eq <void, void> a; +constexpr eq <const void, const void> b; +constexpr eq <int, int> c; +constexpr eq <long int, long int> d; +constexpr eq <const volatile unsigned, const volatile unsigned> e; +constexpr eq <S, S> f; +constexpr eq <U <int>, U <int>> g; +constexpr eq <unsigned[2], unsigned[2]> h; +constexpr eq <int, int2> i; +constexpr eq <int (*) (int, long), int (*) (int, long)> j; +constexpr ne <int, long> k; +constexpr ne <const int, int> l; +constexpr ne <S, T> m; +constexpr ne <int &, int &&> n; +constexpr ne <U <S>, U <T>> o; +constexpr ne <U <short>, U <char>> p; +static_assert (std::type_order_v <S, T> != std::strong_ordering::less + || std::type_order_v <T, V> != std::strong_ordering::less + || std::type_order_v <S, V> == std::strong_ordering::less); +constexpr ne <int (*) (int, long), int (*) (int, int)> q; +constexpr eq <W, W> r; +constexpr ne <V, W> s; +constexpr eq <U <W>, U <W>> t; +constexpr ne <U <V>, U <W>> u; |