From: Jonathan Wakely Date: Thu, 17 Oct 2019 15:40:00 +0000 (+0100) Subject: Define [range.cmp] comparisons for C++20 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da8ddcec0c68a304fce64b102ba27e58c066a5c7;p=gcc.git Define [range.cmp] comparisons for C++20 Define std::identity, std::ranges::equal_to, std::ranges::not_equal_to, std::ranges::greater, std::ranges::less, std::ranges::greater_equal and std::ranges::less_equal. * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/range_cmp.h: New header for C++20 function objects. * include/std/functional: Include new header. * testsuite/20_util/function_objects/identity/1.cc: New test. * testsuite/20_util/function_objects/range.cmp/equal_to.cc: New test. * testsuite/20_util/function_objects/range.cmp/greater.cc: New test. * testsuite/20_util/function_objects/range.cmp/greater_equal.cc: New test. * testsuite/20_util/function_objects/range.cmp/less.cc: New test. * testsuite/20_util/function_objects/range.cmp/less_equal.cc: New test. * testsuite/20_util/function_objects/range.cmp/not_equal_to.cc: New test. From-SVN: r277120 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4c268795fdd..324955c692a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,19 @@ 2019-10-17 Jonathan Wakely + * include/Makefile.am: Add new header. + * include/Makefile.in: Regenerate. + * include/bits/range_cmp.h: New header for C++20 function objects. + * include/std/functional: Include new header. + * testsuite/20_util/function_objects/identity/1.cc: New test. + * testsuite/20_util/function_objects/range.cmp/equal_to.cc: New test. + * testsuite/20_util/function_objects/range.cmp/greater.cc: New test. + * testsuite/20_util/function_objects/range.cmp/greater_equal.cc: New + test. + * testsuite/20_util/function_objects/range.cmp/less.cc: New test. + * testsuite/20_util/function_objects/range.cmp/less_equal.cc: New test. + * testsuite/20_util/function_objects/range.cmp/not_equal_to.cc: New + test. + PR libstdc++/92124 * include/bits/forward_list.h (_M_move_assign(forward_list&&, false_type)): Do not use diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 35ee3cfcd34..9ff12f10fb1 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -152,6 +152,7 @@ bits_headers = \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ ${bits_srcdir}/range_access.h \ + ${bits_srcdir}/range_cmp.h \ ${bits_srcdir}/refwrap.h \ ${bits_srcdir}/regex.h \ ${bits_srcdir}/regex.tcc \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 5d0488846ff..5dce01faeda 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -496,6 +496,7 @@ bits_headers = \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ ${bits_srcdir}/range_access.h \ + ${bits_srcdir}/range_cmp.h \ ${bits_srcdir}/refwrap.h \ ${bits_srcdir}/regex.h \ ${bits_srcdir}/regex.tcc \ diff --git a/libstdc++-v3/include/bits/range_cmp.h b/libstdc++-v3/include/bits/range_cmp.h new file mode 100644 index 00000000000..3e5bb8847ab --- /dev/null +++ b/libstdc++-v3/include/bits/range_cmp.h @@ -0,0 +1,179 @@ +// Concept-constrained comparison implementations -*- C++ -*- + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file bits/ranges_function.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{functional} + */ + +#ifndef _RANGE_CMP_H +#define _RANGE_CMP_H 1 + +#if __cplusplus > 201703L +# include +# include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + struct __is_transparent; // not defined + + // Define std::identity here so that and + // don't need to include to get it. + + /// [func.identity] The identity function. + struct identity + { + template + constexpr _Tp&& + operator()(_Tp&& __t) const noexcept + { return std::forward<_Tp>(__t); } + + using is_transparent = __is_transparent; + }; + +namespace ranges +{ + namespace __detail + { + // BUILTIN-PTR-CMP(T, ==, U) + template + concept __eq_builtin_ptr_cmp + = convertible_to<_Tp, const volatile void*> + && convertible_to<_Up, const volatile void*> + && (! requires(_Tp&& __t, _Up&& __u) + { operator==(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } + && + ! requires(_Tp&& __t, _Up&& __u) + { std::forward<_Tp>(__t).operator==(std::forward<_Up>(__u)); }); + + // BUILTIN-PTR-CMP(T, <, U) + template + concept __less_builtin_ptr_cmp + = convertible_to<_Tp, const volatile void*> + && convertible_to<_Up, const volatile void*> + && (! requires(_Tp&& __t, _Up&& __u) + { operator<(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } + && ! requires(_Tp&& __t, _Up&& __u) + { std::forward<_Tp>(__t).operator<(std::forward<_Up>(__u)); }); + } // namespace __detail + + // [range.cmp] Concept-constrained comparisons + + /// ranges::equal_to function object type. + struct equal_to + { + template + requires equality_comparable_with<_Tp, _Up> + || __detail::__eq_builtin_ptr_cmp<_Tp, _Up> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>())) + { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } + + using is_transparent = __is_transparent; + }; + + /// ranges::not_equal_to function object type. + struct not_equal_to + { + template + requires equality_comparable_with<_Tp, _Up> + || __detail::__eq_builtin_ptr_cmp<_Tp, _Up> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Up>() == std::declval<_Tp>())) + { return !equal_to{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } + + using is_transparent = __is_transparent; + }; + + /// ranges::less function object type. + struct less + { + template + requires totally_ordered_with<_Tp, _Up> + || __detail::__less_builtin_ptr_cmp<_Tp, _Up> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>())) + { + if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>) + return std::less{}( + static_cast(std::forward<_Tp>(__t)), + static_cast(std::forward<_Up>(__u))); + return std::forward<_Tp>(__t) < std::forward<_Up>(__u); + } + + using is_transparent = __is_transparent; + }; + + /// ranges::greater function object type. + struct greater + { + template + requires totally_ordered_with<_Tp, _Up> + || __detail::__less_builtin_ptr_cmp<_Up, _Tp> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>())) + { return less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); } + + using is_transparent = __is_transparent; + }; + + /// ranges::greater_equal function object type. + struct greater_equal + { + template + requires totally_ordered_with<_Tp, _Up> + || __detail::__less_builtin_ptr_cmp<_Tp, _Up> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>())) + { return !less{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); } + + using is_transparent = __is_transparent; + }; + + /// ranges::less_equal function object type. + struct less_equal + { + template + requires totally_ordered_with<_Tp, _Up> + || __detail::__less_builtin_ptr_cmp<_Up, _Tp> + constexpr bool + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>())) + { return !less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); } + + using is_transparent = __is_transparent; + }; + +} // namespace ranges +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // C++20 +#endif // _RANGE_CMP_H diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 30576f23d35..7ad29a1a335 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -64,6 +64,9 @@ # include # include #endif +#if __cplusplus > 201703L +# include +#endif namespace std _GLIBCXX_VISIBILITY(default) { diff --git a/libstdc++-v3/testsuite/20_util/function_objects/identity/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/identity/1.cc new file mode 100644 index 00000000000..fd9b79f1fcd --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/identity/1.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +// C++20 [func.identity] +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( !std::is_invocable_v ); +static_assert( !std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +int i; +static_assert( std::addressof(std::identity{}(i)) == std::addressof(i) ); + +using T = std::identity::is_transparent; // required typedef diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc new file mode 100644 index 00000000000..c3ceb316a58 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc @@ -0,0 +1,77 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::equal_to; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( std::ranges::equal_to{}(99, 99.0) ); +static_assert( ! std::ranges::equal_to{}(99, 99.01) ); +static_assert( ! std::ranges::equal_to{}(99, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( f(&a, (void*)&a[0]) ); + VERIFY( ! f(&a, (void*)&a[1]) ); + VERIFY( f(&a + 1, (void*)(a + 2)) ); +} + +struct X { }; +int operator==(X, X) noexcept { return 2; } +int operator!=(X, X) { return 0; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater.cc new file mode 100644 index 00000000000..87fd518e146 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::greater; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( ! std::ranges::greater{}(99, 99.0) ); +static_assert( std::ranges::greater{}(99.01, 99) ); +static_assert( std::ranges::greater{}(990, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( ! f(&a, (void*)&a[0]) ); + VERIFY( f((void*)&a[1], &a) ); + VERIFY( f(&a + 1, (void*)(a + 1)) ); + VERIFY( ! f(&a, (void*)(a + 1)) ); +} + +struct X { }; +int operator==(X, X) { return 2; } +int operator!=(X, X) { return 0; } +int operator<(X, X) noexcept { return 0; } +int operator>(X, X) { return 0; } +int operator<=(X, X) { return 3; } +int operator>=(X, X) { return 4; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( ! f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater_equal.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater_equal.cc new file mode 100644 index 00000000000..a1972ab1c09 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/greater_equal.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::greater_equal; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( std::ranges::greater_equal{}(99, 99.0) ); +static_assert( std::ranges::greater_equal{}(99.01, 99) ); +static_assert( ! std::ranges::greater_equal{}(99, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( f(&a, (void*)&a[0]) ); + VERIFY( f((void*)&a[1], &a) ); + VERIFY( f(&a + 1, (void*)(a + 1)) ); + VERIFY( ! f(&a, (void*)(a + 1)) ); +} + +struct X { }; +int operator==(X, X) { return 2; } +int operator!=(X, X) { return 0; } +int operator<(X, X) noexcept { return 0; } +int operator>(X, X) { return 0; } +int operator<=(X, X) { return 3; } +int operator>=(X, X) { return 4; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc new file mode 100644 index 00000000000..e484628f76f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::less; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( ! std::ranges::less{}(99, 99.0) ); +static_assert( std::ranges::less{}(99, 99.01) ); +static_assert( std::ranges::less{}(99, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( ! f(&a, (void*)&a[0]) ); + VERIFY( f(&a, (void*)&a[1]) ); + VERIFY( ! f(&a + 1, (void*)(a + 2)) ); + VERIFY( f(&a, (void*)(a + 1)) ); +} + +struct X { }; +int operator==(X, X) { return 2; } +int operator!=(X, X) { return 0; } +int operator<(X, X) noexcept { return 0; } +int operator>(X, X) { return 0; } +int operator<=(X, X) { return 3; } +int operator>=(X, X) { return 4; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( ! f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less_equal.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less_equal.cc new file mode 100644 index 00000000000..7f5bee68eb4 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less_equal.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::less_equal; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( std::ranges::less_equal{}(99, 99.0) ); +static_assert( ! std::ranges::less_equal{}(99.01, 99) ); +static_assert( std::ranges::less_equal{}(99, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( f(&a, (void*)&a[0]) ); + VERIFY( ! f((void*)&a[1], &a) ); + VERIFY( ! f(&a + 1, (void*)(a + 1)) ); + VERIFY( f(&a, (void*)(a + 1)) ); +} + +struct X { }; +int operator==(X, X) { return 2; } +int operator!=(X, X) { return 0; } +int operator<(X, X) noexcept { return 0; } +int operator>(X, X) { return 0; } +int operator<=(X, X) { return 3; } +int operator>=(X, X) { return 4; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/not_equal_to.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/not_equal_to.cc new file mode 100644 index 00000000000..857e63426aa --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/not_equal_to.cc @@ -0,0 +1,77 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +// C++20 [range.cmp] + +using F = std::ranges::not_equal_to; +static_assert( std::is_default_constructible_v ); +static_assert( std::is_copy_constructible_v ); +static_assert( std::is_move_constructible_v ); +static_assert( std::is_copy_assignable_v ); +static_assert( std::is_move_assignable_v ); + +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( ! std::is_invocable_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); +static_assert( std::is_nothrow_invocable_r_v ); + +using T = F::is_transparent; // required typedef + +static_assert( ! std::ranges::not_equal_to{}(99, 99.0) ); +static_assert( std::ranges::not_equal_to{}(99, 99.01) ); +static_assert( std::ranges::not_equal_to{}(99, 140L) ); + +void +test01() +{ + F f; + int a[2]{}; + VERIFY( ! f(&a, (void*)&a[0]) ); + VERIFY( f(&a, (void*)&a[1]) ); + VERIFY( ! f(&a + 1, (void*)(a + 2)) ); +} + +struct X { }; +int operator==(X, X) noexcept { return 2; } +int operator!=(X, X) { return 0; } + +static_assert( std::is_nothrow_invocable_r_v ); + +void +test02() +{ + X x; + F f; + VERIFY( ! f(x, x) ); +} + +int +main() +{ + test01(); + test02(); +}