[libc++] [compare] Named comparison functions, is_eq etc.
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>
Mon, 27 Sep 2021 04:48:39 +0000 (00:48 -0400)
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>
Wed, 29 Sep 2021 20:03:48 +0000 (16:03 -0400)
Some of these were previously half-implemented in "ordering.h";
now they're all implemented, and tested.
Note that `constexpr` functions are implicitly `inline`, so the
standard wording omits `inline` on these; but Louis and I agree
that that's surprising and it's better to be explicit about it.

Differential Revision: https://reviews.llvm.org/D110515

libcxx/include/CMakeLists.txt
libcxx/include/__compare/is_eq.h [new file with mode: 0644]
libcxx/include/__compare/ordering.h
libcxx/include/compare
libcxx/include/module.modulemap
libcxx/test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp [new file with mode: 0644]
libcxx/test/std/language.support/cmp/compare.syn/named_functions.pass.cpp [new file with mode: 0644]

index 2ac3fb3..e046d16 100644 (file)
@@ -103,6 +103,7 @@ set(files
   __charconv/to_chars_result.h
   __compare/common_comparison_category.h
   __compare/compare_three_way_result.h
+  __compare/is_eq.h
   __compare/ordering.h
   __compare/synth_three_way.h
   __compare/three_way_comparable.h
diff --git a/libcxx/include/__compare/is_eq.h b/libcxx/include/__compare/is_eq.h
new file mode 100644 (file)
index 0000000..906cb07
--- /dev/null
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___COMPARE_IS_EQ_H
+#define _LIBCPP___COMPARE_IS_EQ_H
+
+#include <__compare/ordering.h>
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 17
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
+
+#endif // _LIBCPP_STD_VER > 17
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___COMPARE_IS_EQ_H
index f4ad31b..b250c16 100644 (file)
@@ -312,19 +312,6 @@ inline constexpr strong_ordering strong_ordering::equal(_OrdResult::__equiv);
 inline constexpr strong_ordering strong_ordering::equivalent(_OrdResult::__equiv);
 inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater);
 
-// named comparison functions
-_LIBCPP_HIDE_FROM_ABI
-constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; }
-
-_LIBCPP_HIDE_FROM_ABI
-constexpr bool is_lteq(partial_ordering __cmp) noexcept { return __cmp <= 0; }
-
-_LIBCPP_HIDE_FROM_ABI
-constexpr bool is_gt(partial_ordering __cmp) noexcept { return __cmp > 0; }
-
-_LIBCPP_HIDE_FROM_ABI
-constexpr bool is_gteq(partial_ordering __cmp) noexcept { return __cmp >= 0; }
-
 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR)
 
 _LIBCPP_END_NAMESPACE_STD
index dda34de..ca1f574 100644 (file)
@@ -134,6 +134,7 @@ namespace std {
 
 #include <__compare/common_comparison_category.h>
 #include <__compare/compare_three_way_result.h>
+#include <__compare/is_eq.h>
 #include <__compare/ordering.h>
 #include <__compare/three_way_comparable.h>
 #include <__config>
index 89ac506..f85e9e3 100644 (file)
@@ -373,6 +373,7 @@ module std [system] {
     module __compare {
       module common_comparison_category { private header "__compare/common_comparison_category.h" }
       module compare_three_way_result   { private header "__compare/compare_three_way_result.h"   }
+      module is_eq                      { private header "__compare/is_eq.h"                      }
       module ordering                   { private header "__compare/ordering.h"                   }
       module synth_three_way            { private header "__compare/synth_three_way.h"            }
       module three_way_comparable       { private header "__compare/three_way_comparable.h"       }
diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp
new file mode 100644 (file)
index 0000000..2bc316e
--- /dev/null
@@ -0,0 +1,16 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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: modules-build
+
+// WARNING: This test was generated by 'generate_private_header_tests.py'
+// and should not be edited manually.
+
+// expected-error@*:* {{use of private header from outside its module: '__compare/is_eq.h'}}
+#include <__compare/is_eq.h>
diff --git a/libcxx/test/std/language.support/cmp/compare.syn/named_functions.pass.cpp b/libcxx/test/std/language.support/cmp/compare.syn/named_functions.pass.cpp
new file mode 100644 (file)
index 0000000..1d31e55
--- /dev/null
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <compare>
+
+// constexpr bool is_eq  (partial_ordering cmp) noexcept { return cmp == 0; }
+// constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
+// constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp < 0; }
+// constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
+// constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp > 0; }
+// constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }
+
+#include <compare>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test()
+{
+    assert(!std::is_eq(std::strong_ordering::less));
+    assert( std::is_eq(std::strong_ordering::equal));
+    assert(!std::is_eq(std::strong_ordering::greater));
+    assert(!std::is_eq(std::weak_ordering::less));
+    assert( std::is_eq(std::weak_ordering::equivalent));
+    assert(!std::is_eq(std::weak_ordering::greater));
+    assert(!std::is_eq(std::partial_ordering::less));
+    assert( std::is_eq(std::partial_ordering::equivalent));
+    assert(!std::is_eq(std::partial_ordering::greater));
+    assert(!std::is_eq(std::partial_ordering::unordered));
+
+    assert( std::is_neq(std::strong_ordering::less));
+    assert(!std::is_neq(std::strong_ordering::equal));
+    assert( std::is_neq(std::strong_ordering::greater));
+    assert( std::is_neq(std::weak_ordering::less));
+    assert(!std::is_neq(std::weak_ordering::equivalent));
+    assert( std::is_neq(std::weak_ordering::greater));
+    assert( std::is_neq(std::partial_ordering::less));
+    assert(!std::is_neq(std::partial_ordering::equivalent));
+    assert( std::is_neq(std::partial_ordering::greater));
+    assert( std::is_neq(std::partial_ordering::unordered));
+
+    assert( std::is_lt(std::strong_ordering::less));
+    assert(!std::is_lt(std::strong_ordering::equal));
+    assert(!std::is_lt(std::strong_ordering::greater));
+    assert( std::is_lt(std::weak_ordering::less));
+    assert(!std::is_lt(std::weak_ordering::equivalent));
+    assert(!std::is_lt(std::weak_ordering::greater));
+    assert( std::is_lt(std::partial_ordering::less));
+    assert(!std::is_lt(std::partial_ordering::equivalent));
+    assert(!std::is_lt(std::partial_ordering::greater));
+    assert(!std::is_lt(std::partial_ordering::unordered));
+
+    assert( std::is_lteq(std::strong_ordering::less));
+    assert( std::is_lteq(std::strong_ordering::equal));
+    assert(!std::is_lteq(std::strong_ordering::greater));
+    assert( std::is_lteq(std::weak_ordering::less));
+    assert( std::is_lteq(std::weak_ordering::equivalent));
+    assert(!std::is_lteq(std::weak_ordering::greater));
+    assert( std::is_lteq(std::partial_ordering::less));
+    assert( std::is_lteq(std::partial_ordering::equivalent));
+    assert(!std::is_lteq(std::partial_ordering::greater));
+    assert(!std::is_lteq(std::partial_ordering::unordered));
+
+    assert(!std::is_gt(std::strong_ordering::less));
+    assert(!std::is_gt(std::strong_ordering::equal));
+    assert( std::is_gt(std::strong_ordering::greater));
+    assert(!std::is_gt(std::weak_ordering::less));
+    assert(!std::is_gt(std::weak_ordering::equivalent));
+    assert( std::is_gt(std::weak_ordering::greater));
+    assert(!std::is_gt(std::partial_ordering::less));
+    assert(!std::is_gt(std::partial_ordering::equivalent));
+    assert( std::is_gt(std::partial_ordering::greater));
+    assert(!std::is_gt(std::partial_ordering::unordered));
+
+    assert(!std::is_gteq(std::strong_ordering::less));
+    assert( std::is_gteq(std::strong_ordering::equal));
+    assert( std::is_gteq(std::strong_ordering::greater));
+    assert(!std::is_gteq(std::weak_ordering::less));
+    assert( std::is_gteq(std::weak_ordering::equivalent));
+    assert( std::is_gteq(std::weak_ordering::greater));
+    assert(!std::is_gteq(std::partial_ordering::less));
+    assert( std::is_gteq(std::partial_ordering::equivalent));
+    assert( std::is_gteq(std::partial_ordering::greater));
+    assert(!std::is_gteq(std::partial_ordering::unordered));
+
+    // Test noexceptness.
+    ASSERT_NOEXCEPT(std::is_eq(std::partial_ordering::less));
+    ASSERT_NOEXCEPT(std::is_neq(std::partial_ordering::less));
+    ASSERT_NOEXCEPT(std::is_lt(std::partial_ordering::less));
+    ASSERT_NOEXCEPT(std::is_lteq(std::partial_ordering::less));
+    ASSERT_NOEXCEPT(std::is_gt(std::partial_ordering::less));
+    ASSERT_NOEXCEPT(std::is_gteq(std::partial_ordering::less));
+
+    return true;
+}
+
+int main(int, char**) {
+    test();
+    static_assert(test());
+
+    return 0;
+}