[libcxx-commits] [libcxx] [libc++] Implement P2830R10: Standardized Constexpr Type Ordering (PR #216616)

Matthias Wippich via libcxx-commits libcxx-commits at lists.llvm.org
Thu Aug 20 06:12:16 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>);
----------------
Tsche wrote:

The reason I added it here is because we run these tests against GCC. If GCC's builtin behaves _wildly_ different, these tests should catch it. Clang's tests for its own builtin will not.

I don't think I test for transitivity in clang currently, that part can be moved I suppose.

https://github.com/llvm/llvm-project/pull/216616


More information about the libcxx-commits mailing list