Commit da8ddcec by Jonathan Wakely Committed by Jonathan Wakely

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
parent 4c3784ae
2019-10-17 Jonathan Wakely <jwakely@redhat.com>
* 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
......
......@@ -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 \
......
......@@ -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 \
......
// 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
// <http://www.gnu.org/licenses/>.
/** @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 <bits/move.h>
# include <concepts>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_transparent; // not defined
// Define std::identity here so that <iterator> and <ranges>
// don't need to include <bits/stl_function.h> to get it.
/// [func.identity] The identity function.
struct identity
{
template<typename _Tp>
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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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<const volatile void*>{}(
static_cast<const volatile void*>(std::forward<_Tp>(__t)),
static_cast<const volatile void*>(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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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<typename _Tp, typename _Up>
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
......@@ -64,6 +64,9 @@
# include <utility>
# include <bits/stl_algo.h>
#endif
#if __cplusplus > 201703L
# include <bits/range_cmp.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
......
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
#include <functional>
// C++20 [func.identity]
static_assert( std::is_default_constructible_v<std::identity> );
static_assert( std::is_copy_constructible_v<std::identity> );
static_assert( std::is_move_constructible_v<std::identity> );
static_assert( std::is_copy_assignable_v<std::identity> );
static_assert( std::is_move_assignable_v<std::identity> );
static_assert( !std::is_invocable_v<std::identity> );
static_assert( !std::is_invocable_v<std::identity, int&, int&> );
static_assert( std::is_nothrow_invocable_r_v<int&, std::identity&, int&> );
static_assert( std::is_nothrow_invocable_r_v<const long&, std::identity, const long&> );
static_assert( std::is_nothrow_invocable_r_v<short&&, const std::identity&, short> );
static_assert( std::is_nothrow_invocable_r_v<const char&&, const std::identity, const char> );
int i;
static_assert( std::addressof(std::identity{}(i)) == std::addressof(i) );
using T = std::identity::is_transparent; // required typedef
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::equal_to;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( f(x, x) );
}
int
main()
{
test01();
test02();
}
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::greater;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( ! f(x, x) );
}
int
main()
{
test01();
test02();
}
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::greater_equal;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( f(x, x) );
}
int
main()
{
test01();
test02();
}
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::less;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( ! f(x, x) );
}
int
main()
{
test01();
test02();
}
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::less_equal;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( f(x, x) );
}
int
main()
{
test01();
test02();
}
// 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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <functional>
#include <testsuite_hooks.h>
// C++20 [range.cmp]
using F = std::ranges::not_equal_to;
static_assert( std::is_default_constructible_v<F> );
static_assert( std::is_copy_constructible_v<F> );
static_assert( std::is_move_constructible_v<F> );
static_assert( std::is_copy_assignable_v<F> );
static_assert( std::is_move_assignable_v<F> );
static_assert( ! std::is_invocable_v<F> );
static_assert( ! std::is_invocable_v<F, int&> );
static_assert( ! std::is_invocable_v<F, int, void> );
static_assert( ! std::is_invocable_v<F, int, void*> );
static_assert( std::is_nothrow_invocable_r_v<bool, F&, int&, int> );
static_assert( std::is_nothrow_invocable_r_v<bool, F, const long&, char> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F&, short, int&> );
static_assert( std::is_nothrow_invocable_r_v<bool, const F, const char, char> );
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<bool, F&, X, X> );
void
test02()
{
X x;
F f;
VERIFY( ! f(x, x) );
}
int
main()
{
test01();
test02();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment