From 969359e3b86b6cd238bcb48cdaeb9be5dbeddb4b Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Mon, 27 Sep 2021 00:48:39 -0400 Subject: [PATCH] [libc++] [compare] Named comparison functions, is_eq etc. 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 | 1 + libcxx/include/__compare/is_eq.h | 34 +++++++ libcxx/include/__compare/ordering.h | 13 --- libcxx/include/compare | 1 + libcxx/include/module.modulemap | 1 + .../detail.headers/compare/is_eq.module.verify.cpp | 16 +++ .../cmp/compare.syn/named_functions.pass.cpp | 109 +++++++++++++++++++++ 7 files changed, 162 insertions(+), 13 deletions(-) create mode 100644 libcxx/include/__compare/is_eq.h create mode 100644 libcxx/test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp create mode 100644 libcxx/test/std/language.support/cmp/compare.syn/named_functions.pass.cpp diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 2ac3fb3..e046d16 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -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 index 0000000..906cb07 --- /dev/null +++ b/libcxx/include/__compare/is_eq.h @@ -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 diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h index f4ad31b..b250c16 100644 --- a/libcxx/include/__compare/ordering.h +++ b/libcxx/include/__compare/ordering.h @@ -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 diff --git a/libcxx/include/compare b/libcxx/include/compare index dda34de..ca1f574 100644 --- a/libcxx/include/compare +++ b/libcxx/include/compare @@ -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> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 89ac506..f85e9e3 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -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 index 0000000..2bc316e --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/compare/is_eq.module.verify.cpp @@ -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 index 0000000..1d31e55 --- /dev/null +++ b/libcxx/test/std/language.support/cmp/compare.syn/named_functions.pass.cpp @@ -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 + +// + +// 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 +#include + +#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; +} -- 2.7.4