diff --git a/libcxx/include/utility b/libcxx/include/utility --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -319,7 +319,8 @@ wchar_t, byte>::value; template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> -constexpr bool cmp_equal(const _T1 __t1, const _T2 __t2) noexcept +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_equal(const _T1 __t1, const _T2 __t2) noexcept { using T1U = make_unsigned_t<_T1>; using T2U = make_unsigned_t<_T2>; @@ -331,14 +332,16 @@ return __t2 < 0 ? false : __t1 == T2U(__t2); } -template -constexpr bool cmp_not_equal(const _T1 __t1, const _T2 __t2) noexcept +template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_not_equal(const _T1 __t1, const _T2 __t2) noexcept { return !cmp_equal(__t1, __t2); } template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> -constexpr bool cmp_less(const _T1 __t1, const _T2 __t2) noexcept +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_less(const _T1 __t1, const _T2 __t2) noexcept { using T1U = make_unsigned_t<_T1>; using T2U = make_unsigned_t<_T2>; @@ -350,26 +353,30 @@ return __t2 < 0 ? false : __t1 < T2U(__t2); } -template -constexpr bool cmp_greater(const _T1 __t1, const _T2 __t2) noexcept +template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_greater(const _T1 __t1, const _T2 __t2) noexcept { return cmp_less(__t2, __t1); } -template -constexpr bool cmp_less_equal(const _T1 __t1, const _T2 __t2) noexcept +template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_less_equal(const _T1 __t1, const _T2 __t2) noexcept { return !cmp_greater(__t1, __t2); } -template -constexpr bool cmp_greater_equal(const _T1 __t1, const _T2 __t2) noexcept +template<__is_safe_integral_cmp _T1, __is_safe_integral_cmp _T2> +_LIBCPP_INLINE_VISIBILITY constexpr +bool cmp_greater_equal(const _T1 __t1, const _T2 __t2) noexcept { return !cmp_less(__t1, __t2); } template<__is_safe_integral_cmp _Rt, __is_safe_integral_cmp _Ty> -constexpr bool in_range(const _Ty __t) noexcept +_LIBCPP_INLINE_VISIBILITY constexpr +bool in_range(const _Ty __t) noexcept { return cmp_less_equal(__t, numeric_limits<_Rt>::max()) && cmp_greater_equal(__t, numeric_limits<_Rt>::min()); diff --git a/libcxx/test/std/utilities/utility/intcmp/intcmp.fail.cpp b/libcxx/test/std/utilities/utility/intcmp/intcmp.fail.cpp --- a/libcxx/test/std/utilities/utility/intcmp/intcmp.fail.cpp +++ b/libcxx/test/std/utilities/utility/intcmp/intcmp.fail.cpp @@ -24,17 +24,93 @@ #include "test_macros.h" +struct NonEmptyT { + static int foo; + void func(int); +}; + +struct EmptyT {}; + template constexpr void test() { - std::cmp_equal(T(), T()); // expected-error10{{no matching function for call to 'cmp_equal'}} - std::cmp_equal(T(), int()); // expected-error10{{no matching function for call to 'cmp_equal'}} - std::cmp_equal(int(), T()); // expected-error10{{no matching function for call to 'cmp_equal'}} - std::cmp_less(T(), T()); // expected-error10{{no matching function for call to 'cmp_less'}} - std::cmp_less(T(), int()); // expected-error10{{no matching function for call to 'cmp_less'}} - std::cmp_less(int(), T()); // expected-error10{{no matching function for call to 'cmp_less'}} - std::in_range(int()); // expected-error10{{no matching function for call to 'in_range'}} - std::in_range(T()); // expected-error10{{no matching function for call to 'in_range'}} + std::cmp_equal( + T(), + T()); // expected-error7{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + T(), + int()); // expected-error7{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + int(), + T()); // expected-error7{{no matching function for call to 'cmp_equal'}} + std::cmp_less( + T(), + T()); // expected-error7{{no matching function for call to 'cmp_less'}} + std::cmp_less( + T(), + int()); // expected-error7{{no matching function for call to 'cmp_less'}} + std::cmp_less( + int(), + T()); // expected-error7{{no matching function for call to 'cmp_less'}} + std::in_range( + int()); // expected-error7{{no matching function for call to 'in_range'}} + std::in_range( + T()); // expected-error7{{no matching function for call to 'in_range'}} +} +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template +constexpr void test_char8t() { + std::cmp_equal( + T(), + T()); // expected-error{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + T(), + int()); // expected-error{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + int(), + T()); // expected-error{{no matching function for call to 'cmp_equal'}} + std::cmp_less( + T(), + T()); // expected-error{{no matching function for call to 'cmp_less'}} + std::cmp_less( + T(), + int()); // expected-error{{no matching function for call to 'cmp_less'}} + std::cmp_less( + int(), + T()); // expected-error{{no matching function for call to 'cmp_less'}} + std::in_range( + int()); // expected-error{{no matching function for call to 'in_range'}} + std::in_range( + T()); // expected-error{{no matching function for call to 'in_range'}} +} +#endif // _LIBCPP_NO_HAS_CHAR8_T + +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +template +constexpr void test_uchars() { + std::cmp_equal( + T(), + T()); // expected-error2{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + T(), + int()); // expected-error2{{no matching function for call to 'cmp_equal'}} + std::cmp_equal( + int(), + T()); // expected-error2{{no matching function for call to 'cmp_equal'}} + std::cmp_less( + T(), + T()); // expected-error2{{no matching function for call to 'cmp_less'}} + std::cmp_less( + T(), + int()); // expected-error2{{no matching function for call to 'cmp_less'}} + std::cmp_less( + int(), + T()); // expected-error2{{no matching function for call to 'cmp_less'}} + std::in_range( + int()); // expected-error2{{no matching function for call to 'in_range'}} + std::in_range( + T()); // expected-error2{{no matching function for call to 'in_range'}} } +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS int main() { test(); @@ -44,13 +120,15 @@ test(); test(); test(); + test(); + test(); #ifndef _LIBCPP_NO_HAS_CHAR8_T - test(); + test_char8t(); #endif // !_LIBCPP_NO_HAS_CHAR8_T #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - test(); - test(); + test_uchars(); + test_uchars(); #endif // !_LIBCPP_HAS_NO_UNICODE_CHARS return 0; } diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_equal/cmp_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_equal/cmp_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_equal/cmp_equal.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// template +// constexpr bool cmp_equal(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr static bool test_cmp_equal1() { + constexpr Tuple tup; + assert(std::cmp_equal(T(0), T(0))); + assert(std::cmp_equal(T(10), T(10))); + assert(std::cmp_equal(tup.min, tup.min)); + assert(std::cmp_equal(tup.max, tup.max)); + + assert(!std::cmp_equal(T(0), T(1))); + assert(!std::cmp_equal(T(1), T(0))); + assert(!std::cmp_equal(T(5), T(10))); + assert(!std::cmp_equal(T(10), T(5))); + + assert(!std::cmp_equal(tup.min, tup.max)); + assert(!std::cmp_equal(tup.max, tup.min)); + + assert(!std::cmp_equal(1, tup.max)); + assert(!std::cmp_equal(tup.max, 1)); + assert(!std::cmp_equal(1, tup.min)); + assert(!std::cmp_equal(tup.min, 1)); + + if constexpr (std::is_signed_v) { + assert(std::cmp_equal(T(-5), T(-5))); + + assert(!std::cmp_equal(-2, tup.min)); + assert(!std::cmp_equal(tup.min, -2)); + assert(!std::cmp_equal(-2, tup.max)); + assert(!std::cmp_equal(tup.max, -2)); + } + return true; +} + +template +constexpr static bool test_cmp_equal2() { + constexpr Tuple ttup; + constexpr Tuple utup; + assert(std::cmp_equal(T(0), U(0))); + assert(std::cmp_equal(T(10), U(10))); + assert(!std::cmp_equal(T(0), U(1))); + assert(!std::cmp_equal(T(1), U(0))); + assert(!std::cmp_equal(T(5), U(10))); + assert(!std::cmp_equal(T(10), U(5))); + assert(!std::cmp_equal(ttup.min, utup.max)); + assert(!std::cmp_equal(utup.min, ttup.max)); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_equal1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_equal2()) && (... && test_cmp_equal2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types1{}) && + test2(Types1{}, Types2{})); + return true; +} + +int main() { + + ASSERT_NOEXCEPT(std::cmp_equal(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater/cmp_greater.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// constexpr bool cmp_greater(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr bool test_cmp_greater1() { + constexpr Tuple tup; + assert(!std::cmp_greater(T(0), T(1))); + assert(!std::cmp_greater(T(1), T(2))); + assert(!std::cmp_greater(tup.min, tup.max)); + assert(!std::cmp_greater(tup.min, tup.mid)); + assert(!std::cmp_greater(tup.mid, tup.max)); + + assert(std::cmp_greater(T(1), T(0))); + assert(std::cmp_greater(T(10), T(5))); + assert(std::cmp_greater(tup.max, tup.min)); + assert(std::cmp_greater(tup.mid, tup.min)); + assert(!std::cmp_greater(tup.mid, tup.mid)); + assert(!std::cmp_greater(tup.min, tup.min)); + assert(!std::cmp_greater(tup.max, tup.max)); + + assert(std::cmp_greater(tup.max, 1)); + assert(std::cmp_greater(1, tup.min)); + + if constexpr (std::is_signed_v) { + assert(!std::cmp_greater(T(-1), T(-1))); + assert(std::cmp_greater(-2, tup.min)); + assert(!std::cmp_greater(tup.min, -2)); + assert(!std::cmp_greater(-2, tup.max)); + assert(std::cmp_greater(tup.max, -2)); + } + + return true; +} + +template +constexpr bool test_cmp_greater2() { + assert(!std::cmp_greater(T(0), U(1))); + assert(std::cmp_greater(T(1), U(0))); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_greater1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_greater2()) && + (... && test_cmp_greater2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types1{}) && + test2(Types1{}, Types2{})); + return true; +} + +int main() { + + ASSERT_NOEXCEPT(std::cmp_greater(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater_equal/cmp_greater_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater_equal/cmp_greater_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_greater_equal/cmp_greater_equal.pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// constexpr bool cmp_greater_equal(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr bool test_cmp_greater_equal1() { + constexpr Tuple tup; + assert(!std::cmp_greater_equal(T(0), T(1))); + assert(!std::cmp_greater_equal(T(1), T(2))); + assert(!std::cmp_greater_equal(tup.min, tup.max)); + assert(!std::cmp_greater_equal(tup.min, tup.mid)); + assert(!std::cmp_greater_equal(tup.mid, tup.max)); + + assert(std::cmp_greater_equal(T(1), T(0))); + assert(std::cmp_greater_equal(T(10), T(5))); + assert(std::cmp_greater_equal(tup.max, tup.min)); + assert(std::cmp_greater_equal(tup.mid, tup.min)); + assert(std::cmp_greater_equal(tup.mid, tup.mid)); + assert(std::cmp_greater_equal(tup.min, tup.min)); + assert(std::cmp_greater_equal(tup.max, tup.max)); + + assert(std::cmp_greater_equal(tup.max, 1)); + assert(std::cmp_greater_equal(1, tup.min)); + + if constexpr (std::is_signed_v) { + assert(std::cmp_greater_equal(T(-1), T(-1))); + + assert(std::cmp_greater_equal(-2, tup.min)); + assert(!std::cmp_greater_equal(tup.min, -2)); + assert(!std::cmp_greater_equal(-2, tup.max)); + assert(std::cmp_greater_equal(tup.max, -2)); + } + return true; +} + +template +constexpr bool test_cmp_greater_equal2() { + assert(!std::cmp_greater_equal(T(0), U(1))); + assert(std::cmp_greater_equal(T(1), U(0))); + assert(std::cmp_greater_equal(T(0), U(0))); + assert(std::cmp_greater_equal(T(1), U(1))); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_greater_equal1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_greater_equal2()) && + (... && test_cmp_greater_equal2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types1{}) && + test2(Types1{}, Types2{})); + return true; +} + +int main() { + + ASSERT_NOEXCEPT( + std::cmp_greater_equal(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less/cmp_less.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// template +// constexpr bool cmp_less(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr bool test_cmp_less1() { + constexpr Tuple tup; + assert(std::cmp_less(T(0), T(1))); + assert(std::cmp_less(T(1), T(2))); + assert(std::cmp_less(tup.min, tup.max)); + assert(std::cmp_less(tup.min, tup.mid)); + assert(std::cmp_less(tup.mid, tup.max)); + + assert(!std::cmp_less(T(1), T(0))); + assert(!std::cmp_less(T(10), T(5))); + assert(!std::cmp_less(tup.max, tup.min)); + assert(!std::cmp_less(tup.mid, tup.min)); + assert(!std::cmp_less(tup.mid, tup.mid)); + assert(!std::cmp_less(tup.min, tup.min)); + assert(!std::cmp_less(tup.max, tup.max)); + + assert(!std::cmp_less(tup.max, 1)); + assert(!std::cmp_less(1, tup.min)); + + if constexpr (std::is_signed_v) { + assert(!std::cmp_less(T(-1), T(-1))); + + assert(!std::cmp_less(-2, tup.min)); + assert(std::cmp_less(tup.min, -2)); + assert(std::cmp_less(-2, tup.max)); + assert(!std::cmp_less(tup.max, -2)); + } + + return true; +} + +template +constexpr bool test_cmp_less2() { + assert(std::cmp_less(T(0), U(1))); + assert(!std::cmp_less(T(1), U(0))); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_less1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_less2()) && (... && test_cmp_less2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types1{}) && + test2(Types1{}, Types2{})); + return true; +} + +int main() { + ASSERT_NOEXCEPT(std::cmp_less(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_less_equal/cmp_less_equal.pass.cpp @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// constexpr bool cmp_less_equal(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr bool test_cmp_less_equal1() { + constexpr Tuple tup; + assert(std::cmp_less_equal(T(0), T(0))); + assert(std::cmp_less_equal(T(0), T(1))); + assert(std::cmp_less_equal(tup.min, tup.max)); + assert(std::cmp_less_equal(tup.min, tup.mid)); + assert(std::cmp_less_equal(tup.mid, tup.max)); + assert(std::cmp_less_equal(tup.max, tup.max)); + assert(std::cmp_less_equal(tup.mid, tup.mid)); + assert(std::cmp_less_equal(tup.min, tup.min)); + + assert(!std::cmp_less_equal(T(1), T(0))); + assert(!std::cmp_less_equal(T(10), T(5))); + assert(!std::cmp_less_equal(tup.max, tup.min)); + assert(!std::cmp_less_equal(tup.mid, tup.min)); + assert(!std::cmp_less_equal(tup.max, 1)); + assert(!std::cmp_less_equal(1, tup.min)); + + if constexpr (std::is_signed_v) { + assert(std::cmp_less_equal(T(-1), T(-1))); + assert(!std::cmp_less_equal(-2, tup.min)); + assert(std::cmp_less_equal(tup.min, -2)); + assert(std::cmp_less_equal(-2, tup.max)); + assert(!std::cmp_less_equal(tup.max, -2)); + } + return true; +} + +template +constexpr bool test_cmp_less_equal2() { + assert(std::cmp_less_equal(T(0), U(1))); + assert(std::cmp_less_equal(T(0), U(0))); + assert(!std::cmp_less_equal(T(1), U(0))); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_less_equal1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_less_equal2()) && + (... && test_cmp_less_equal2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types1{}) && + test2(Types1{}, Types2{})); + return true; +} +int main() { + + ASSERT_NOEXCEPT( + std::cmp_less_equal(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_not_equal/cmp_not_equal.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_not_equal/cmp_not_equal.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.cmp_not_equal/cmp_not_equal.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// template +// constexpr bool cmp_not_equal(T t, U u) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr bool test_cmp_not_equal1() { + constexpr Tuple tup; + assert(!std::cmp_not_equal(T(0), T(0))); + assert(!std::cmp_not_equal(T(10), T(10))); + assert(!std::cmp_not_equal(tup.min, tup.min)); + assert(!std::cmp_not_equal(tup.max, tup.max)); + + assert(std::cmp_not_equal(T(0), T(1))); + assert(std::cmp_not_equal(T(1), T(0))); + assert(std::cmp_not_equal(T(5), T(10))); + assert(std::cmp_not_equal(T(10), T(5))); + + assert(std::cmp_not_equal(tup.min, tup.max)); + assert(std::cmp_not_equal(tup.max, tup.min)); + + assert(std::cmp_not_equal(1, tup.max)); + assert(std::cmp_not_equal(tup.max, 1)); + assert(std::cmp_not_equal(1, tup.min)); + assert(std::cmp_not_equal(tup.min, 1)); + + if constexpr (std::is_signed_v) { + assert(std::cmp_not_equal(-2, tup.min)); + assert(std::cmp_not_equal(tup.min, -2)); + assert(std::cmp_not_equal(-2, tup.max)); + assert(std::cmp_not_equal(tup.max, -2)); + } + + return true; +} + +template +constexpr bool test_cmp_not_equal2() { + constexpr Tuple ttup; + constexpr Tuple utup; + assert(!std::cmp_not_equal(T(0), U(0))); + assert(!std::cmp_not_equal(T(10), U(10))); + + assert(std::cmp_not_equal(T(0), U(1))); + assert(std::cmp_not_equal(T(1), U(0))); + assert(std::cmp_not_equal(T(5), U(10))); + assert(std::cmp_not_equal(T(10), U(5))); + assert(std::cmp_not_equal(ttup.min, utup.max)); + assert(std::cmp_not_equal(utup.min, ttup.max)); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_cmp_not_equal1()); +} + +template +constexpr bool test2(const std::tuple&, const std::tuple&) { + static_assert(sizeof...(T) == sizeof...(U)); + return (... && test_cmp_not_equal2()) && + (... && test_cmp_not_equal2()); +} + +constexpr bool test() { + using Types1 = + std::tuple; + using Types2 = std::tuple< +#ifndef _LIBCPP_HAS_NO_INT128 + __int128_t, __uint128_t, +#endif + unsigned long long, long long, uint64_t, int64_t, unsigned long, long, + uint32_t, int32_t, unsigned int, int, uint16_t, int16_t, unsigned short, + short, uint8_t, int8_t, unsigned char, signed char>; + assert(test1(Types1{}) && test2(Types1{}, Types2{}) && + test2(Types1{}, Types2{}) && test2(Types2{}, Types1{})); + return true; +} + +int main() { + + ASSERT_NOEXCEPT(std::cmp_not_equal(std::declval(), std::declval())); + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.in_range/in_range.pass.cpp b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.in_range/in_range.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.intcmp/intcmp.in_range/in_range.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// UNSUPPORTED: libcpp-no-concepts + +// + +// template +// constexpr bool in_range(T t) noexcept; // C++20 + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +struct Tuple { + T min; + T max; + T mid; + constexpr Tuple() { + min = std::numeric_limits::min(); + max = std::numeric_limits::max(); + mid = std::midpoint(min, max); + } +}; + +template +constexpr static bool test_in_range() { + constexpr Tuple tup; + assert(std::in_range(tup.min)); + assert(std::in_range(tup.min + 1)); + assert(std::in_range(tup.max)); + assert(std::in_range(tup.max - 1)); + assert(std::in_range(tup.mid)); + assert(std::in_range(tup.mid - 1)); + assert(std::in_range(tup.mid + 1)); + return true; +} + +constexpr static bool test_in_range1() { + constexpr Tuple utup8; + constexpr Tuple stup8; + assert(!std::in_range(utup8.max)); + assert(std::in_range(utup8.max)); + assert(!std::in_range(stup8.min)); + assert(std::in_range(utup8.mid)); + assert(!std::in_range(stup8.mid)); + assert(!std::in_range(-1)); + return true; +} + +template +constexpr bool test1(const std::tuple&) { + return (... && test_in_range()) && test_in_range1(); +} + +constexpr bool test() { + using Types1 = + std::tuple; + assert(test1(Types1{})); + return true; +} + +int main() { + + ASSERT_NOEXCEPT(std::in_range(std::declval())); + test(); + static_assert(test()); + return 0; +}