[libcxx-commits] [libcxx] [libc++] Implement P2830R10: Standardized Constexpr Type Ordering (PR #216616)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 28 01:00:18 PDT 2026
================
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// These compilers do not support __builtin_type_order
+// UNSUPPORTED: clang-21, clang-22, clang-23, apple-clang-21
+// UNSUPPORTED: gcc-15
+
+// <compare>
+
+// template<class T, class U>
+// struct type_order;
+// template<class T, class U>
+// constexpr strong_ordering type_order_v = type_order<T, U>::value;
+
+#include <compare>
+#include <concepts>
+
+template <class T, class U>
+constexpr bool test_order(std::strong_ordering expected) {
+ return std::type_order<T, U>()() == expected && std::type_order<T, U>::value == expected &&
+ std::type_order_v<T, U> == expected && static_cast<std::strong_ordering>(std::type_order<T, U>()) == expected;
+}
+
+template <class T, class U>
+constexpr bool eq = test_order<T, U>(std::strong_ordering::equal);
+template <class T, class U>
+constexpr bool lt = test_order<T, U>(std::strong_ordering::less);
+template <class T, class U>
+constexpr bool gt = test_order<T, U>(std::strong_ordering::greater);
+template <class T, class U>
+constexpr bool ne = lt<T, U> || gt<T, U>;
+
+struct A {};
+struct B {};
+struct C {};
+
+static_assert(std::same_as<std::type_order<A, A>::value_type, std::strong_ordering>);
+static_assert(std::same_as<decltype(std::type_order<A, A>::value), const std::strong_ordering>);
+static_assert(std::same_as<decltype(std::type_order_v<A, A>), const std::strong_ordering>);
+
+static_assert(noexcept(std::type_order<int, int>()()));
+static_assert(noexcept(static_cast<std::strong_ordering>(std::type_order<int, int>())));
+
+static_assert(ne<int, const int>);
+static_assert(ne<int, int&>);
+static_assert(ne<int&, int&&>);
+
+static_assert(eq<A, A>);
+static_assert(ne<A, B> && ne<B, A>);
+
+// Since we do lexicographical compare of the mangled names and both A and B
+// are class types, A must compare less than B regardless of ABI
+static_assert(lt<A, B>);
----------------
philnik777 wrote:
> > You should also make sure that exactly one of A < B and B < A is true, as well as with a third type.
>
> I've omitted the third type here. The transitivity check should be in the clang Sema test, not here.
Why shouldn't it be tested here? That's clearly part of the interface required for the implementation.
https://github.com/llvm/llvm-project/pull/216616
More information about the libcxx-commits
mailing list