From patchwork Thu Oct 17 15:40:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1178766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511231-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Ueaz2erK"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46vCzT272Hz9sPc for ; Fri, 18 Oct 2019 02:40:19 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=QAkEh9K/XBSFaay6aBGYn7TVSrN3EhcHlSmmXU59LMOce3Ui0aWGj 9LE/8BLcENS8ICxDTKs4mhTyylZ2jXXxJXVYGnzPtrDStp8+disVnDnf8FSKCi0i UWkuwefpyQAm91t4pg6KuGQP6KYI0j0At4yHEbbc/0HlLwlyyStoxg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=Py/XUWrKj+ZTG1l7fxLLLlXobn4=; b=Ueaz2erKTmJe0SAyVOVl 39j7u6OsqjROuz2oj8xNEROLI5lmwH7su3bA26OYMciI9TL3GA75whrCYvV/oilj 9W7U11oWOkrgVNnMRrYWhjH8psjmdPOpP9s4mFRwc2auUGhVKpt5gQ82Be4qk2hE zI8PqH/G2et40B3PlF/d3us= Received: (qmail 69054 invoked by alias); 17 Oct 2019 15:40:10 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 68862 invoked by uid 89); 17 Oct 2019 15:40:10 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-16.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 Oct 2019 15:40:05 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3898411A30; Thu, 17 Oct 2019 15:40:04 +0000 (UTC) Received: from localhost (unknown [10.33.36.149]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8DD6A60872; Thu, 17 Oct 2019 15:40:03 +0000 (UTC) Date: Thu, 17 Oct 2019 16:40:02 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] Define [range.cmp] comparisons for C++20 Message-ID: <20191017154002.GK4169@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.12.1 (2019-06-15) 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. Tested powerpc64le-linux, committed to trunk. commit b948d3f92d7bbe4d53237cb20ff40a15fa123988 Author: Jonathan Wakely Date: Thu Oct 17 15:20:38 2019 +0100 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. 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/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(); +}