From patchwork Fri Feb 14 15:35:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1238126 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-519548-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.a=rsa-sha1 header.s=default header.b=iCXNI8wY; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ib2x9Weo; 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 48JyDq6Mvxz9sRQ for ; Sat, 15 Feb 2020 02:37:31 +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:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; q=dns; s= default; b=WA7eOtrIkk9johvWpY0vyD9tPNaMa2urBivOVoLfRFB5o/GT6iea7 dzQgHoan7azOwElUSxJ0iPTKCmbZ0N41gv/040vl0kvcrSaTpvVYIHs/r9z37Fw+ 80DIG4kJ9+n2FT5Vvn9Mw3OjoR5HgOJqllh4Kj/xU6HpjlvsbbSUCU= 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:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=default; bh=rJJh9j8MGL5aoGAbR24Q62h/ezE=; b=iCXNI8wYAB8QdoA2orZxgRC95GIR 6+dZ7NTC0qedZKVIwvCs9Km8gEV4ETByJHEI0q/qi2hP0zLJoIwqoFYCRZ9MwEwB xdvJnASMQh2OfDvuAxBo4ZNrrXTbv54MloOdnKoufwtUEgZ49Ev2qkS/7C+o5srL aboqpYzReSyS6Ac= Received: (qmail 110878 invoked by alias); 14 Feb 2020 15:36:24 -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 110701 invoked by uid 89); 14 Feb 2020 15:36:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=vim, 22017, move_result, sk:move_ba X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Feb 2020 15:36:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581694562; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ypJq0Yrw3wbBlF+Eh7J9gDvJ2dshbN3jUMHEX0u3cg4=; b=ib2x9WeoAzu2VlaqucTva6tB2btyOsWK7R048JTCt/moNmZfzLtrRYh7kopgg2bwDzh0BX u0tz76VzdD4daBZdTpd5Z2D7D5Nz1We52SvdOLMDE3/651uBkKkj6U/v1BM04WIOPcjlv7 RcMIw/99pJcc49JkbQCuHTg75ObwIW0= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-361--wd9M8USNfeqTXu9LOqOhg-1; Fri, 14 Feb 2020 10:35:59 -0500 Received: by mail-qk1-f198.google.com with SMTP id e11so6393219qkl.8 for ; Fri, 14 Feb 2020 07:35:59 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id n7sm3364919qkk.41.2020.02.14.07.35.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 07:35:54 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org, jwakely@redhat.com, Patrick Palka Subject: [PATCH 2/3] libstdc++: Convert the ranges algorithm entities into function objects Date: Fri, 14 Feb 2020 10:35:46 -0500 Message-Id: <20200214153547.2390767-2-ppalka@redhat.com> In-Reply-To: <20200214153547.2390767-1-ppalka@redhat.com> References: <20200214153547.2390767-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-IsSubscribed: yes This is the standard way to inhibit ADL for these entities, which is required as per [algorithms.requirements] p2 and [specialized.algorithms] p4. The conversion was done mostly mechanically with a custom Vim macro. [ To make it easier to review, the diffstat below was generated with the -w flag, which ignores all changes to whitespace. Formatting will be fixed in a subsequent patch. ] libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h: (adjacent_find, all_of, any_of, binary_search, copy_if, count, count_if, equal_range, find, find_end, find_first_of, find_if, find_if_not, for_each, generate, generate_n, includes, inplace_merge, is_heap, is_heap_until, is_partitioned, is_permutation, is_sorted, is_sorted_until, lexicographical_compare, lower_bound, make_heap, max, max_element, merge, min, min_element, minmax, minmax_element, mismatch, next_permutation, none_of, nth_element, partial_sort, partial_sort_copy, partition, partition_copy, partition_point, pop_heap, prev_permutation, push_heap, remove, remove_copy, remove_copy_if, remove_if, replace, replace_copy, replace_copy_if, replace_if, reverse, reverse_copy, rotate, rotate_copy, search, search_n, set_difference, set_intersection, set_symmetric_difference, set_union, shuffle, sort, sort_heap, stable_partition, stable_sort, swap_ranges, transform, unique, unique_copy, upper_bound): Convert into function objects. * include/bits/ranges_algobase.h: (equal, copy, move, copy_n, fill_n, fill, move_backward, copy_backward): Likewise. * include/bits/ranges_uninitialized.h (uninitialized_default_construct, uninitialized_default_construct_n, uninitialized_value_construct, uninitialized_value_construct_n, uninitialized_copy, uninitialized_copy_n, uninitialized_move, uninitialized_move_n, uninitialized_fill, uninitialized_fill_n, construct_at, destroy_at, destroy, destroy_n): Likewise. --- libstdc++-v3/include/bits/ranges_algo.h | 1019 +++++++++++------ libstdc++-v3/include/bits/ranges_algobase.h | 86 +- .../include/bits/ranges_uninitialized.h | 145 ++- 3 files changed, 868 insertions(+), 382 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 6b6f4defdf5..af6d1722998 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -67,11 +67,13 @@ namespace ranges } } // namespace __detail + struct __all_of_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr bool - all_of(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -82,17 +84,22 @@ namespace ranges template, _Proj>> _Pred> constexpr bool - all_of(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::all_of(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __all_of_fn all_of{}; + struct __any_of_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr bool - any_of(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -103,17 +110,22 @@ namespace ranges template, _Proj>> _Pred> constexpr bool - any_of(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::any_of(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __any_of_fn any_of{}; + + struct __none_of_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr bool - none_of(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -124,11 +136,14 @@ namespace ranges template, _Proj>> _Pred> constexpr bool - none_of(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::none_of(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __none_of_fn none_of{}; template struct for_each_result @@ -148,11 +163,13 @@ namespace ranges { return {std::move(in), std::move(fun)}; } }; + struct __for_each_fn + { template _Sent, typename _Proj = identity, indirectly_unary_invocable> _Fun> constexpr for_each_result<_Iter, _Fun> - for_each(_Iter __first, _Sent __last, _Fun __f, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Fun __f, _Proj __proj = {}) const { for (; __first != __last; ++__first) std::__invoke(__f, std::__invoke(__proj, *__first)); @@ -163,18 +180,23 @@ namespace ranges indirectly_unary_invocable, _Proj>> _Fun> constexpr for_each_result, _Fun> - for_each(_Range&& __r, _Fun __f, _Proj __proj = {}) + operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const { - return ranges::for_each(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__f), std::move(__proj)); } + }; + inline constexpr __for_each_fn for_each{}; + + struct __find_fn + { template _Sent, typename _Tp, typename _Proj = identity> requires indirect_binary_predicate, const _Tp*> constexpr _Iter - find(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const { while (__first != __last && !(std::__invoke(__proj, *__first) == __value)) @@ -187,17 +209,22 @@ namespace ranges projected, _Proj>, const _Tp*> constexpr safe_iterator_t<_Range> - find(_Range&& __r, const _Tp& __value, _Proj __proj = {}) + operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const { - return ranges::find(ranges::begin(__r), ranges::end(__r), __value, + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); } + }; + + inline constexpr __find_fn find{}; + struct __find_if_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr _Iter - find_if(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { while (__first != __last && !(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -209,17 +236,22 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> constexpr safe_iterator_t<_Range> - find_if(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::find_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __find_if_fn find_if{}; + + struct __find_if_not_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr _Iter - find_if_not(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { while (__first != __last && (bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -231,21 +263,26 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> constexpr safe_iterator_t<_Range> - find_if_not(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::find_if_not(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __find_if_not_fn find_if_not{}; + + struct __find_first_of_fn + { template _Sent1, forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Pred = ranges::equal_to, typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> constexpr _Iter1 - find_first_of(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { for (; __first1 != __last1; ++__first1) for (auto __iter = __first2; __iter != __last2; ++__iter) @@ -262,22 +299,27 @@ namespace ranges requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> constexpr safe_iterator_t<_Range1> - find_first_of(_Range1&& __r1, _Range2&& __r2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::find_first_of(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __find_first_of_fn find_first_of{}; + struct __count_fn + { template _Sent, typename _Tp, typename _Proj = identity> requires indirect_binary_predicate, const _Tp*> constexpr iter_difference_t<_Iter> - count(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const { iter_difference_t<_Iter> __n = 0; for (; __first != __last; ++__first) @@ -291,17 +333,22 @@ namespace ranges projected, _Proj>, const _Tp*> constexpr range_difference_t<_Range> - count(_Range&& __r, const _Tp& __value, _Proj __proj = {}) + operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const { - return ranges::count(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); } + }; + inline constexpr __count_fn count{}; + + struct __count_if_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr iter_difference_t<_Iter> - count_if(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { iter_difference_t<_Iter> __n = 0; for (; __first != __last; ++__first) @@ -314,11 +361,14 @@ namespace ranges typename _Proj = identity, indirect_unary_predicate, _Proj>> _Pred> constexpr range_difference_t<_Range> - count_if(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::count_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __count_if_fn count_if{}; template struct mismatch_result @@ -339,14 +389,16 @@ namespace ranges { return {std::move(in1), std::move(in2)}; } }; + struct __mismatch_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Pred = ranges::equal_to, typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> constexpr mismatch_result<_Iter1, _Iter2> - mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2 && (bool)std::__invoke(__pred, @@ -365,23 +417,28 @@ namespace ranges requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> constexpr mismatch_result, iterator_t<_Range2>> - mismatch(_Range1&& __r1, _Range2&& __r2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::mismatch(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + inline constexpr __mismatch_fn mismatch{}; + + struct __search_fn + { template _Sent1, forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Pred = ranges::equal_to, typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> constexpr subrange<_Iter1> - search(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if (__first1 == __last1 || __first2 == __last2) return {__first1, __first1}; @@ -423,21 +480,26 @@ namespace ranges requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> constexpr safe_subrange_t<_Range1> - search(_Range1&& __r1, _Range2&& __r2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::search(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __search_fn search{}; + struct __search_n_fn + { template _Sent, typename _Tp, typename _Pred = ranges::equal_to, typename _Proj = identity> requires indirectly_comparable<_Iter, const _Tp*, _Pred, _Proj> constexpr subrange<_Iter> - search_n(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count, - const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count, + const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const { if (__count <= 0) return {__first, __first}; @@ -505,25 +567,28 @@ namespace ranges typename _Pred = ranges::equal_to, typename _Proj = identity> requires indirectly_comparable, const _Tp*, _Pred, _Proj> constexpr safe_subrange_t<_Range> - search_n(_Range&& __r, range_difference_t<_Range> __count, - const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) + operator()(_Range&& __r, range_difference_t<_Range> __count, + const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const { - return ranges::search_n(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__count), __value, std::move(__pred), std::move(__proj)); } + }; + inline constexpr __search_n_fn search_n{}; - + struct __find_end_fn + { template _Sent1, forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Pred = ranges::equal_to, typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> constexpr subrange<_Iter1> - find_end(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (bidirectional_iterator<_Iter1> && bidirectional_iterator<_Iter2>) @@ -578,23 +643,28 @@ namespace ranges requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> constexpr safe_subrange_t<_Range1> - find_end(_Range1&& __r1, _Range2&& __r2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::find_end(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + inline constexpr __find_end_fn find_end{}; + + struct __adjacent_find_fn + { template _Sent, typename _Proj = identity, indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> constexpr _Iter - adjacent_find(_Iter __first, _Sent __last, - _Pred __pred = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Pred __pred = {}, _Proj __proj = {}) const { if (__first == __last) return __first; @@ -614,12 +684,17 @@ namespace ranges projected, _Proj>, projected, _Proj>> _Pred = ranges::equal_to> constexpr safe_iterator_t<_Range> - adjacent_find(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const { - return ranges::adjacent_find(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __adjacent_find_fn adjacent_find{}; + struct __is_permutation_fn + { template _Sent1, forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Proj1 = identity, typename _Proj2 = identity, @@ -627,9 +702,9 @@ namespace ranges projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> constexpr bool - is_permutation(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { constexpr bool __sized_iters = (sized_sentinel_for<_Sent1, _Iter1> @@ -693,25 +768,30 @@ namespace ranges projected, _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> constexpr bool - is_permutation(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::is_permutation(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __is_permutation_fn is_permutation{}; template using copy_if_result = copy_result<_Iter, _Out>; + struct __copy_if_fn + { template _Sent, weakly_incrementable _Out, typename _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_copyable<_Iter, _Out> constexpr copy_if_result<_Iter, _Out> - copy_if(_Iter __first, _Sent __last, _Out __result, - _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Out __result, + _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -727,22 +807,27 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> constexpr copy_if_result, _Out> - copy_if(_Range&& __r, _Out __result, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, _Pred __pred, _Proj __proj = {}) const { - return ranges::copy_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __copy_if_fn copy_if{}; template using swap_ranges_result = mismatch_result<_Iter1, _Iter2>; + struct __swap_ranges_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2> requires indirectly_swappable<_Iter1, _Iter2> constexpr swap_ranges_result<_Iter1, _Iter2> - swap_ranges(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2) + operator()(_Iter1 __first1, _Sent1 __last1, + _Iter2 __first2, _Sent2 __last2) const { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) @@ -754,15 +839,42 @@ namespace ranges requires indirectly_swappable, iterator_t<_Range2>> constexpr swap_ranges_result, safe_iterator_t<_Range2>> - swap_ranges(_Range1&& __r1, _Range2&& __r2) + operator()(_Range1&& __r1, _Range2&& __r2) const { - return ranges::swap_ranges(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2)); } + }; + + inline constexpr __swap_ranges_fn swap_ranges{}; template using unary_transform_result = copy_result<_Iter, _Out>; + template + struct binary_transform_result + { + [[no_unique_address]] _Iter1 in1; + [[no_unique_address]] _Iter2 in2; + [[no_unique_address]] _Out out; + + template + requires convertible_to + && convertible_to + && convertible_to + operator binary_transform_result<_IIter1, _IIter2, _OOut>() const & + { return {in1, in2, out}; } + + template + requires convertible_to<_Iter1, _IIter1> + && convertible_to<_Iter2, _IIter2> + && convertible_to<_Out, _OOut> + operator binary_transform_result<_IIter1, _IIter2, _OOut>() && + { return {std::move(in1), std::move(in2), std::move(out)}; } + }; + + struct __transform_fn + { template _Sent, weakly_incrementable _Out, copy_constructible _Fp, typename _Proj = identity> @@ -770,8 +882,8 @@ namespace ranges indirect_result_t<_Fp&, projected<_Iter, _Proj>>> constexpr unary_transform_result<_Iter, _Out> - transform(_Iter __first1, _Sent __last1, _Out __result, - _Fp __op, _Proj __proj = {}) + operator()(_Iter __first1, _Sent __last1, _Out __result, + _Fp __op, _Proj __proj = {}) const { for (; __first1 != __last1; ++__first1, (void)++__result) *__result = std::__invoke(__op, std::__invoke(__proj, *__first1)); @@ -784,35 +896,13 @@ namespace ranges indirect_result_t<_Fp&, projected, _Proj>>> constexpr unary_transform_result, _Out> - transform(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const { - return ranges::transform(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), std::move(__op), std::move(__proj)); } - template - struct binary_transform_result - { - [[no_unique_address]] _Iter1 in1; - [[no_unique_address]] _Iter2 in2; - [[no_unique_address]] _Out out; - - template - requires convertible_to - && convertible_to - && convertible_to - operator binary_transform_result<_IIter1, _IIter2, _OOut>() const & - { return {in1, in2, out}; } - - template - requires convertible_to<_Iter1, _IIter1> - && convertible_to<_Iter2, _IIter2> - && convertible_to<_Out, _OOut> - operator binary_transform_result<_IIter1, _IIter2, _OOut>() && - { return {std::move(in1), std::move(in2), std::move(out)}; } - }; - template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, copy_constructible _Fp, @@ -822,9 +912,9 @@ namespace ranges projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>>> constexpr binary_transform_result<_Iter1, _Iter2, _Out> - transform(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, _Fp __binary_op, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2, ++__result) @@ -843,24 +933,29 @@ namespace ranges projected, _Proj2>>> constexpr binary_transform_result, safe_iterator_t<_Range2>, _Out> - transform(_Range1&& __r1, _Range2&& __r2, _Out __result, - _Fp __binary_op, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, + _Fp __binary_op, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::transform(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__binary_op), std::move(__proj1), std::move(__proj2)); } + }; + inline constexpr __transform_fn transform{}; + + struct __replace_fn + { template _Sent, typename _Tp1, typename _Tp2, typename _Proj = identity> requires indirectly_writable<_Iter, const _Tp2&> && indirect_binary_predicate, const _Tp1*> constexpr _Iter - replace(_Iter __first, _Sent __last, + operator()(_Iter __first, _Sent __last, const _Tp1& __old_value, const _Tp2& __new_value, - _Proj __proj = {}) + _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__proj, *__first) == __old_value) @@ -875,21 +970,26 @@ namespace ranges projected, _Proj>, const _Tp1*> constexpr safe_iterator_t<_Range> - replace(_Range&& __r, + operator()(_Range&& __r, const _Tp1& __old_value, const _Tp2& __new_value, - _Proj __proj = {}) + _Proj __proj = {}) const { - return ranges::replace(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __old_value, __new_value, std::move(__proj)); } + }; + + inline constexpr __replace_fn replace{}; + struct __replace_if_fn + { template _Sent, typename _Tp, typename _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_writable<_Iter, const _Tp&> constexpr _Iter - replace_if(_Iter __first, _Sent __last, - _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -901,17 +1001,22 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_writable, const _Tp&> constexpr safe_iterator_t<_Range> - replace_if(_Range&& __r, - _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) + operator()(_Range&& __r, + _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { - return ranges::replace_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), __new_value, std::move(__proj)); } + }; + + inline constexpr __replace_if_fn replace_if{}; template using replace_copy_result = copy_result<_Iter, _Out>; + struct __replace_copy_fn + { template _Sent, typename _Tp1, typename _Tp2, output_iterator _Out, typename _Proj = identity> @@ -919,9 +1024,9 @@ namespace ranges && indirect_binary_predicate, const _Tp1*> constexpr replace_copy_result<_Iter, _Out> - replace_copy(_Iter __first, _Sent __last, _Out __result, + operator()(_Iter __first, _Sent __last, _Out __result, const _Tp1& __old_value, const _Tp2& __new_value, - _Proj __proj = {}) + _Proj __proj = {}) const { for (; __first != __last; ++__first, (void)++__result) if (std::__invoke(__proj, *__first) == __old_value) @@ -938,26 +1043,31 @@ namespace ranges projected, _Proj>, const _Tp1*> constexpr replace_copy_result, _Out> - replace_copy(_Range&& __r, _Out __result, + operator()(_Range&& __r, _Out __result, const _Tp1& __old_value, const _Tp2& __new_value, - _Proj __proj = {}) + _Proj __proj = {}) const { - return ranges::replace_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), __old_value, __new_value, std::move(__proj)); } + }; + + inline constexpr __replace_copy_fn replace_copy{}; template using replace_copy_if_result = copy_result<_Iter, _Out>; + struct __replace_copy_if_fn + { template _Sent, typename _Tp, output_iterator _Out, typename _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_copyable<_Iter, _Out> constexpr replace_copy_if_result<_Iter, _Out> - replace_copy_if(_Iter __first, _Sent __last, _Out __result, - _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Out __result, + _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { for (; __first != __last; ++__first, (void)++__result) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -973,31 +1083,41 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> constexpr replace_copy_if_result, _Out> - replace_copy_if(_Range&& __r, _Out __result, - _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, + _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { - return ranges::replace_copy_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), std::move(__pred), __new_value, std::move(__proj)); } + }; + + inline constexpr __replace_copy_if_fn replace_copy_if{}; + struct __generate_n_fn + { template requires invocable<_Fp&> && indirectly_writable<_Out, invoke_result_t<_Fp&>> constexpr _Out - generate_n(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) + operator()(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) const { for (; __n > 0; --__n, (void)++__first) *__first = std::__invoke(__gen); return __first; } + }; + inline constexpr __generate_n_fn generate_n{}; + + struct __generate_fn + { template _Sent, copy_constructible _Fp> requires invocable<_Fp&> && indirectly_writable<_Out, invoke_result_t<_Fp&>> constexpr _Out - generate(_Out __first, _Sent __last, _Fp __gen) + operator()(_Out __first, _Sent __last, _Fp __gen) const { for (; __first != __last; ++__first) *__first = std::__invoke(__gen); @@ -1007,17 +1127,22 @@ namespace ranges template requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>> constexpr safe_iterator_t<_Range> - generate(_Range&& __r, _Fp __gen) + operator()(_Range&& __r, _Fp __gen) const { - return ranges::generate(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen)); } + }; + + inline constexpr __generate_fn generate{}; + struct __remove_if_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr subrange<_Iter> - remove_if(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { __first = ranges::find_if(__first, __last, __pred, __proj); if (__first == __last) @@ -1039,19 +1164,24 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> constexpr safe_subrange_t<_Range> - remove_if(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::remove_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __remove_if_fn remove_if{}; + + struct __remove_fn + { template _Sent, typename _Tp, typename _Proj = identity> requires indirect_binary_predicate, const _Tp*> constexpr subrange<_Iter> - remove(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const { auto __pred = [&] (auto&& __arg) { return std::forward(__arg) == __value; @@ -1066,22 +1196,27 @@ namespace ranges projected, _Proj>, const _Tp*> constexpr safe_subrange_t<_Range> - remove(_Range&& __r, const _Tp& __value, _Proj __proj = {}) + operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const { - return ranges::remove(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__proj)); } + }; + + inline constexpr __remove_fn remove{}; template using remove_copy_if_result = copy_result<_Iter, _Out>; + struct __remove_copy_if_fn + { template _Sent, weakly_incrementable _Out, typename _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_copyable<_Iter, _Out> constexpr remove_copy_if_result<_Iter, _Out> - remove_copy_if(_Iter __first, _Sent __last, _Out __result, - _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Out __result, + _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -1097,17 +1232,22 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> constexpr remove_copy_if_result, _Out> - remove_copy_if(_Range&& __r, _Out __result, - _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, + _Pred __pred, _Proj __proj = {}) const { - return ranges::remove_copy_if(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __remove_copy_if_fn remove_copy_if{}; template using remove_copy_result = copy_result<_Iter, _Out>; + struct __remove_copy_fn + { template _Sent, weakly_incrementable _Out, typename _Tp, typename _Proj = identity> requires indirectly_copyable<_Iter, _Out> @@ -1115,8 +1255,8 @@ namespace ranges projected<_Iter, _Proj>, const _Tp*> constexpr remove_copy_result<_Iter, _Out> - remove_copy(_Iter __first, _Sent __last, _Out __result, - const _Tp& __value, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Out __result, + const _Tp& __value, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (!(std::__invoke(__proj, *__first) == __value)) @@ -1134,21 +1274,25 @@ namespace ranges projected, _Proj>, const _Tp*> constexpr remove_copy_result, _Out> - remove_copy(_Range&& __r, _Out __result, - const _Tp& __value, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, + const _Tp& __value, _Proj __proj = {}) const { - return ranges::remove_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), __value, std::move(__proj)); - } + }; + inline constexpr __remove_copy_fn remove_copy{}; + + struct __unique_fn + { template _Sent, typename _Proj = identity, indirect_equivalence_relation< projected<_Iter, _Proj>> _Comp = ranges::equal_to> constexpr subrange<_Iter> - unique(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { __first = ranges::adjacent_find(__first, __last, __comp, __proj); if (__first == __last) @@ -1169,15 +1313,20 @@ namespace ranges projected, _Proj>> _Comp = ranges::equal_to> requires permutable> constexpr safe_subrange_t<_Range> - unique(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::unique(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __unique_fn unique{}; template using unique_copy_result = copy_result<_Iter, _Out>; + struct __unique_copy_fn + { template _Sent, weakly_incrementable _Out, typename _Proj = identity, indirect_equivalence_relation< @@ -1188,8 +1337,8 @@ namespace ranges && same_as, iter_value_t<_Out>>) || indirectly_copyable_storable<_Iter, _Out>) constexpr unique_copy_result<_Iter, _Out> - unique_copy(_Iter __first, _Sent __last, _Out __result, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Out __result, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return {std::move(__first), std::move(__result)}; @@ -1248,18 +1397,23 @@ namespace ranges && same_as, iter_value_t<_Out>>) || indirectly_copyable_storable, _Out>) constexpr unique_copy_result, _Out> - unique_copy(_Range&& __r, _Out __result, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Out __result, + _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::unique_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __unique_copy_fn unique_copy{}; + struct __reverse_fn + { template _Sent> requires permutable<_Iter> constexpr _Iter - reverse(_Iter __first, _Sent __last) + operator()(_Iter __first, _Sent __last) const { auto __i = ranges::next(__first, __last); auto __tail = __i; @@ -1295,19 +1449,24 @@ namespace ranges template requires permutable> constexpr safe_iterator_t<_Range> - reverse(_Range&& __r) + operator()(_Range&& __r) const { - return ranges::reverse(ranges::begin(__r), ranges::end(__r)); + return (*this)(ranges::begin(__r), ranges::end(__r)); } + }; + + inline constexpr __reverse_fn reverse{}; template using reverse_copy_result = copy_result<_Iter, _Out>; + struct __reverse_copy_fn + { template _Sent, weakly_incrementable _Out> requires indirectly_copyable<_Iter, _Out> constexpr reverse_copy_result<_Iter, _Out> - reverse_copy(_Iter __first, _Sent __last, _Out __result) + operator()(_Iter __first, _Sent __last, _Out __result) const { auto __i = ranges::next(__first, __last); auto __tail = __i; @@ -1323,15 +1482,20 @@ namespace ranges template requires indirectly_copyable, _Out> constexpr reverse_copy_result, _Out> - reverse_copy(_Range&& __r, _Out __result) + operator()(_Range&& __r, _Out __result) const { - return ranges::reverse_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __reverse_copy_fn reverse_copy{}; + struct __rotate_fn + { template _Sent> constexpr subrange<_Iter> - rotate(_Iter __first, _Iter __middle, _Sent __last) + operator()(_Iter __first, _Iter __middle, _Sent __last) const { auto __lasti = ranges::next(__first, __last); if (__first == __middle) @@ -1465,21 +1629,26 @@ namespace ranges template requires permutable> constexpr safe_subrange_t<_Range> - rotate(_Range&& __r, iterator_t<_Range> __middle) + operator()(_Range&& __r, iterator_t<_Range> __middle) const { - return ranges::rotate(ranges::begin(__r), + return (*this)(ranges::begin(__r), std::move(__middle), ranges::end(__r)); } + }; + + inline constexpr __rotate_fn rotate{}; template using rotate_copy_result = copy_result<_Iter, _Out>; + struct __rotate_copy_fn + { template _Sent, weakly_incrementable _Out> requires indirectly_copyable<_Iter, _Out> constexpr rotate_copy_result<_Iter, _Out> - rotate_copy(_Iter __first, _Iter __middle, _Sent __last, _Out __result) + operator()(_Iter __first, _Iter __middle, _Sent __last, _Out __result) const { auto __copy1 = ranges::copy(__middle, std::move(__last), @@ -1493,21 +1662,26 @@ namespace ranges template requires indirectly_copyable, _Out> constexpr rotate_copy_result, _Out> - rotate_copy(_Range&& __r, iterator_t<_Range> __middle, _Out __result) + operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const { - return ranges::rotate_copy(ranges::begin(__r), + return (*this)(ranges::begin(__r), std::move(__middle), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __rotate_copy_fn rotate_copy{}; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 + struct __shuffle_fn + { template _Sent, typename _Gen> requires permutable<_Iter> && uniform_random_bit_generator> _Iter - shuffle(_Iter __first, _Sent __last, _Gen&& __g) + operator()(_Iter __first, _Sent __last, _Gen&& __g) const { auto __lasti = ranges::next(__first, __last); std::shuffle(std::move(__first), __lasti, std::forward<_Gen>(__g)); @@ -1518,18 +1692,23 @@ namespace ranges requires permutable> && uniform_random_bit_generator> safe_iterator_t<_Range> - shuffle(_Range&& __r, _Gen&& __g) + operator()(_Range&& __r, _Gen&& __g) const { - return ranges::shuffle(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::forward<_Gen>(__g)); } + }; + + inline constexpr __shuffle_fn shuffle{}; #endif + struct __push_heap_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - push_heap(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::push_heap(__first, __lasti, @@ -1541,17 +1720,22 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - push_heap(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::push_heap(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __push_heap_fn push_heap{}; + + struct __pop_heap_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - pop_heap(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::pop_heap(__first, __lasti, @@ -1563,17 +1747,22 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - pop_heap(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::pop_heap(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __pop_heap_fn pop_heap{}; + struct __make_heap_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - make_heap(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::make_heap(__first, __lasti, @@ -1585,17 +1774,22 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - make_heap(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::make_heap(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __make_heap_fn make_heap{}; + + struct __sort_heap_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - sort_heap(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::sort_heap(__first, __lasti, @@ -1607,19 +1801,24 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - sort_heap(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::sort_heap(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __sort_heap_fn sort_heap{}; + struct __is_heap_until_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - is_heap_until(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { iter_difference_t<_Iter> __n = ranges::distance(__first, __last); iter_difference_t<_Iter> __parent = 0, __child = 1; @@ -1639,18 +1838,23 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - is_heap_until(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::is_heap_until(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __is_heap_until_fn is_heap_until{}; + + struct __is_heap_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr bool - is_heap(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return (__last == ranges::is_heap_until(__first, __last, @@ -1663,17 +1867,22 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr bool - is_heap(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::is_heap(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __is_heap_fn is_heap{}; + struct __sort_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - sort(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::sort(std::move(__first), __lasti, @@ -1685,18 +1894,23 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - sort(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::sort(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __sort_fn sort{}; + struct __stable_sort_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> _Iter - stable_sort(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::stable_sort(std::move(__first), __lasti, @@ -1708,18 +1922,23 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> safe_iterator_t<_Range> - stable_sort(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::stable_sort(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __stable_sort_fn stable_sort{}; + + struct __partial_sort_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - partial_sort(_Iter __first, _Iter __middle, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Iter __middle, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __middle) return ranges::next(__first, __last); @@ -1744,18 +1963,23 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - partial_sort(_Range&& __r, iterator_t<_Range> __middle, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, iterator_t<_Range> __middle, + _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::partial_sort(ranges::begin(__r), + return (*this)(ranges::begin(__r), std::move(__middle), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __partial_sort_fn partial_sort{}; template using partial_sort_copy_result = copy_result<_Iter, _Out>; + struct __partial_sort_copy_fn + { template _Sent1, random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Comp = ranges::less, @@ -1766,10 +1990,10 @@ namespace ranges projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> constexpr partial_sort_copy_result<_Iter1, _Iter2> - partial_sort_copy(_Iter1 __first, _Sent1 __last, + operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if (__result_first == __result_last) { @@ -1814,22 +2038,27 @@ namespace ranges projected, _Proj2>> constexpr partial_sort_copy_result, safe_iterator_t<_Range2>> - partial_sort_copy(_Range1&& __r, _Range2&& __out, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::partial_sort_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), ranges::begin(__out), ranges::end(__out), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + inline constexpr __partial_sort_copy_fn partial_sort_copy{}; + + struct __is_sorted_until_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - is_sorted_until(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return __first; @@ -1847,18 +2076,23 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - is_sorted_until(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::is_sorted_until(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __is_sorted_until_fn is_sorted_until{}; + struct __is_sorted_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr bool - is_sorted(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return true; @@ -1876,18 +2110,23 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr bool - is_sorted(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::is_sorted(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __is_sorted_fn is_sorted{}; + + struct __nth_element_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr _Iter - nth_element(_Iter __first, _Iter __nth, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Iter __nth, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::nth_element(std::move(__first), std::move(__nth), __lasti, @@ -1899,21 +2138,26 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr safe_iterator_t<_Range> - nth_element(_Range&& __r, iterator_t<_Range> __nth, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, iterator_t<_Range> __nth, + _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::nth_element(ranges::begin(__r), std::move(__nth), + return (*this)(ranges::begin(__r), std::move(__nth), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __nth_element_fn nth_element{}; + struct __lower_bound_fn + { template _Sent, typename _Tp, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - lower_bound(_Iter __first, _Sent __last, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __len = ranges::distance(__first, __last); @@ -1939,21 +2183,26 @@ namespace ranges projected, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - lower_bound(_Range&& __r, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::lower_bound(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__comp), std::move(__proj)); } + }; + inline constexpr __lower_bound_fn lower_bound{}; + + struct __upper_bound_fn + { template _Sent, typename _Tp, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - upper_bound(_Iter __first, _Sent __last, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __len = ranges::distance(__first, __last); @@ -1979,21 +2228,26 @@ namespace ranges projected, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - upper_bound(_Range&& __r, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::upper_bound(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __upper_bound_fn upper_bound{}; + struct __equal_range_fn + { template _Sent, typename _Tp, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr subrange<_Iter> - equal_range(_Iter __first, _Sent __last, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __len = ranges::distance(__first, __last); @@ -2035,21 +2289,26 @@ namespace ranges projected, _Proj>> _Comp = ranges::less> constexpr safe_subrange_t<_Range> - equal_range(_Range&& __r, const _Tp& __value, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, const _Tp& __value, + _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::equal_range(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__comp), std::move(__proj)); } + }; + inline constexpr __equal_range_fn equal_range{}; + + struct __binary_search_fn + { template _Sent, typename _Tp, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr bool - binary_search(_Iter __first, _Sent __last, - const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __i = ranges::lower_bound(__first, __last, __value, __comp, __proj); if (__i == __last) @@ -2063,19 +2322,24 @@ namespace ranges projected, _Proj>> _Comp = ranges::less> constexpr bool - binary_search(_Range&& __r, const _Tp& __value, _Comp __comp = {}, - _Proj __proj = {}) + operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {}, + _Proj __proj = {}) const { - return ranges::binary_search(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __value, std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __binary_search_fn binary_search{}; + struct __is_partitioned_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr bool - is_partitioned(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { __first = ranges::find_if_not(std::move(__first), __last, __pred, __proj); if (__first == __last) @@ -2088,17 +2352,22 @@ namespace ranges template, _Proj>> _Pred> constexpr bool - is_partitioned(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::is_partitioned(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __is_partitioned_fn is_partitioned{}; + struct __partition_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr subrange<_Iter> - partition(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { if constexpr (bidirectional_iterator<_Iter>) { @@ -2151,18 +2420,23 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> constexpr safe_subrange_t<_Range> - partition(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::partition(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __partition_fn partition{}; + + struct __stable_partition_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> requires permutable<_Iter> subrange<_Iter> - stable_partition(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); auto __middle @@ -2175,11 +2449,14 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> safe_subrange_t<_Range> - stable_partition(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::stable_partition(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __stable_partition_fn stable_partition{}; template struct partition_copy_result @@ -2203,6 +2480,8 @@ namespace ranges { return {std::move(in), std::move(out1), std::move(out2)}; } }; + struct __partition_copy_fn + { template _Sent, weakly_incrementable _Out1, weakly_incrementable _O2, typename _Proj = identity, @@ -2210,9 +2489,9 @@ namespace ranges requires indirectly_copyable<_Iter, _Out1> && indirectly_copyable<_Iter, _O2> constexpr partition_copy_result<_Iter, _Out1, _O2> - partition_copy(_Iter __first, _Sent __last, + operator()(_Iter __first, _Sent __last, _Out1 __out_true, _O2 __out_false, - _Pred __pred, _Proj __proj = {}) + _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) if (std::__invoke(__pred, std::__invoke(__proj, *__first))) @@ -2236,20 +2515,25 @@ namespace ranges requires indirectly_copyable, _Out1> && indirectly_copyable, _O2> constexpr partition_copy_result, _Out1, _O2> - partition_copy(_Range&& __r, _Out1 out_true, _O2 out_false, - _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Out1 out_true, _O2 out_false, + _Pred __pred, _Proj __proj = {}) const { - return ranges::partition_copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(out_true), std::move(out_false), std::move(__pred), std::move(__proj)); } + }; + inline constexpr __partition_copy_fn partition_copy{}; + + struct __partition_point_fn + { template _Sent, typename _Proj = identity, indirect_unary_predicate> _Pred> constexpr _Iter - partition_point(_Iter __first, _Sent __last, - _Pred __pred, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Pred __pred, _Proj __proj = {}) const { auto __len = ranges::distance(__first, __last); @@ -2273,24 +2557,29 @@ namespace ranges template, _Proj>> _Pred> constexpr safe_iterator_t<_Range> - partition_point(_Range&& __r, _Pred __pred, _Proj __proj = {}) + operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { - return ranges::partition_point(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__pred), std::move(__proj)); } + }; + + inline constexpr __partition_point_fn partition_point{}; template using merge_result = binary_transform_result<_Iter1, _Iter2, _Out>; + struct __merge_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, typename _Comp = ranges::less, typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2> constexpr merge_result<_Iter1, _Iter2, _Out> - merge(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) { @@ -2324,22 +2613,27 @@ namespace ranges constexpr merge_result, safe_iterator_t<_Range2>, _Out> - merge(_Range1&& __r1, _Range2&& __r2, _Out __result, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::merge(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __merge_fn merge{}; + struct __inplace_merge_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> _Iter - inplace_merge(_Iter __first, _Iter __middle, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Iter __middle, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { auto __lasti = ranges::next(__first, __last); std::inplace_merge(std::move(__first), std::move(__middle), __lasti, @@ -2351,14 +2645,19 @@ namespace ranges typename _Comp = ranges::less, typename _Proj = identity> requires sortable, _Comp, _Proj> safe_iterator_t<_Range> - inplace_merge(_Range&& __r, iterator_t<_Range> __middle, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, iterator_t<_Range> __middle, + _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::inplace_merge(ranges::begin(__r), std::move(__middle), + return (*this)(ranges::begin(__r), std::move(__middle), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __inplace_merge_fn inplace_merge{}; + + struct __includes_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Proj1 = identity, typename _Proj2 = identity, @@ -2366,8 +2665,8 @@ namespace ranges projected<_Iter2, _Proj2>> _Comp = ranges::less> constexpr bool - includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) if (std::__invoke(__comp, @@ -2393,27 +2692,32 @@ namespace ranges projected, _Proj2>> _Comp = ranges::less> constexpr bool - includes(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::includes(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __includes_fn includes{}; template using set_union_result = binary_transform_result<_Iter1, _Iter2, _Out>; + struct __set_union_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, typename _Comp = ranges::less, typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2> constexpr set_union_result<_Iter1, _Iter2, _Out> - set_union(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) { @@ -2454,28 +2758,33 @@ namespace ranges _Comp, _Proj1, _Proj2> constexpr set_union_result, safe_iterator_t<_Range2>, _Out> - set_union(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::set_union(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __set_union_fn set_union{}; template using set_intersection_result = binary_transform_result<_Iter1, _Iter2, _Out>; + struct __set_intersection_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, typename _Comp = ranges::less, typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2> constexpr set_intersection_result<_Iter1, _Iter2, _Out> - set_intersection(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) if (std::__invoke(__comp, @@ -2506,27 +2815,32 @@ namespace ranges _Comp, _Proj1, _Proj2> constexpr set_intersection_result, safe_iterator_t<_Range2>, _Out> - set_intersection(_Range1&& __r1, _Range2&& __r2, _Out __result, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::set_intersection(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __set_intersection_fn set_intersection{}; template using set_difference_result = copy_result<_Iter, _Out>; + struct __set_difference_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, typename _Comp = ranges::less, typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2> constexpr set_difference_result<_Iter1, _Out> - set_difference(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) if (std::__invoke(__comp, @@ -2556,29 +2870,34 @@ namespace ranges requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> constexpr set_difference_result, _Out> - set_difference(_Range1&& __r1, _Range2&& __r2, _Out __result, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, + _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::set_difference(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__comp), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __set_difference_fn set_difference{}; template using set_symmetric_difference_result = binary_transform_result<_Iter1, _Iter2, _Out>; + struct __set_symmetric_difference_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, weakly_incrementable _Out, typename _Comp = ranges::less, typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable<_Iter1, _Iter2, _Out, _Comp, _Proj1, _Proj2> constexpr set_symmetric_difference_result<_Iter1, _Iter2, _Out> - set_symmetric_difference(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Out __result, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { while (__first1 != __last1 && __first2 != __last2) if (std::__invoke(__comp, @@ -2618,22 +2937,27 @@ namespace ranges constexpr set_symmetric_difference_result, safe_iterator_t<_Range2>, _Out> - set_symmetric_difference(_Range1&& __r1, _Range2&& __r2, _Out __result, + operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return (ranges::set_symmetric_difference + return (*this) (ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__result), std::move(__comp), - std::move(__proj1), std::move(__proj2))); + std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __set_symmetric_difference_fn set_symmetric_difference{}; + struct __min_fn + { template> _Comp = ranges::less> constexpr const _Tp& - min(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) + operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { if (std::__invoke(std::move(__comp), std::__invoke(__proj, __b), @@ -2649,7 +2973,7 @@ namespace ranges requires indirectly_copyable_storable, range_value_t<_Range>*> constexpr range_value_t<_Range> - min(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); @@ -2670,17 +2994,22 @@ namespace ranges indirect_strict_weak_order> _Comp = ranges::less> constexpr _Tp - min(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::min(ranges::subrange(__r), + return (*this)(ranges::subrange(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __min_fn min{}; + + struct __max_fn + { template> _Comp = ranges::less> constexpr const _Tp& - max(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) + operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { if (std::__invoke(std::move(__comp), std::__invoke(__proj, __a), @@ -2696,7 +3025,7 @@ namespace ranges requires indirectly_copyable_storable, range_value_t<_Range>*> constexpr range_value_t<_Range> - max(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); @@ -2717,11 +3046,14 @@ namespace ranges indirect_strict_weak_order> _Comp = ranges::less> constexpr _Tp - max(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::max(ranges::subrange(__r), + return (*this)(ranges::subrange(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __max_fn max{}; template struct minmax_result @@ -2740,11 +3072,13 @@ namespace ranges { return {std::move(min), std::move(max)}; } }; + struct __minmax_fn + { template> _Comp = ranges::less> constexpr minmax_result - minmax(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) + operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { if (std::__invoke(std::move(__comp), std::__invoke(__proj, __b), @@ -2760,7 +3094,7 @@ namespace ranges requires indirectly_copyable_storable, range_value_t<_Range>*> constexpr minmax_result> - minmax(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); @@ -2785,19 +3119,24 @@ namespace ranges indirect_strict_weak_order> _Comp = ranges::less> constexpr minmax_result<_Tp> - minmax(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::minmax(ranges::subrange(__r), + return (*this)(ranges::subrange(__r), std::move(__comp), std::move(__proj)); } + }; + inline constexpr __minmax_fn minmax{}; + + struct __min_element_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - min_element(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return __first; @@ -2817,19 +3156,24 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - min_element(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::min_element(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __min_element_fn min_element{}; + struct __max_element_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr _Iter - max_element(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return __first; @@ -2849,22 +3193,27 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr safe_iterator_t<_Range> - max_element(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::max_element(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __max_element_fn max_element{}; template using minmax_element_result = minmax_result<_Iter>; + struct __minmax_element_fn + { template _Sent, typename _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> constexpr minmax_element_result<_Iter> - minmax_element(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return {__first, __first}; @@ -2889,12 +3238,17 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> constexpr minmax_element_result> - minmax_element(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::minmax_element(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __minmax_element_fn minmax_element{}; + struct __lexicographical_compare_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Proj1 = identity, typename _Proj2 = identity, @@ -2902,14 +3256,14 @@ namespace ranges projected<_Iter2, _Proj2>> _Comp = ranges::less> constexpr bool - lexicographical_compare(_Iter1 __first1, _Sent1 __last1, + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (__detail::__is_normal_iterator<_Iter1> || __detail::__is_normal_iterator<_Iter2>) - return ranges::lexicographical_compare + return (*this) (std::__niter_base(std::move(__first1)), std::__niter_base(std::move(__last1)), std::__niter_base(std::move(__first2)), @@ -2983,15 +3337,18 @@ namespace ranges projected, _Proj2>> _Comp = ranges::less> constexpr bool - lexicographical_compare(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, _Comp __comp = {}, + _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return (ranges::lexicographical_compare + return (*this) (ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__comp), - std::move(__proj1), std::move(__proj2))); + std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __lexicographical_compare_fn lexicographical_compare; template struct next_permutation_result @@ -3000,12 +3357,14 @@ namespace ranges _Iter in; }; + struct __next_permutation_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr next_permutation_result<_Iter> - next_permutation(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return {false, std::move(__first)}; @@ -3048,21 +3407,26 @@ namespace ranges typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr next_permutation_result> - next_permutation(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::next_permutation(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __next_permutation_fn next_permutation{}; template using prev_permutation_result = next_permutation_result<_Iter>; + struct __prev_permutation_fn + { template _Sent, typename _Comp = ranges::less, typename _Proj = identity> requires sortable<_Iter, _Comp, _Proj> constexpr prev_permutation_result<_Iter> - prev_permutation(_Iter __first, _Sent __last, - _Comp __comp = {}, _Proj __proj = {}) + operator()(_Iter __first, _Sent __last, + _Comp __comp = {}, _Proj __proj = {}) const { if (__first == __last) return {false, std::move(__first)}; @@ -3105,11 +3469,14 @@ namespace ranges typename _Proj = identity> requires sortable, _Comp, _Proj> constexpr prev_permutation_result> - prev_permutation(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - return ranges::prev_permutation(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__comp), std::move(__proj)); } + }; + + inline constexpr __prev_permutation_fn prev_permutation{}; } // namespace ranges _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h index 813a5096ae0..f3b800863dc 100644 --- a/libstdc++-v3/include/bits/ranges_algobase.h +++ b/libstdc++-v3/include/bits/ranges_algobase.h @@ -71,20 +71,22 @@ namespace ranges __is_move_iterator> = true; } // namespace __detail + struct __equal_fn + { template _Sent1, input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, typename _Pred = ranges::equal_to, typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> constexpr bool - equal(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { // TODO: implement more specializations to at least have parity with // std::equal. if constexpr (__detail::__is_normal_iterator<_Iter1> || __detail::__is_normal_iterator<_Iter2>) - return ranges::equal(std::__niter_base(std::move(__first1)), + return (*this)(std::__niter_base(std::move(__first1)), std::__niter_base(std::move(__last1)), std::__niter_base(std::move(__first2)), std::__niter_base(std::move(__last2)), @@ -145,14 +147,17 @@ namespace ranges requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> constexpr bool - equal(_Range1&& __r1, _Range2&& __r2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + operator()(_Range1&& __r1, _Range2&& __r2, + _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return ranges::equal(ranges::begin(__r1), ranges::end(__r1), + return (*this)(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), std::move(__pred), std::move(__proj1), std::move(__proj2)); } + }; + + inline constexpr __equal_fn equal{}; template struct copy_result @@ -288,11 +293,13 @@ namespace ranges } } + struct __copy_fn + { template _Sent, weakly_incrementable _Out> requires indirectly_copyable<_Iter, _Out> constexpr copy_result<_Iter, _Out> - copy(_Iter __first, _Sent __last, _Out __result) + operator()(_Iter __first, _Sent __last, _Out __result) const { return ranges::__copy_or_move(std::move(__first), std::move(__last), @@ -302,17 +309,22 @@ namespace ranges template requires indirectly_copyable, _Out> constexpr copy_result, _Out> - copy(_Range&& __r, _Out __result) + operator()(_Range&& __r, _Out __result) const { - return ranges::copy(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __copy_fn copy{}; + struct __move_fn + { template _Sent, weakly_incrementable _Out> requires indirectly_movable<_Iter, _Out> constexpr move_result<_Iter, _Out> - move(_Iter __first, _Sent __last, _Out __result) + operator()(_Iter __first, _Sent __last, _Out __result) const { return ranges::__copy_or_move(std::move(__first), std::move(__last), @@ -322,11 +334,14 @@ namespace ranges template requires indirectly_movable, _Out> constexpr move_result, _Out> - move(_Range&& __r, _Out __result) + operator()(_Range&& __r, _Out __result) const { - return ranges::move(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __move_fn move{}; template _Sent, @@ -420,11 +435,13 @@ namespace ranges } } + struct __copy_backward_fn + { template _Sent1, bidirectional_iterator _Iter2> requires indirectly_copyable<_Iter1, _Iter2> constexpr copy_backward_result<_Iter1, _Iter2> - copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) + operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const { return ranges::__copy_or_move_backward(std::move(__first), std::move(__last), @@ -434,17 +451,22 @@ namespace ranges template requires indirectly_copyable, _Iter> constexpr copy_backward_result, _Iter> - copy_backward(_Range&& __r, _Iter __result) + operator()(_Range&& __r, _Iter __result) const { - return ranges::copy_backward(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __copy_backward_fn copy_backward{}; + struct __move_backward_fn + { template _Sent1, bidirectional_iterator _Iter2> requires indirectly_movable<_Iter1, _Iter2> constexpr move_backward_result<_Iter1, _Iter2> - move_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result) + operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const { return ranges::__copy_or_move_backward(std::move(__first), std::move(__last), @@ -454,19 +476,24 @@ namespace ranges template requires indirectly_movable, _Iter> constexpr move_backward_result, _Iter> - move_backward(_Range&& __r, _Iter __result) + operator()(_Range&& __r, _Iter __result) const { - return ranges::move_backward(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__result)); } + }; + + inline constexpr __move_backward_fn move_backward{}; template using copy_n_result = copy_result<_Iter, _Out>; + struct __copy_n_fn + { template requires indirectly_copyable<_Iter, _Out> constexpr copy_n_result<_Iter, _Out> - copy_n(_Iter __first, iter_difference_t<_Iter> __n, _Out __result) + operator()(_Iter __first, iter_difference_t<_Iter> __n, _Out __result) const { if constexpr (random_access_iterator<_Iter>) return ranges::copy(__first, __first + __n, std::move(__result)); @@ -477,10 +504,15 @@ namespace ranges return {std::move(__first), std::move(__result)}; } } + }; + + inline constexpr __copy_n_fn copy_n{}; + struct __fill_n_fn + { template _Out> constexpr _Out - fill_n(_Out __first, iter_difference_t<_Out> __n, const _Tp& __value) + operator()(_Out __first, iter_difference_t<_Out> __n, const _Tp& __value) const { // TODO: implement more specializations to be at least on par with // std::fill_n @@ -507,11 +539,16 @@ namespace ranges return __first; } } + }; + + inline constexpr __fill_n_fn fill_n{}; + struct __fill_fn + { template _Out, sentinel_for<_Out> _Sent> constexpr _Out - fill(_Out __first, _Sent __last, const _Tp& __value) + operator()(_Out __first, _Sent __last, const _Tp& __value) const { // TODO: implement more specializations to be at least on par with // std::fill @@ -537,10 +574,13 @@ namespace ranges template _Range> constexpr safe_iterator_t<_Range> - fill(_Range&& __r, const _Tp& __value) + operator()(_Range&& __r, const _Tp& __value) const { - return ranges::fill(ranges::begin(__r), ranges::end(__r), __value); + return (*this)(ranges::begin(__r), ranges::end(__r), __value); } + }; + + inline constexpr __fill_fn fill{}; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index 5ff2eaa1b3a..fa4238b9181 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -78,11 +78,21 @@ namespace ranges && __nothrow_forward_iterator>); } // namespace __detail + struct __destroy_fn + { template<__detail::__nothrow_input_iterator _Iter, __detail::__nothrow_sentinel<_Iter> _Sent> requires destructible> constexpr _Iter - destroy(_Iter __first, _Sent __last) noexcept; + operator()(_Iter __first, _Sent __last) const noexcept; + + template<__detail::__nothrow_input_range _Range> + requires destructible> + constexpr safe_iterator_t<_Range> + operator()(_Range&& __r) const noexcept; + }; + + inline constexpr __destroy_fn destroy{}; namespace __detail { @@ -126,11 +136,13 @@ namespace ranges }; } // namespace __detail + struct __uninitialized_default_construct_fn + { template<__detail::__nothrow_forward_iterator _Iter, __detail::__nothrow_sentinel<_Iter> _Sent> requires default_initializable> _Iter - uninitialized_default_construct(_Iter __first, _Sent __last) + operator()(_Iter __first, _Sent __last) const { using _ValueType = remove_reference_t>; if constexpr (is_trivially_default_constructible_v<_ValueType>) @@ -148,17 +160,23 @@ namespace ranges template<__detail::__nothrow_forward_range _Range> requires default_initializable> safe_iterator_t<_Range> - uninitialized_default_construct(_Range&& __r) + operator()(_Range&& __r) const { - return ranges::uninitialized_default_construct(ranges::begin(__r), + return (*this)(ranges::begin(__r), ranges::end(__r)); } + }; + inline constexpr __uninitialized_default_construct_fn + uninitialized_default_construct{}; + + struct __uninitialized_default_construct_n_fn + { template<__detail::__nothrow_forward_iterator _Iter> requires default_initializable> _Iter - uninitialized_default_construct_n(_Iter __first, - iter_difference_t<_Iter> __n) + operator()(_Iter __first, + iter_difference_t<_Iter> __n) const { using _ValueType = remove_reference_t>; if constexpr (is_trivially_default_constructible_v<_ValueType>) @@ -172,12 +190,18 @@ namespace ranges return __first; } } + }; + inline constexpr __uninitialized_default_construct_n_fn + uninitialized_default_construct_n; + + struct __uninitialized_value_construct_fn + { template<__detail::__nothrow_forward_iterator _Iter, __detail::__nothrow_sentinel<_Iter> _Sent> requires default_initializable> _Iter - uninitialized_value_construct(_Iter __first, _Sent __last) + operator()(_Iter __first, _Sent __last) const { using _ValueType = remove_reference_t>; if constexpr (is_trivial_v<_ValueType> @@ -196,16 +220,22 @@ namespace ranges template<__detail::__nothrow_forward_range _Range> requires default_initializable> safe_iterator_t<_Range> - uninitialized_value_construct(_Range&& __r) + operator()(_Range&& __r) const { - return ranges::uninitialized_value_construct(ranges::begin(__r), + return (*this)(ranges::begin(__r), ranges::end(__r)); } + }; + inline constexpr __uninitialized_value_construct_fn + uninitialized_value_construct{}; + + struct __uninitialized_value_construct_n_fn + { template<__detail::__nothrow_forward_iterator _Iter> requires default_initializable> _Iter - uninitialized_value_construct_n(_Iter __first, iter_difference_t<_Iter> __n) + operator()(_Iter __first, iter_difference_t<_Iter> __n) const { using _ValueType = remove_reference_t>; if constexpr (is_trivial_v<_ValueType> @@ -220,17 +250,23 @@ namespace ranges return __first; } } + }; + + inline constexpr __uninitialized_value_construct_n_fn + uninitialized_value_construct_n; template using uninitialized_copy_result = copy_result<_Iter, _Out>; + struct __uninitialized_copy_fn + { template _ISent, __detail::__nothrow_forward_iterator _Out, __detail::__nothrow_sentinel<_Out> _OSent> requires constructible_from, iter_reference_t<_Iter>> uninitialized_copy_result<_Iter, _Out> - uninitialized_copy(_Iter __ifirst, _ISent __ilast, - _Out __ofirst, _OSent __olast) + operator()(_Iter __ifirst, _ISent __ilast, + _Out __ofirst, _OSent __olast) const { using _OutType = remove_reference_t>; if constexpr (sized_sentinel_for<_ISent, _Iter> @@ -259,23 +295,28 @@ namespace ranges range_reference_t<_IRange>> uninitialized_copy_result, safe_iterator_t<_ORange>> - uninitialized_copy(_IRange&& __inr, _ORange&& __outr) + operator()(_IRange&& __inr, _ORange&& __outr) const { - return ranges::uninitialized_copy(ranges::begin(__inr), + return (*this)(ranges::begin(__inr), ranges::end(__inr), ranges::begin(__outr), ranges::end(__outr)); } + }; + + inline constexpr __uninitialized_copy_fn uninitialized_copy{}; template using uninitialized_copy_n_result = uninitialized_copy_result<_Iter, _Out>; + struct __uninitialized_copy_n_fn + { template _Sent> requires constructible_from, iter_reference_t<_Iter>> uninitialized_copy_n_result<_Iter, _Out> - uninitialized_copy_n(_Iter __ifirst, iter_difference_t<_Iter> __n, - _Out __ofirst, _Sent __olast) + operator()(_Iter __ifirst, iter_difference_t<_Iter> __n, + _Out __ofirst, _Sent __olast) const { using _OutType = remove_reference_t>; if constexpr (sized_sentinel_for<_Sent, _Out> @@ -296,18 +337,23 @@ namespace ranges return {__ifirst, __ofirst}; } } + }; + + inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{}; template using uninitialized_move_result = uninitialized_copy_result<_Iter, _Out>; + struct __uninitialized_move_fn + { template _ISent, __detail::__nothrow_forward_iterator _Out, __detail::__nothrow_sentinel<_Out> _OSent> requires constructible_from, iter_rvalue_reference_t<_Iter>> uninitialized_move_result<_Iter, _Out> - uninitialized_move(_Iter __ifirst, _ISent __ilast, - _Out __ofirst, _OSent __olast) + operator()(_Iter __ifirst, _ISent __ilast, + _Out __ofirst, _OSent __olast) const { using _OutType = remove_reference_t>; if constexpr (sized_sentinel_for<_ISent, _Iter> @@ -338,24 +384,29 @@ namespace ranges range_rvalue_reference_t<_IRange>> uninitialized_move_result, safe_iterator_t<_ORange>> - uninitialized_move(_IRange&& __inr, _ORange&& __outr) + operator()(_IRange&& __inr, _ORange&& __outr) const { - return ranges::uninitialized_move(ranges::begin(__inr), + return (*this)(ranges::begin(__inr), ranges::end(__inr), ranges::begin(__outr), ranges::end(__outr)); } + }; + + inline constexpr __uninitialized_move_fn uninitialized_move{}; template using uninitialized_move_n_result = uninitialized_copy_result<_Iter, _Out>; + struct __uninitialized_move_n_fn + { template _Sent> requires constructible_from, iter_rvalue_reference_t<_Iter>> uninitialized_move_n_result<_Iter, _Out> - uninitialized_move_n(_Iter __ifirst, iter_difference_t<_Iter> __n, - _Out __ofirst, _Sent __olast) + operator()(_Iter __ifirst, iter_difference_t<_Iter> __n, + _Out __ofirst, _Sent __olast) const { using _OutType = remove_reference_t>; if constexpr (sized_sentinel_for<_Sent, _Out> @@ -378,12 +429,17 @@ namespace ranges return {__ifirst, __ofirst}; } } + }; + + inline constexpr __uninitialized_move_n_fn uninitialized_move_n{}; + struct __uninitialized_fill_fn + { template<__detail::__nothrow_forward_iterator _Iter, __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp> requires constructible_from, const _Tp&> _Iter - uninitialized_fill(_Iter __first, _Sent __last, const _Tp& __x) + operator()(_Iter __first, _Sent __last, const _Tp& __x) const { using _ValueType = remove_reference_t>; if constexpr (is_trivial_v<_ValueType> @@ -402,17 +458,22 @@ namespace ranges template<__detail::__nothrow_forward_range _Range, typename _Tp> requires constructible_from, const _Tp&> safe_iterator_t<_Range> - uninitialized_fill(_Range&& __r, const _Tp& __x) + operator()(_Range&& __r, const _Tp& __x) const { - return ranges::uninitialized_fill(ranges::begin(__r), ranges::end(__r), + return (*this)(ranges::begin(__r), ranges::end(__r), __x); } + }; + + inline constexpr __uninitialized_fill_fn uninitialized_fill{}; + struct __uninitialized_fill_n_fn + { template<__detail::__nothrow_forward_iterator _Iter, typename _Tp> requires constructible_from, const _Tp&> _Iter - uninitialized_fill_n(_Iter __first, iter_difference_t<_Iter> __n, - const _Tp& __x) + operator()(_Iter __first, iter_difference_t<_Iter> __n, + const _Tp& __x) const { using _ValueType = remove_reference_t>; if constexpr (is_trivial_v<_ValueType> @@ -427,31 +488,44 @@ namespace ranges return __first; } } + }; + + inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{}; + struct __construct_at_fn + { template requires requires { ::new (declval()) _Tp(declval<_Args>()...); } constexpr _Tp* - construct_at(_Tp* __location, _Args&&... __args) + operator()(_Tp* __location, _Args&&... __args) const { return ::new (__detail::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...); } + }; + + inline constexpr __construct_at_fn construct_at{}; + struct __destroy_at_fn + { template constexpr void - destroy_at(_Tp* __location) noexcept + operator()(_Tp* __location) const noexcept { if constexpr (is_array_v<_Tp>) ranges::destroy(ranges::begin(*__location), ranges::end(*__location)); else __location->~_Tp(); } + }; + + inline constexpr __destroy_at_fn destroy_at{}; template<__detail::__nothrow_input_iterator _Iter, __detail::__nothrow_sentinel<_Iter> _Sent> requires destructible> constexpr _Iter - destroy(_Iter __first, _Sent __last) noexcept + __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept { if constexpr (is_trivially_destructible_v>) return ranges::next(__first, __last); @@ -466,13 +540,15 @@ namespace ranges template<__detail::__nothrow_input_range _Range> requires destructible> constexpr safe_iterator_t<_Range> - destroy(_Range&& __r) noexcept - { return ranges::destroy(ranges::begin(__r), ranges::end(__r)); } + __destroy_fn::operator()(_Range&& __r) const noexcept + { return (*this)(ranges::begin(__r), ranges::end(__r)); } + struct __destroy_n_fn + { template<__detail::__nothrow_input_iterator _Iter> requires destructible> constexpr _Iter - destroy_n(_Iter __first, iter_difference_t<_Iter> __n) noexcept + operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept { if constexpr (is_trivially_destructible_v>) return ranges::next(__first, __n); @@ -483,6 +559,9 @@ namespace ranges return __first; } } + }; + + inline constexpr __destroy_n_fn destroy_n{}; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std