4380 lines
178 KiB
Markdown
4380 lines
178 KiB
Markdown
[function.objects]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.10 Function objects [function.objects]
|
||
|
||
### [22.10.1](#general) General [[function.objects.general]](function.objects.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11215)
|
||
|
||
A [*function object type*](#def:function_object,type "22.10.1 General [function.objects.general]") is an object
|
||
type ([[basic.types.general]](basic.types.general#term.object.type "6.9.1 General")) that can be the type of the[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") in a function call ([[expr.call]](expr.call "7.6.1.3 Function call"), [[over.match.call]](over.match.call "12.2.2.2 Function call syntax"))[.](#general-1.sentence-1)[193](#footnote-193 "Such a type is a function pointer or a class type which has a member operator() or a class type which has a conversion to a pointer to function.")
|
||
|
||
A [*function object*](#def:function_object "22.10.1 General [function.objects.general]") is an
|
||
object of a function object type[.](#general-1.sentence-2)
|
||
|
||
In the places where one would expect to pass a
|
||
pointer to a function to an algorithmic template ([[algorithms]](algorithms "26 Algorithms library")), the
|
||
interface is specified to accept a function object[.](#general-1.sentence-3)
|
||
|
||
This not only makes
|
||
algorithmic templates work with pointers to functions, but also enables them to
|
||
work with arbitrary function objects[.](#general-1.sentence-4)
|
||
|
||
[193)](#footnote-193)[193)](#footnoteref-193)
|
||
|
||
Such a type is a function
|
||
pointer or a class type which has a member operator() or a class type
|
||
which has a conversion to a pointer to function[.](#footnote-193.sentence-1)
|
||
|
||
### [22.10.2](#functional.syn) Header <functional> synopsis [[functional.syn]](functional.syn)
|
||
|
||
[ð](#header:%3cfunctional%3e)
|
||
|
||
namespace std {// [[func.invoke]](#func.invoke "22.10.5 invoke functions"), invoketemplate<class F, class... Args>constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // freestandingnoexcept(is_nothrow_invocable_v<F, Args...>); template<class R, class F, class... Args>constexpr R invoke_r(F&& f, Args&&... args) // freestandingnoexcept(is_nothrow_invocable_r_v<R, F, Args...>); // [[refwrap]](#refwrap "22.10.6 Class template reference_wrapper"), reference_wrappertemplate<class T> class reference_wrapper; // freestandingtemplate<class T> constexpr reference_wrapper<T> ref(T&) noexcept; // freestandingtemplate<class T> constexpr reference_wrapper<const T> cref(const T&) noexcept; // freestandingtemplate<class T> void ref(const T&&) = delete; // freestandingtemplate<class T> void cref(const T&&) = delete; // freestandingtemplate<class T>constexpr reference_wrapper<T> ref(reference_wrapper<T>) noexcept; // freestandingtemplate<class T>constexpr reference_wrapper<const T> cref(reference_wrapper<T>) noexcept; // freestanding// [[refwrap.common.ref]](#refwrap.common.ref "22.10.6.8 common_reference related specializations"), common_reference related specializationstemplate<class R, class T, template<class> class RQual, template<class> class TQual>requires *see below*struct basic_common_reference<R, T, RQual, TQual>; template<class T, class R, template<class> class TQual, template<class> class RQual>requires *see below*struct basic_common_reference<T, R, TQual, RQual>; // [[arithmetic.operations]](#arithmetic.operations "22.10.7 Arithmetic operations"), arithmetic operationstemplate<class T = void> struct plus; // freestandingtemplate<class T = void> struct minus; // freestandingtemplate<class T = void> struct multiplies; // freestandingtemplate<class T = void> struct divides; // freestandingtemplate<class T = void> struct modulus; // freestandingtemplate<class T = void> struct negate; // freestandingtemplate<> struct plus<void>; // freestandingtemplate<> struct minus<void>; // freestandingtemplate<> struct multiplies<void>; // freestandingtemplate<> struct divides<void>; // freestandingtemplate<> struct modulus<void>; // freestandingtemplate<> struct negate<void>; // freestanding// [[comparisons]](#comparisons "22.10.8 Comparisons"), comparisonstemplate<class T = void> struct equal_to; // freestandingtemplate<class T = void> struct not_equal_to; // freestandingtemplate<class T = void> struct greater; // freestandingtemplate<class T = void> struct less; // freestandingtemplate<class T = void> struct greater_equal; // freestandingtemplate<class T = void> struct less_equal; // freestandingtemplate<> struct equal_to<void>; // freestandingtemplate<> struct not_equal_to<void>; // freestandingtemplate<> struct greater<void>; // freestandingtemplate<> struct less<void>; // freestandingtemplate<> struct greater_equal<void>; // freestandingtemplate<> struct less_equal<void>; // freestanding// [[comparisons.three.way]](#comparisons.three.way "22.10.8.8 Class compare_three_way"), class compare_three_waystruct compare_three_way; // freestanding// [[logical.operations]](#logical.operations "22.10.10 Logical operations"), logical operationstemplate<class T = void> struct logical_and; // freestandingtemplate<class T = void> struct logical_or; // freestandingtemplate<class T = void> struct logical_not; // freestandingtemplate<> struct logical_and<void>; // freestandingtemplate<> struct logical_or<void>; // freestandingtemplate<> struct logical_not<void>; // freestanding// [[bitwise.operations]](#bitwise.operations "22.10.11 Bitwise operations"), bitwise operationstemplate<class T = void> struct bit_and; // freestandingtemplate<class T = void> struct bit_or; // freestandingtemplate<class T = void> struct bit_xor; // freestandingtemplate<class T = void> struct bit_not; // freestandingtemplate<> struct bit_and<void>; // freestandingtemplate<> struct bit_or<void>; // freestandingtemplate<> struct bit_xor<void>; // freestandingtemplate<> struct bit_not<void>; // freestanding// [[func.identity]](#func.identity "22.10.12 Class identity"), identitystruct identity; // freestanding// [[func.not.fn]](#func.not.fn "22.10.13 Function template not_fn"), function template not_fntemplate<class F> constexpr *unspecified* not_fn(F&& f); // freestandingtemplate<auto f> constexpr *unspecified* not_fn() noexcept; // freestanding// [[func.bind.partial]](#func.bind.partial "22.10.14 Function templates bind_front and bind_back"), function templates bind_front and bind_backtemplate<class F, class... Args>constexpr *unspecified* bind_front(F&&, Args&&...); // freestandingtemplate<auto f, class... Args>constexpr *unspecified* bind_front(Args&&...); // freestandingtemplate<class F, class... Args>constexpr *unspecified* bind_back(F&&, Args&&...); // freestandingtemplate<auto f, class... Args>constexpr *unspecified* bind_back(Args&&...); // freestanding// [[func.bind]](#func.bind "22.10.15 Function object binders"), bindtemplate<class T> struct is_bind_expression; // freestandingtemplate<class T>constexpr bool [is_bind_expression_v](#lib:is_bind_expression_v "22.10.2 Header <functional> synopsis [functional.syn]") = // freestanding is_bind_expression<T>::value; template<class T> struct is_placeholder; // freestandingtemplate<class T>constexpr int [is_placeholder_v](#lib:is_placeholder_v "22.10.2 Header <functional> synopsis [functional.syn]") = // freestanding is_placeholder<T>::value; template<class F, class... BoundArgs>constexpr *unspecified* bind(F&&, BoundArgs&&...); // freestandingtemplate<class R, class F, class... BoundArgs>constexpr *unspecified* bind(F&&, BoundArgs&&...); // freestandingnamespace placeholders {// *M* is the implementation-defined number of placeholders*see below* _1; // freestanding*see below* _2; // freestanding ⋮ *see below* _*M*; // freestanding}// [[func.memfn]](#func.memfn "22.10.16 Function template mem_fn"), member function adaptorstemplate<class R, class T>constexpr *unspecified* mem_fn(R T::*) noexcept; // freestanding// [[func.wrap]](#func.wrap "22.10.17 Polymorphic function wrappers"), polymorphic function wrappers// [[func.wrap.badcall]](#func.wrap.badcall "22.10.17.2 Class bad_function_call"), class bad_function_callclass bad_function_call; // [[func.wrap.func]](#func.wrap.func "22.10.17.3 Class template function"), class template functiontemplate<class> class function; // *not defined*template<class R, class... ArgTypes> class function<R(ArgTypes...)>; // [[func.wrap.func.alg]](#func.wrap.func.alg "22.10.17.3.8 Specialized algorithms"), function specialized algorithmstemplate<class R, class... ArgTypes>void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept; // [[func.wrap.func.nullptr]](#func.wrap.func.nullptr "22.10.17.3.7 Null pointer comparison operator functions"), function null pointer comparison operator functionstemplate<class R, class... ArgTypes>bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // [[func.wrap.move]](#func.wrap.move "22.10.17.4 Move-only wrapper"), move-only wrappertemplate<class... S> class move_only_function; // *not defined*template<class R, class... ArgTypes>class move_only_function<R(ArgTypes...) cv *ref* noexcept(*noex*)>; // *see below*// [[func.wrap.copy]](#func.wrap.copy "22.10.17.5 Copyable wrapper"), copyable wrappertemplate<class... S> class copyable_function; // *not defined*template<class R, class... ArgTypes>class copyable_function<R(ArgTypes...) cv *ref* noexcept(*noex*)>; // *see below*// [[func.wrap.ref]](#func.wrap.ref "22.10.17.6 Non-owning wrapper"), non-owning wrappertemplate<class... S> class function_ref; // freestanding, *not defined*template<class R, class... ArgTypes>class function_ref<R(ArgTypes...) cv noexcept(*noex*)>; // freestanding, *see below*// [[func.search]](#func.search "22.10.18 Searchers"), searcherstemplate<class ForwardIterator1, class BinaryPredicate = equal_to<>>class default_searcher; // freestandingtemplate<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>>class boyer_moore_searcher; template<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>>class boyer_moore_horspool_searcher; // [[unord.hash]](#unord.hash "22.10.19 Class template hash"), class template hashtemplate<class T>struct hash; // freestandingnamespace ranges {// [[range.cmp]](#range.cmp "22.10.9 Concept-constrained comparisons"), concept-constrained comparisonsstruct equal_to; // freestandingstruct not_equal_to; // freestandingstruct greater; // freestandingstruct less; // freestandingstruct greater_equal; // freestandingstruct less_equal; // freestanding}template<class Fn, class... Args>concept [*callable*](#concept:callable "22.10.2 Header <functional> synopsis [functional.syn]") = // *exposition only*requires (Fn&& fn, Args&&... args) { std::forward<Fn>(fn)(std::forward<Args>(args)...); }; template<class Fn, class... Args>concept [*nothrow-callable*](#concept:nothrow-callable "22.10.2 Header <functional> synopsis [functional.syn]") = // *exposition only*[*callable*](#concept:callable "22.10.2 Header <functional> synopsis [functional.syn]")<Fn, Args...> &&requires (Fn&& fn, Args&&... args) {{ std::forward<Fn>(fn)(std::forward<Args>(args)...) } noexcept; }; template<class Fn, class... Args>using *call-result-t* = decltype(declval<Fn>()(declval<Args>()...)); // *exposition only*template<const auto& T>using *decayed-typeof* = decltype(auto(T)); // *exposition only*}
|
||
|
||
[1](#functional.syn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11443)
|
||
|
||
[*Example [1](#functional.syn-example-1)*:
|
||
|
||
If a C++ program wants to have a by-element addition of two vectors a and b containing double and put the result into a,
|
||
it can do:transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
|
||
|
||
â *end example*]
|
||
|
||
[2](#functional.syn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11453)
|
||
|
||
[*Example [2](#functional.syn-example-2)*:
|
||
|
||
To negate every element of a:
|
||
|
||
transform(a.begin(), a.end(), a.begin(), negate<double>()); â *end example*]
|
||
|
||
### [22.10.3](#func.def) Definitions [[func.def]](func.def)
|
||
|
||
[1](#func.def-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11465)
|
||
|
||
The following definitions apply to this Clause:
|
||
|
||
[2](#func.def-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11468)
|
||
|
||
A [*call signature*](#def:call_signature "22.10.3 Definitions [func.def]") is the name of a return type followed by a
|
||
parenthesized comma-separated list of zero or more argument types[.](#func.def-2.sentence-1)
|
||
|
||
[3](#func.def-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11472)
|
||
|
||
A [*callable type*](#def:type,callable "22.10.3 Definitions [func.def]") is a function object type ([function.objects]) or a pointer to member[.](#func.def-3.sentence-1)
|
||
|
||
[4](#func.def-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11475)
|
||
|
||
A [*callable object*](#def:object,callable "22.10.3 Definitions [func.def]") is an object of a callable type[.](#func.def-4.sentence-1)
|
||
|
||
[5](#func.def-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11478)
|
||
|
||
A [*call wrapper type*](#def:call_wrapper,type "22.10.3 Definitions [func.def]") is a type that holds a callable object
|
||
and supports a call operation that forwards to that object[.](#func.def-5.sentence-1)
|
||
|
||
[6](#func.def-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11482)
|
||
|
||
A [*call wrapper*](#def:call_wrapper "22.10.3 Definitions [func.def]") is an object of a call wrapper type[.](#func.def-6.sentence-1)
|
||
|
||
[7](#func.def-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11485)
|
||
|
||
A [*target object*](#def:target_object "22.10.3 Definitions [func.def]") is the callable object held by a call wrapper[.](#func.def-7.sentence-1)
|
||
|
||
[8](#func.def-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11488)
|
||
|
||
A call wrapper type may additionally hold
|
||
a sequence of objects and references
|
||
that may be passed as arguments to the target object[.](#func.def-8.sentence-1)
|
||
|
||
These entities are collectively referred to
|
||
as [*bound argument entities*](#def:bound_argument_entity "22.10.3 Definitions [func.def]")[.](#func.def-8.sentence-2)
|
||
|
||
[9](#func.def-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11495)
|
||
|
||
The target object and bound argument entities of the call wrapper are
|
||
collectively referred to as [*state entities*](#def:state_entity "22.10.3 Definitions [func.def]")[.](#func.def-9.sentence-1)
|
||
|
||
### [22.10.4](#func.require) Requirements [[func.require]](func.require)
|
||
|
||
[1](#func.require-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11501)
|
||
|
||
Define *INVOKE*(f, t1, t2, …, tN) as follows:
|
||
|
||
- [(1.1)](#func.require-1.1)
|
||
|
||
(t1.*f)(t2, …, tN) when f is a pointer to a
|
||
member function of a class T andis_same_v<T, remove_cvref_t<decltype(t1)>> ||is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
|
||
|
||
- [(1.2)](#func.require-1.2)
|
||
|
||
(t1.get().*f)(t2, …, tN) when f is a pointer to a
|
||
member function of a class T and remove_cvref_t<decltype(t1)> is a specialization of reference_wrapper;
|
||
|
||
- [(1.3)](#func.require-1.3)
|
||
|
||
((*t1).*f)(t2, …, tN) when f is a pointer to a
|
||
member function of a class T and t1 does not satisfy the previous two items;
|
||
|
||
- [(1.4)](#func.require-1.4)
|
||
|
||
t1.*f when N=1 and f is a pointer to
|
||
data member of a class T andis_same_v<T, remove_cvref_t<decltype(t1)>> ||is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
|
||
|
||
- [(1.5)](#func.require-1.5)
|
||
|
||
t1.get().*f when N=1 and f is a pointer to
|
||
data member of a class T and remove_cvref_t<decltype(t1)> is a specialization of reference_wrapper;
|
||
|
||
- [(1.6)](#func.require-1.6)
|
||
|
||
(*t1).*f when N=1 and f is a pointer to
|
||
data member of a class T and t1 does not satisfy the previous two items;
|
||
|
||
- [(1.7)](#func.require-1.7)
|
||
|
||
f(t1, t2, …, tN) in all other cases[.](#func.require-1.sentence-1)
|
||
|
||
[2](#func.require-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11537)
|
||
|
||
Define *INVOKE*<R>(f, t1, t2, …, tN) asstatic_cast<void>(*INVOKE*(f, t1, t2, …, tN)) if R is cv void, otherwise*INVOKE*(f, t1, t2, …, tN) implicitly converted
|
||
to R[.](#func.require-2.sentence-1)
|
||
|
||
Ifreference_converts_from_temporary_v<R, decltype(*INVOKE*(f, t1, t2, …, tN))> is true,*INVOKE*<R>(f, t1, t2, …, tN) is ill-formed[.](#func.require-2.sentence-2)
|
||
|
||
[3](#func.require-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11550)
|
||
|
||
Every call wrapper ([[func.def]](#func.def "22.10.3 Definitions")) meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.require-3.sentence-1)
|
||
|
||
An [*argument forwarding call wrapper*](#def:argument_forwarding_call_wrapper "22.10.4 Requirements [func.require]") is a
|
||
call wrapper that can be called with an arbitrary argument list
|
||
and delivers the arguments to the target object as references[.](#func.require-3.sentence-2)
|
||
|
||
This forwarding step delivers rvalue arguments as rvalue references
|
||
and lvalue arguments as lvalue references[.](#func.require-3.sentence-3)
|
||
|
||
[*Note [1](#func.require-note-1)*:
|
||
|
||
In a typical implementation, argument forwarding call wrappers have
|
||
an overloaded function call operator of the formtemplate<class... UnBoundArgs>constexpr R operator()(UnBoundArgs&&... unbound_args) *cv-qual*;
|
||
|
||
â *end note*]
|
||
|
||
[4](#func.require-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11570)
|
||
|
||
A [*perfect forwarding call wrapper*](#def:call_wrapper,perfect_forwarding "22.10.4 Requirements [func.require]") is
|
||
an argument forwarding call wrapper
|
||
that forwards its state entities to the underlying call expression[.](#func.require-4.sentence-1)
|
||
|
||
This forwarding step delivers a state entity of type T as cv T& when the call is performed on an lvalue of the call wrapper type and
|
||
as cv T&& otherwise,
|
||
where cv represents the cv-qualifiers of the call wrapper and
|
||
where cv shall be neither volatile nor const volatile[.](#func.require-4.sentence-2)
|
||
|
||
[5](#func.require-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11582)
|
||
|
||
A [*call pattern*](#def:call_pattern "22.10.4 Requirements [func.require]") defines the semantics of invoking
|
||
a perfect forwarding call wrapper[.](#func.require-5.sentence-1)
|
||
|
||
A postfix call performed on a perfect forwarding call wrapper is
|
||
expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) to
|
||
an expression e determined from its call pattern cp by replacing all occurrences
|
||
of the arguments of the call wrapper and its state entities
|
||
with references as described in the corresponding forwarding steps[.](#func.require-5.sentence-2)
|
||
|
||
[6](#func.require-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11592)
|
||
|
||
A [*simple call wrapper*](#def:simple_call_wrapper "22.10.4 Requirements [func.require]") is a perfect forwarding call wrapper that meets
|
||
the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements
|
||
and whose copy constructor, move constructor, and assignment operators
|
||
are constexpr functions that do not throw exceptions[.](#func.require-6.sentence-1)
|
||
|
||
[7](#func.require-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11599)
|
||
|
||
The copy/move constructor of an argument forwarding call wrapper has
|
||
the same apparent semantics
|
||
as if memberwise copy/move of its state entities
|
||
were performed ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors"))[.](#func.require-7.sentence-1)
|
||
|
||
[*Note [2](#func.require-note-2)*:
|
||
|
||
This implies that each of the copy/move constructors has
|
||
the same exception-specification as
|
||
the corresponding implicit definition and is declared as constexpr if the corresponding implicit definition would be considered to be constexpr[.](#func.require-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[8](#func.require-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11611)
|
||
|
||
Argument forwarding call wrappers returned by
|
||
a given standard library function template have the same type
|
||
if the types of their corresponding state entities are the same[.](#func.require-8.sentence-1)
|
||
|
||
### [22.10.5](#func.invoke) invoke functions [[func.invoke]](func.invoke)
|
||
|
||
[ð](#lib:invoke)
|
||
|
||
`template<class F, class... Args>
|
||
constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
|
||
noexcept(is_nothrow_invocable_v<F, Args...>);
|
||
`
|
||
|
||
[1](#func.invoke-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11626)
|
||
|
||
*Constraints*: is_invocable_v<F, Args...> is true[.](#func.invoke-1.sentence-1)
|
||
|
||
[2](#func.invoke-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11630)
|
||
|
||
*Returns*: *INVOKE*(std::forward<F>(f), std::forward<Args>(args)...) ([[func.require]](#func.require "22.10.4 Requirements"))[.](#func.invoke-2.sentence-1)
|
||
|
||
[ð](#lib:invoke_r)
|
||
|
||
`template<class R, class F, class... Args>
|
||
constexpr R invoke_r(F&& f, Args&&... args)
|
||
noexcept(is_nothrow_invocable_r_v<R, F, Args...>);
|
||
`
|
||
|
||
[3](#func.invoke-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11643)
|
||
|
||
*Constraints*: is_invocable_r_v<R, F, Args...> is true[.](#func.invoke-3.sentence-1)
|
||
|
||
[4](#func.invoke-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11647)
|
||
|
||
*Returns*: *INVOKE*<R>(std::forward<F>(f), std::forward<Args>(args)...) ([[func.require]](#func.require "22.10.4 Requirements"))[.](#func.invoke-4.sentence-1)
|
||
|
||
### [22.10.6](#refwrap) Class template reference_wrapper [[refwrap]](refwrap)
|
||
|
||
#### [22.10.6.1](#refwrap.general) General [[refwrap.general]](refwrap.general)
|
||
|
||
[ð](#lib:reference_wrapper)
|
||
|
||
namespace std {template<class T> class reference_wrapper {public:// typesusing type = T; // [[refwrap.const]](#refwrap.const "22.10.6.2 Constructors"), constructorstemplate<class U>constexpr reference_wrapper(U&&) noexcept(*see below*); constexpr reference_wrapper(const reference_wrapper& x) noexcept; // [[refwrap.assign]](#refwrap.assign "22.10.6.3 Assignment"), assignmentconstexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept; // [[refwrap.access]](#refwrap.access "22.10.6.4 Access"), accessconstexpr operator T& () const noexcept; constexpr T& get() const noexcept; // [[refwrap.invoke]](#refwrap.invoke "22.10.6.5 Invocation"), invocationtemplate<class... ArgTypes>constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&...) constnoexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // [[refwrap.comparisons]](#refwrap.comparisons "22.10.6.6 Comparisons"), comparisonsfriend constexpr bool operator==(reference_wrapper, reference_wrapper); friend constexpr bool operator==(reference_wrapper, const T&); friend constexpr bool operator==(reference_wrapper, reference_wrapper<const T>); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); friend constexpr auto operator<=>(reference_wrapper, const T&); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper<const T>); }; template<class T> reference_wrapper(T&) -> reference_wrapper<T>;}
|
||
|
||
[1](#refwrap.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11697)
|
||
|
||
reference_wrapper<T> is a [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") wrapper
|
||
around a reference to an object or function of type T[.](#refwrap.general-1.sentence-1)
|
||
|
||
[2](#refwrap.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11701)
|
||
|
||
reference_wrapper<T> is
|
||
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General"))[.](#refwrap.general-2.sentence-1)
|
||
|
||
[3](#refwrap.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11705)
|
||
|
||
The template parameter T of reference_wrapper may be an incomplete type[.](#refwrap.general-3.sentence-1)
|
||
|
||
[*Note [1](#refwrap.general-note-1)*:
|
||
|
||
Using the comparison operators described in [[refwrap.comparisons]](#refwrap.comparisons "22.10.6.6 Comparisons") with T being an incomplete type
|
||
can lead to an ill-formed program
|
||
with no diagnostic required ([[temp.point]](temp.point "13.8.4.1 Point of instantiation"), [[temp.constr.atomic]](temp.constr.atomic "13.5.2.3 Atomic constraints"))[.](#refwrap.general-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.6.2](#refwrap.const) Constructors [[refwrap.const]](refwrap.const)
|
||
|
||
[ð](#lib:reference_wrapper,constructor)
|
||
|
||
`template<class U>
|
||
constexpr reference_wrapper(U&& u) noexcept(see below);
|
||
`
|
||
|
||
[1](#refwrap.const-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11724)
|
||
|
||
Let *FUN* denote the exposition-only functionsvoid *FUN*(T&) noexcept;void *FUN*(T&&) = delete;
|
||
|
||
[2](#refwrap.const-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11731)
|
||
|
||
*Constraints*: The expression *FUN*(declval<U>()) is well-formed andis_same_v<remove_cvref_t<U>, reference_wrapper> is false[.](#refwrap.const-2.sentence-1)
|
||
|
||
[3](#refwrap.const-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11736)
|
||
|
||
*Effects*: Creates a variable r as if by T& r = std::forward<U>(u),
|
||
then constructs a reference_wrapper object
|
||
that stores a reference to r[.](#refwrap.const-3.sentence-1)
|
||
|
||
[4](#refwrap.const-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11743)
|
||
|
||
*Remarks*: The exception specification is equivalent tonoexcept(*FUN*(declval<U>()))[.](#refwrap.const-4.sentence-1)
|
||
|
||
[ð](#lib:reference_wrapper,constructor_)
|
||
|
||
`constexpr reference_wrapper(const reference_wrapper& x) noexcept;
|
||
`
|
||
|
||
[5](#refwrap.const-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11755)
|
||
|
||
*Effects*: Constructs a reference_wrapper object that
|
||
stores a reference to x.get()[.](#refwrap.const-5.sentence-1)
|
||
|
||
#### [22.10.6.3](#refwrap.assign) Assignment [[refwrap.assign]](refwrap.assign)
|
||
|
||
[ð](#lib:operator=,reference_wrapper)
|
||
|
||
`constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept;
|
||
`
|
||
|
||
[1](#refwrap.assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11769)
|
||
|
||
*Postconditions*: *this stores a reference to x.get()[.](#refwrap.assign-1.sentence-1)
|
||
|
||
#### [22.10.6.4](#refwrap.access) Access [[refwrap.access]](refwrap.access)
|
||
|
||
[ð](#lib:operator_T&,reference_wrapper)
|
||
|
||
`constexpr operator T& () const noexcept;
|
||
`
|
||
|
||
[1](#refwrap.access-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11782)
|
||
|
||
*Returns*: The stored reference[.](#refwrap.access-1.sentence-1)
|
||
|
||
[ð](#lib:get,reference_wrapper)
|
||
|
||
`constexpr T& get() const noexcept;
|
||
`
|
||
|
||
[2](#refwrap.access-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11793)
|
||
|
||
*Returns*: The stored reference[.](#refwrap.access-2.sentence-1)
|
||
|
||
#### [22.10.6.5](#refwrap.invoke) Invocation [[refwrap.invoke]](refwrap.invoke)
|
||
|
||
[ð](#lib:operator(),reference_wrapper)
|
||
|
||
`template<class... ArgTypes>
|
||
constexpr invoke_result_t<T&, ArgTypes...>
|
||
operator()(ArgTypes&&... args) const noexcept(is_nothrow_invocable_v<T&, ArgTypes...>);
|
||
`
|
||
|
||
[1](#refwrap.invoke-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11808)
|
||
|
||
*Mandates*: T is a complete type[.](#refwrap.invoke-1.sentence-1)
|
||
|
||
[2](#refwrap.invoke-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11812)
|
||
|
||
*Returns*: *INVOKE*(get(), std::forward<ArgTypes>(args)...) ([[func.require]](#func.require "22.10.4 Requirements"))[.](#refwrap.invoke-2.sentence-1)
|
||
|
||
#### [22.10.6.6](#refwrap.comparisons) Comparisons [[refwrap.comparisons]](refwrap.comparisons)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:1)
|
||
|
||
`friend constexpr bool operator==(reference_wrapper x, reference_wrapper y);
|
||
`
|
||
|
||
[1](#refwrap.comparisons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11824)
|
||
|
||
*Constraints*: The expression x.get() == y.get() is well-formed and
|
||
its result is convertible to bool[.](#refwrap.comparisons-1.sentence-1)
|
||
|
||
[2](#refwrap.comparisons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11829)
|
||
|
||
*Returns*: x.get() == y.get()[.](#refwrap.comparisons-2.sentence-1)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:2)
|
||
|
||
`friend constexpr bool operator==(reference_wrapper x, const T& y);
|
||
`
|
||
|
||
[3](#refwrap.comparisons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11839)
|
||
|
||
*Constraints*: The expression x.get() == y is well-formed and
|
||
its result is convertible to bool[.](#refwrap.comparisons-3.sentence-1)
|
||
|
||
[4](#refwrap.comparisons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11844)
|
||
|
||
*Returns*: x.get() == y[.](#refwrap.comparisons-4.sentence-1)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:3)
|
||
|
||
`friend constexpr bool operator==(reference_wrapper x, reference_wrapper<const T> y);
|
||
`
|
||
|
||
[5](#refwrap.comparisons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11854)
|
||
|
||
*Constraints*: is_const_v<T> is false and
|
||
the expression x.get() == y.get() is well-formed and
|
||
its result is convertible to bool[.](#refwrap.comparisons-5.sentence-1)
|
||
|
||
[6](#refwrap.comparisons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11860)
|
||
|
||
*Returns*: x.get() == y.get()[.](#refwrap.comparisons-6.sentence-1)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:4)
|
||
|
||
`friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper y);
|
||
`
|
||
|
||
[7](#refwrap.comparisons-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11870)
|
||
|
||
*Constraints*: The expression *synth-three-way*(x.get(), y.get()) is well-formed[.](#refwrap.comparisons-7.sentence-1)
|
||
|
||
[8](#refwrap.comparisons-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11875)
|
||
|
||
*Returns*: *synth-three-way*(x.get(), y.get())[.](#refwrap.comparisons-8.sentence-1)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:5)
|
||
|
||
`friend constexpr auto operator<=>(reference_wrapper x, const T& y);
|
||
`
|
||
|
||
[9](#refwrap.comparisons-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11885)
|
||
|
||
*Constraints*: The expression *synth-three-way*(x.get(), y) is well-formed[.](#refwrap.comparisons-9.sentence-1)
|
||
|
||
[10](#refwrap.comparisons-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11890)
|
||
|
||
*Returns*: *synth-three-way*(x.get(), y)[.](#refwrap.comparisons-10.sentence-1)
|
||
|
||
[ð](#refwrap.comparisons-itemdecl:6)
|
||
|
||
`friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper<const T> y);
|
||
`
|
||
|
||
[11](#refwrap.comparisons-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11900)
|
||
|
||
*Constraints*: is_const_v<T> is false[.](#refwrap.comparisons-11.sentence-1)
|
||
|
||
The expression *synth-three-way*(x.get(), y.get()) is well-formed[.](#refwrap.comparisons-11.sentence-2)
|
||
|
||
[12](#refwrap.comparisons-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11906)
|
||
|
||
*Returns*: *synth-three-way*(x.get(), y.get())[.](#refwrap.comparisons-12.sentence-1)
|
||
|
||
#### [22.10.6.7](#refwrap.helpers) Helper functions [[refwrap.helpers]](refwrap.helpers)
|
||
|
||
[1](#refwrap.helpers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11913)
|
||
|
||
The template parameter T of
|
||
the following ref and cref function templates
|
||
may be an incomplete type[.](#refwrap.helpers-1.sentence-1)
|
||
|
||
[ð](#lib:ref,reference_wrapper)
|
||
|
||
`template<class T> constexpr reference_wrapper<T> ref(T& t) noexcept;
|
||
`
|
||
|
||
[2](#refwrap.helpers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11924)
|
||
|
||
*Returns*: reference_wrapper<T>(t)[.](#refwrap.helpers-2.sentence-1)
|
||
|
||
[ð](#lib:ref,reference_wrapper_)
|
||
|
||
`template<class T> constexpr reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
|
||
`
|
||
|
||
[3](#refwrap.helpers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11935)
|
||
|
||
*Returns*: t[.](#refwrap.helpers-3.sentence-1)
|
||
|
||
[ð](#lib:cref,reference_wrapper)
|
||
|
||
`template<class T> constexpr reference_wrapper<const T> cref(const T& t) noexcept;
|
||
`
|
||
|
||
[4](#refwrap.helpers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11946)
|
||
|
||
*Returns*: reference_wrapper<const T>(t)[.](#refwrap.helpers-4.sentence-1)
|
||
|
||
[ð](#lib:cref,reference_wrapper_)
|
||
|
||
`template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
|
||
`
|
||
|
||
[5](#refwrap.helpers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11957)
|
||
|
||
*Returns*: t[.](#refwrap.helpers-5.sentence-1)
|
||
|
||
#### [22.10.6.8](#refwrap.common.ref) common_reference related specializations [[refwrap.common.ref]](refwrap.common.ref)
|
||
|
||
[ð](#lib:basic_common_reference)
|
||
|
||
namespace std {template<class T>constexpr bool *is-ref-wrapper* = false; // *exposition only*template<class T>constexpr bool *is-ref-wrapper*<reference_wrapper<T>> = true; template<class R, class T, class RQ, class TQ>concept [*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_reference related specializations [refwrap.common.ref]") = // *exposition only**is-ref-wrapper*<R> &&requires { typename common_reference_t<typename R::type&, TQ>; } &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<RQ, common_reference_t<typename R::type&, TQ>>; template<class R, class T, template<class> class RQual, template<class> class TQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_reference related specializations [refwrap.common.ref]")<R, T, RQual<R>, TQual<T>> &&<T, R, TQual<T>, RQual<R>>)struct basic_common_reference<R, T, RQual, TQual> {using type = common_reference_t<typename R::type&, TQual<T>>; }; template<class T, class R, template<class> class TQual, template<class> class RQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_reference related specializations [refwrap.common.ref]")<R, T, RQual<R>, TQual<T>> &&<T, R, TQual<T>, RQual<R>>)struct basic_common_reference<T, R, TQual, RQual> {using type = common_reference_t<typename R::type&, TQual<T>>; };}
|
||
|
||
### [22.10.7](#arithmetic.operations) Arithmetic operations [[arithmetic.operations]](arithmetic.operations)
|
||
|
||
#### [22.10.7.1](#arithmetic.operations.general) General [[arithmetic.operations.general]](arithmetic.operations.general)
|
||
|
||
[1](#arithmetic.operations.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11999)
|
||
|
||
The library provides basic function object classes for all of the arithmetic
|
||
operators in the language ([[expr.mul]](expr.mul "7.6.5 Multiplicative operators"), [[expr.add]](expr.add "7.6.6 Additive operators"))[.](#arithmetic.operations.general-1.sentence-1)
|
||
|
||
#### [22.10.7.2](#arithmetic.operations.plus) Class template plus [[arithmetic.operations.plus]](arithmetic.operations.plus)
|
||
|
||
[ð](#lib:plus)
|
||
|
||
`template<class T = void> struct plus {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),plus)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.plus-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12018)
|
||
|
||
*Returns*: x + y[.](#arithmetic.operations.plus-1.sentence-1)
|
||
|
||
[ð](#lib:plus%3c%3e)
|
||
|
||
`template<> struct plus<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) + std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),plus%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) + std::forward<U>(u));
|
||
`
|
||
|
||
[2](#arithmetic.operations.plus-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12040)
|
||
|
||
*Returns*: std::forward<T>(t) + std::forward<U>(u)[.](#arithmetic.operations.plus-2.sentence-1)
|
||
|
||
#### [22.10.7.3](#arithmetic.operations.minus) Class template minus [[arithmetic.operations.minus]](arithmetic.operations.minus)
|
||
|
||
[ð](#lib:minus)
|
||
|
||
`template<class T = void> struct minus {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),minus)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.minus-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12060)
|
||
|
||
*Returns*: x - y[.](#arithmetic.operations.minus-1.sentence-1)
|
||
|
||
[ð](#lib:minus%3c%3e)
|
||
|
||
`template<> struct minus<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) - std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),minus%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) - std::forward<U>(u));
|
||
`
|
||
|
||
[2](#arithmetic.operations.minus-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12082)
|
||
|
||
*Returns*: std::forward<T>(t) - std::forward<U>(u)[.](#arithmetic.operations.minus-2.sentence-1)
|
||
|
||
#### [22.10.7.4](#arithmetic.operations.multiplies) Class template multiplies [[arithmetic.operations.multiplies]](arithmetic.operations.multiplies)
|
||
|
||
[ð](#lib:multiplies)
|
||
|
||
`template<class T = void> struct multiplies {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),multiplies)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.multiplies-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12102)
|
||
|
||
*Returns*: x * y[.](#arithmetic.operations.multiplies-1.sentence-1)
|
||
|
||
[ð](#lib:multiplies%3c%3e)
|
||
|
||
`template<> struct multiplies<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) * std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),multiplies%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) * std::forward<U>(u));
|
||
`
|
||
|
||
[2](#arithmetic.operations.multiplies-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12124)
|
||
|
||
*Returns*: std::forward<T>(t) * std::forward<U>(u)[.](#arithmetic.operations.multiplies-2.sentence-1)
|
||
|
||
#### [22.10.7.5](#arithmetic.operations.divides) Class template divides [[arithmetic.operations.divides]](arithmetic.operations.divides)
|
||
|
||
[ð](#lib:divides)
|
||
|
||
`template<class T = void> struct divides {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),divides)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.divides-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12144)
|
||
|
||
*Returns*: x / y[.](#arithmetic.operations.divides-1.sentence-1)
|
||
|
||
[ð](#lib:divides%3c%3e)
|
||
|
||
`template<> struct divides<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) / std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),divides%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) / std::forward<U>(u));
|
||
`
|
||
|
||
[2](#arithmetic.operations.divides-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12166)
|
||
|
||
*Returns*: std::forward<T>(t) / std::forward<U>(u)[.](#arithmetic.operations.divides-2.sentence-1)
|
||
|
||
#### [22.10.7.6](#arithmetic.operations.modulus) Class template modulus [[arithmetic.operations.modulus]](arithmetic.operations.modulus)
|
||
|
||
[ð](#lib:modulus)
|
||
|
||
`template<class T = void> struct modulus {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),modulus)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.modulus-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12186)
|
||
|
||
*Returns*: x % y[.](#arithmetic.operations.modulus-1.sentence-1)
|
||
|
||
[ð](#lib:modulus%3c%3e)
|
||
|
||
`template<> struct modulus<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) % std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),modulus%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) % std::forward<U>(u));
|
||
`
|
||
|
||
[2](#arithmetic.operations.modulus-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12208)
|
||
|
||
*Returns*: std::forward<T>(t) % std::forward<U>(u)[.](#arithmetic.operations.modulus-2.sentence-1)
|
||
|
||
#### [22.10.7.7](#arithmetic.operations.negate) Class template negate [[arithmetic.operations.negate]](arithmetic.operations.negate)
|
||
|
||
[ð](#lib:negate)
|
||
|
||
`template<class T = void> struct negate {
|
||
constexpr T operator()(const T& x) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),negate)
|
||
|
||
`constexpr T operator()(const T& x) const;
|
||
`
|
||
|
||
[1](#arithmetic.operations.negate-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12228)
|
||
|
||
*Returns*: -x[.](#arithmetic.operations.negate-1.sentence-1)
|
||
|
||
[ð](#lib:negate%3c%3e)
|
||
|
||
`template<> struct negate<void> {
|
||
template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(-std::forward<T>(t));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),negate%3c%3e)
|
||
|
||
`template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(-std::forward<T>(t));
|
||
`
|
||
|
||
[2](#arithmetic.operations.negate-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12250)
|
||
|
||
*Returns*: -std::forward<T>(t)[.](#arithmetic.operations.negate-2.sentence-1)
|
||
|
||
### [22.10.8](#comparisons) Comparisons [[comparisons]](comparisons)
|
||
|
||
#### [22.10.8.1](#comparisons.general) General [[comparisons.general]](comparisons.general)
|
||
|
||
[1](#comparisons.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12260)
|
||
|
||
The library provides basic function object classes for all of the comparison
|
||
operators in the language ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality operators"))[.](#comparisons.general-1.sentence-1)
|
||
|
||
[2](#comparisons.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12264)
|
||
|
||
For templates less, greater, less_equal, andgreater_equal, the specializations for any pointer type
|
||
yield a result consistent with the
|
||
implementation-defined strict total order over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers"))[.](#comparisons.general-2.sentence-1)
|
||
|
||
[*Note [1](#comparisons.general-note-1)*:
|
||
|
||
If a < b is well-defined
|
||
for pointers a and b of type P,
|
||
then (a < b) == less<P>()(a, b),(a > b) == greater<P>()(a, b), and so forth[.](#comparisons.general-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
For template specializations less<void>, greater<void>,less_equal<void>, and greater_equal<void>,
|
||
if the call operator calls a built-in operator comparing pointers,
|
||
the call operator yields a result consistent
|
||
with the implementation-defined strict total order over pointers[.](#comparisons.general-2.sentence-3)
|
||
|
||
#### [22.10.8.2](#comparisons.equal.to) Class template equal_to [[comparisons.equal.to]](comparisons.equal.to)
|
||
|
||
[ð](#lib:equal_to)
|
||
|
||
`template<class T = void> struct equal_to {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),equal_to)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.equal.to-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12296)
|
||
|
||
*Returns*: x == y[.](#comparisons.equal.to-1.sentence-1)
|
||
|
||
[ð](#lib:equal_to%3c%3e)
|
||
|
||
`template<> struct equal_to<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) == std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),equal_to%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) == std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.equal.to-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12318)
|
||
|
||
*Returns*: std::forward<T>(t) == std::forward<U>(u)[.](#comparisons.equal.to-2.sentence-1)
|
||
|
||
#### [22.10.8.3](#comparisons.not.equal.to) Class template not_equal_to [[comparisons.not.equal.to]](comparisons.not.equal.to)
|
||
|
||
[ð](#lib:not_equal_to)
|
||
|
||
`template<class T = void> struct not_equal_to {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),not_equal_to)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.not.equal.to-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12338)
|
||
|
||
*Returns*: x != y[.](#comparisons.not.equal.to-1.sentence-1)
|
||
|
||
[ð](#lib:not_equal_to%3c%3e)
|
||
|
||
`template<> struct not_equal_to<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) != std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),not_equal_to%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) != std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.not.equal.to-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12360)
|
||
|
||
*Returns*: std::forward<T>(t) != std::forward<U>(u)[.](#comparisons.not.equal.to-2.sentence-1)
|
||
|
||
#### [22.10.8.4](#comparisons.greater) Class template greater [[comparisons.greater]](comparisons.greater)
|
||
|
||
[ð](#lib:greater)
|
||
|
||
`template<class T = void> struct greater {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),greater)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.greater-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12380)
|
||
|
||
*Returns*: x > y[.](#comparisons.greater-1.sentence-1)
|
||
|
||
[ð](#lib:greater%3c%3e)
|
||
|
||
`template<> struct greater<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) > std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),greater%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) > std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.greater-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12402)
|
||
|
||
*Returns*: std::forward<T>(t) > std::forward<U>(u)[.](#comparisons.greater-2.sentence-1)
|
||
|
||
#### [22.10.8.5](#comparisons.less) Class template less [[comparisons.less]](comparisons.less)
|
||
|
||
[ð](#lib:less)
|
||
|
||
`template<class T = void> struct less {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),less)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.less-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12422)
|
||
|
||
*Returns*: x < y[.](#comparisons.less-1.sentence-1)
|
||
|
||
[ð](#lib:less%3c%3e)
|
||
|
||
`template<> struct less<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) < std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),less%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) < std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.less-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12444)
|
||
|
||
*Returns*: std::forward<T>(t) < std::forward<U>(u)[.](#comparisons.less-2.sentence-1)
|
||
|
||
#### [22.10.8.6](#comparisons.greater.equal) Class template greater_equal [[comparisons.greater.equal]](comparisons.greater.equal)
|
||
|
||
[ð](#lib:greater_equal)
|
||
|
||
`template<class T = void> struct greater_equal {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),greater_equal)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.greater.equal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12464)
|
||
|
||
*Returns*: x >= y[.](#comparisons.greater.equal-1.sentence-1)
|
||
|
||
[ð](#lib:greater_equal%3c%3e)
|
||
|
||
`template<> struct greater_equal<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) >= std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),greater_equal%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) >= std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.greater.equal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12486)
|
||
|
||
*Returns*: std::forward<T>(t) >= std::forward<U>(u)[.](#comparisons.greater.equal-2.sentence-1)
|
||
|
||
#### [22.10.8.7](#comparisons.less.equal) Class template less_equal [[comparisons.less.equal]](comparisons.less.equal)
|
||
|
||
[ð](#lib:less_equal)
|
||
|
||
`template<class T = void> struct less_equal {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),less_equal)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#comparisons.less.equal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12506)
|
||
|
||
*Returns*: x <= y[.](#comparisons.less.equal-1.sentence-1)
|
||
|
||
[ð](#lib:less_equal%3c%3e)
|
||
|
||
`template<> struct less_equal<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) <= std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),less_equal%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) <= std::forward<U>(u));
|
||
`
|
||
|
||
[2](#comparisons.less.equal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12528)
|
||
|
||
*Returns*: std::forward<T>(t) <= std::forward<U>(u)[.](#comparisons.less.equal-2.sentence-1)
|
||
|
||
#### [22.10.8.8](#comparisons.three.way) Class compare_three_way [[comparisons.three.way]](comparisons.three.way)
|
||
|
||
[ð](#lib:compare_three_way)
|
||
|
||
namespace std {struct compare_three_way {template<class T, class U>constexpr auto operator()(T&& t, U&& u) const; using is_transparent = *unspecified*; };}
|
||
|
||
[ð](#comparisons.three.way-itemdecl:1)
|
||
|
||
`template<class T, class U>
|
||
constexpr auto operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[1](#comparisons.three.way-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12553)
|
||
|
||
*Constraints*: T and U satisfy [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_way_comparable [cmp.concept]")[.](#comparisons.three.way-1.sentence-1)
|
||
|
||
[2](#comparisons.three.way-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12557)
|
||
|
||
*Preconditions*: If the expression std::forward<T>(t) <=> std::forward<U>(u) results in
|
||
a call to a built-in operator <=> comparing pointers of type P,
|
||
the conversion sequences from both T and U to P are equality-preserving ([[concepts.equality]](concepts.equality "18.2 Equality preservation"));
|
||
otherwise, T and U model [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_way_comparable [cmp.concept]")[.](#comparisons.three.way-2.sentence-1)
|
||
|
||
[3](#comparisons.three.way-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12565)
|
||
|
||
*Effects*:
|
||
|
||
- [(3.1)](#comparisons.three.way-3.1)
|
||
|
||
If the expression std::forward<T>(t) <=> std::forward<U>(u) results in
|
||
a call to a built-in operator <=> comparing pointers of type P,
|
||
returns strong_ordering::less if (the converted value of) t precedes u in the implementation-defined strict total order
|
||
over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers")), strong_ordering::greater if u precedes t, and
|
||
otherwise strong_ordering::equal.
|
||
|
||
- [(3.2)](#comparisons.three.way-3.2)
|
||
|
||
Otherwise, equivalent to: return std::forward<T>(t) <=> std::forward<U>(u);
|
||
|
||
### [22.10.9](#range.cmp) Concept-constrained comparisons [[range.cmp]](range.cmp)
|
||
|
||
[ð](#lib:equal_to_)
|
||
|
||
struct ranges::equal_to {template<class T, class U>constexpr bool operator()(T&& t, U&& u) const; using is_transparent = *unspecified*;};
|
||
|
||
[ð](#range.cmp-itemdecl:1)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[1](#range.cmp-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12601)
|
||
|
||
*Constraints*: T and U satisfy [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")[.](#range.cmp-1.sentence-1)
|
||
|
||
[2](#range.cmp-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12605)
|
||
|
||
*Preconditions*: If the expression std::forward<T>(t) == std::forward<U>(u) results in a call to a built-in operator == comparing pointers of typeP, the conversion sequences from both T and U to P are equality-preserving ([[concepts.equality]](concepts.equality "18.2 Equality preservation"));
|
||
otherwise, T and U model [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")[.](#range.cmp-2.sentence-1)
|
||
|
||
[3](#range.cmp-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12613)
|
||
|
||
*Effects*:
|
||
|
||
- [(3.1)](#range.cmp-3.1)
|
||
|
||
If the expression std::forward<T>(t) == std::forward<U>(u) results in
|
||
a call to a built-in operator == comparing pointers:
|
||
returns false if either (the converted value of) t precedes u or u precedes t in the implementation-defined strict
|
||
total order over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers")) and otherwise true.
|
||
|
||
- [(3.2)](#range.cmp-3.2)
|
||
|
||
Otherwise, equivalent to: return std::forward<T>(t) == std::forward<U>(u);
|
||
|
||
[ð](#lib:not_equal_to_)
|
||
|
||
struct ranges::not_equal_to {template<class T, class U>constexpr bool operator()(T&& t, U&& u) const; using is_transparent = *unspecified*;};
|
||
|
||
[ð](#range.cmp-itemdecl:2)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[4](#range.cmp-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12645)
|
||
|
||
*Constraints*: T and U satisfy [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")[.](#range.cmp-4.sentence-1)
|
||
|
||
[5](#range.cmp-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12649)
|
||
|
||
*Effects*: Equivalent to:return !ranges::equal_to{}(std::forward<T>(t), std::forward<U>(u));
|
||
|
||
[ð](#lib:greater_)
|
||
|
||
struct ranges::greater {template<class T, class U>constexpr bool operator()(T&& t, U&& u) const; using is_transparent = *unspecified*;};
|
||
|
||
[ð](#range.cmp-itemdecl:3)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[6](#range.cmp-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12673)
|
||
|
||
*Constraints*: T and U satisfy [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_ordered [concept.totallyordered]")[.](#range.cmp-6.sentence-1)
|
||
|
||
[7](#range.cmp-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12677)
|
||
|
||
*Effects*: Equivalent to:return ranges::less{}(std::forward<U>(u), std::forward<T>(t));
|
||
|
||
[ð](#lib:less_)
|
||
|
||
struct ranges::less {template<class T, class U>constexpr bool operator()(T&& t, U&& u) const; using is_transparent = *unspecified*;};
|
||
|
||
[ð](#range.cmp-itemdecl:4)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[8](#range.cmp-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12701)
|
||
|
||
*Constraints*: T and U satisfy [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_ordered [concept.totallyordered]")[.](#range.cmp-8.sentence-1)
|
||
|
||
[9](#range.cmp-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12705)
|
||
|
||
*Preconditions*: If the expression std::forward<T>(t) < std::forward<U>(u) results in a
|
||
call to a built-in operator < comparing pointers of type P, the
|
||
conversion sequences from both T and U to P are
|
||
equality-preserving ([[concepts.equality]](concepts.equality "18.2 Equality preservation"));
|
||
otherwise, T and U model [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_ordered [concept.totallyordered]")[.](#range.cmp-9.sentence-1)
|
||
|
||
For any expressionsET and EU such that decltype((ET)) is T anddecltype((EU)) is U, exactly one ofranges::less{}(ET, EU),ranges::less{}(EU, ET), orranges::equal_to{}(ET, EU) is true[.](#range.cmp-9.sentence-2)
|
||
|
||
[10](#range.cmp-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12720)
|
||
|
||
*Effects*:
|
||
|
||
- [(10.1)](#range.cmp-10.1)
|
||
|
||
If the expression std::forward<T>(t) < std::forward<U>(u) results in a
|
||
call to a built-in operator < comparing pointers:
|
||
returns true if (the converted value of) t precedes u in
|
||
the implementation-defined strict total order over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers"))
|
||
and otherwise false.
|
||
|
||
- [(10.2)](#range.cmp-10.2)
|
||
|
||
Otherwise, equivalent to:return std::forward<T>(t) < std::forward<U>(u);
|
||
|
||
[ð](#lib:greater_equal_)
|
||
|
||
struct ranges::greater_equal {template<class T, class U>constexpr bool operator()(T&& t, U&& u) const; using is_transparent = *unspecified*;};
|
||
|
||
[ð](#range.cmp-itemdecl:5)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[11](#range.cmp-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12752)
|
||
|
||
*Constraints*: T and U satisfy [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_ordered [concept.totallyordered]")[.](#range.cmp-11.sentence-1)
|
||
|
||
[12](#range.cmp-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12756)
|
||
|
||
*Effects*: Equivalent to:return !ranges::less{}(std::forward<T>(t), std::forward<U>(u));
|
||
|
||
[ð](#lib:less_equal_)
|
||
|
||
`struct ranges::less_equal {
|
||
template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#range.cmp-itemdecl:7)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator()(T&& t, U&& u) const;
|
||
`
|
||
|
||
[13](#range.cmp-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12780)
|
||
|
||
*Constraints*: T and U satisfy [totally_ordered_with](concept.totallyordered#concept:totally_ordered_with "18.5.5 Concept totally_ordered [concept.totallyordered]")[.](#range.cmp-13.sentence-1)
|
||
|
||
[14](#range.cmp-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12784)
|
||
|
||
*Effects*: Equivalent to:return !ranges::less{}(std::forward<U>(u), std::forward<T>(t));
|
||
|
||
### [22.10.10](#logical.operations) Logical operations [[logical.operations]](logical.operations)
|
||
|
||
#### [22.10.10.1](#logical.operations.general) General [[logical.operations.general]](logical.operations.general)
|
||
|
||
[1](#logical.operations.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12796)
|
||
|
||
The library provides basic function object classes for all of the logical
|
||
operators in the language ([[expr.log.and]](expr.log.and "7.6.14 Logical AND operator"), [[expr.log.or]](expr.log.or "7.6.15 Logical OR operator"), [[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators"))[.](#logical.operations.general-1.sentence-1)
|
||
|
||
#### [22.10.10.2](#logical.operations.and) Class template logical_and [[logical.operations.and]](logical.operations.and)
|
||
|
||
[ð](#lib:logical_and)
|
||
|
||
`template<class T = void> struct logical_and {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_and)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#logical.operations.and-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12815)
|
||
|
||
*Returns*: x && y[.](#logical.operations.and-1.sentence-1)
|
||
|
||
[ð](#lib:logical_and%3c%3e)
|
||
|
||
`template<> struct logical_and<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) && std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_and%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) && std::forward<U>(u));
|
||
`
|
||
|
||
[2](#logical.operations.and-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12837)
|
||
|
||
*Returns*: std::forward<T>(t) && std::forward<U>(u)[.](#logical.operations.and-2.sentence-1)
|
||
|
||
#### [22.10.10.3](#logical.operations.or) Class template logical_or [[logical.operations.or]](logical.operations.or)
|
||
|
||
[ð](#lib:logical_or)
|
||
|
||
`template<class T = void> struct logical_or {
|
||
constexpr bool operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_or)
|
||
|
||
`constexpr bool operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#logical.operations.or-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12857)
|
||
|
||
*Returns*: x || y[.](#logical.operations.or-1.sentence-1)
|
||
|
||
[ð](#lib:logical_or%3c%3e)
|
||
|
||
`template<> struct logical_or<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) || std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_or%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) || std::forward<U>(u));
|
||
`
|
||
|
||
[2](#logical.operations.or-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12879)
|
||
|
||
*Returns*: std::forward<T>(t) || std::forward<U>(u)[.](#logical.operations.or-2.sentence-1)
|
||
|
||
#### [22.10.10.4](#logical.operations.not) Class template logical_not [[logical.operations.not]](logical.operations.not)
|
||
|
||
[ð](#lib:logical_not)
|
||
|
||
`template<class T = void> struct logical_not {
|
||
constexpr bool operator()(const T& x) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_not)
|
||
|
||
`constexpr bool operator()(const T& x) const;
|
||
`
|
||
|
||
[1](#logical.operations.not-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12899)
|
||
|
||
*Returns*: !x[.](#logical.operations.not-1.sentence-1)
|
||
|
||
[ð](#lib:logical_not%3c%3e)
|
||
|
||
`template<> struct logical_not<void> {
|
||
template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(!std::forward<T>(t));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),logical_not%3c%3e)
|
||
|
||
`template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(!std::forward<T>(t));
|
||
`
|
||
|
||
[2](#logical.operations.not-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12921)
|
||
|
||
*Returns*: !std::forward<T>(t)[.](#logical.operations.not-2.sentence-1)
|
||
|
||
### [22.10.11](#bitwise.operations) Bitwise operations [[bitwise.operations]](bitwise.operations)
|
||
|
||
#### [22.10.11.1](#bitwise.operations.general) General [[bitwise.operations.general]](bitwise.operations.general)
|
||
|
||
[1](#bitwise.operations.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12931)
|
||
|
||
The library provides basic function object classes for all of the bitwise
|
||
operators in the language ([[expr.bit.and]](expr.bit.and "7.6.11 Bitwise AND operator"), [[expr.or]](expr.or "7.6.13 Bitwise inclusive OR operator"), [[expr.xor]](expr.xor "7.6.12 Bitwise exclusive OR operator"), [[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators"))[.](#bitwise.operations.general-1.sentence-1)
|
||
|
||
#### [22.10.11.2](#bitwise.operations.and) Class template bit_and [[bitwise.operations.and]](bitwise.operations.and)
|
||
|
||
[ð](#lib:bit_and)
|
||
|
||
`template<class T = void> struct bit_and {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_and)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#bitwise.operations.and-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12950)
|
||
|
||
*Returns*: x & y[.](#bitwise.operations.and-1.sentence-1)
|
||
|
||
[ð](#lib:bit_and%3c%3e)
|
||
|
||
`template<> struct bit_and<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) & std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_and%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) & std::forward<U>(u));
|
||
`
|
||
|
||
[2](#bitwise.operations.and-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12972)
|
||
|
||
*Returns*: std::forward<T>(t) & std::forward<U>(u)[.](#bitwise.operations.and-2.sentence-1)
|
||
|
||
#### [22.10.11.3](#bitwise.operations.or) Class template bit_or [[bitwise.operations.or]](bitwise.operations.or)
|
||
|
||
[ð](#lib:bit_or)
|
||
|
||
`template<class T = void> struct bit_or {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_or)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#bitwise.operations.or-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12992)
|
||
|
||
*Returns*: x | y[.](#bitwise.operations.or-1.sentence-1)
|
||
|
||
[ð](#lib:bit_or%3c%3e)
|
||
|
||
`template<> struct bit_or<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) | std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_or%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) | std::forward<U>(u));
|
||
`
|
||
|
||
[2](#bitwise.operations.or-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13014)
|
||
|
||
*Returns*: std::forward<T>(t) | std::forward<U>(u)[.](#bitwise.operations.or-2.sentence-1)
|
||
|
||
#### [22.10.11.4](#bitwise.operations.xor) Class template bit_xor [[bitwise.operations.xor]](bitwise.operations.xor)
|
||
|
||
[ð](#lib:bit_xor)
|
||
|
||
`template<class T = void> struct bit_xor {
|
||
constexpr T operator()(const T& x, const T& y) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_xor)
|
||
|
||
`constexpr T operator()(const T& x, const T& y) const;
|
||
`
|
||
|
||
[1](#bitwise.operations.xor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13034)
|
||
|
||
*Returns*: x ^ y[.](#bitwise.operations.xor-1.sentence-1)
|
||
|
||
[ð](#lib:bit_xor%3c%3e)
|
||
|
||
`template<> struct bit_xor<void> {
|
||
template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) ^ std::forward<U>(u));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_xor%3c%3e)
|
||
|
||
`template<class T, class U> constexpr auto operator()(T&& t, U&& u) const
|
||
-> decltype(std::forward<T>(t) ^ std::forward<U>(u));
|
||
`
|
||
|
||
[2](#bitwise.operations.xor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13056)
|
||
|
||
*Returns*: std::forward<T>(t) ^ std::forward<U>(u)[.](#bitwise.operations.xor-2.sentence-1)
|
||
|
||
#### [22.10.11.5](#bitwise.operations.not) Class template bit_not [[bitwise.operations.not]](bitwise.operations.not)
|
||
|
||
[ð](#bitwise.operations.not-itemdecl:1)
|
||
|
||
`template<class T = void> struct bit_not {
|
||
constexpr T operator()(const T& x) const;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_not)
|
||
|
||
`constexpr T operator()(const T& x) const;
|
||
`
|
||
|
||
[1](#bitwise.operations.not-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13075)
|
||
|
||
*Returns*: ~x[.](#bitwise.operations.not-1.sentence-1)
|
||
|
||
[ð](#lib:bit_not%3c%3e)
|
||
|
||
`template<> struct bit_not<void> {
|
||
template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(~std::forward<T>(t));
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
`
|
||
|
||
[ð](#lib:operator(),bit_not%3c%3e)
|
||
|
||
`template<class T> constexpr auto operator()(T&& t) const
|
||
-> decltype(~std::forward<T>(t));
|
||
`
|
||
|
||
[2](#bitwise.operations.not-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13097)
|
||
|
||
*Returns*: ~std::forward<T>(t)[.](#bitwise.operations.not-2.sentence-1)
|
||
|
||
### [22.10.12](#func.identity) Class identity [[func.identity]](func.identity)
|
||
|
||
[ð](#lib:identity)
|
||
|
||
`struct identity {
|
||
template<class T>
|
||
constexpr T&& operator()(T&& t) const noexcept;
|
||
|
||
using is_transparent = unspecified;
|
||
};
|
||
|
||
template<class T>
|
||
constexpr T&& operator()(T&& t) const noexcept;
|
||
`
|
||
|
||
[1](#func.identity-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13119)
|
||
|
||
*Effects*: Equivalent to: return std::forward<T>(t);
|
||
|
||
### [22.10.13](#func.not.fn) Function template not_fn [[func.not.fn]](func.not.fn)
|
||
|
||
[ð](#lib:not_fn)
|
||
|
||
`template<class F> constexpr unspecified not_fn(F&& f);
|
||
`
|
||
|
||
[1](#func.not.fn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13133)
|
||
|
||
In the text that follows:
|
||
|
||
- [(1.1)](#func.not.fn-1.1)
|
||
|
||
g is a value of the result of a not_fn invocation,
|
||
|
||
- [(1.2)](#func.not.fn-1.2)
|
||
|
||
FD is the type decay_t<F>,
|
||
|
||
- [(1.3)](#func.not.fn-1.3)
|
||
|
||
fd is the target object of g ([[func.def]](#func.def "22.10.3 Definitions"))
|
||
of type FD,
|
||
direct-non-list-initialized with std::forward<F>(f),
|
||
|
||
- [(1.4)](#func.not.fn-1.4)
|
||
|
||
call_args is an argument pack
|
||
used in a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call")) of g[.](#func.not.fn-1.sentence-1)
|
||
|
||
[2](#func.not.fn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13145)
|
||
|
||
*Mandates*: is_constructible_v<FD, F> && is_move_constructible_v<FD> is true[.](#func.not.fn-2.sentence-1)
|
||
|
||
[3](#func.not.fn-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13150)
|
||
|
||
*Preconditions*: FD meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.not.fn-3.sentence-1)
|
||
|
||
[4](#func.not.fn-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13154)
|
||
|
||
*Returns*: A perfect forwarding call wrapper ([[func.require]](#func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements")) g with call pattern !invoke(fd, call_args...)[.](#func.not.fn-4.sentence-1)
|
||
|
||
[5](#func.not.fn-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13159)
|
||
|
||
*Throws*: Any exception thrown by the initialization of fd[.](#func.not.fn-5.sentence-1)
|
||
|
||
[ð](#lib:not_fn_)
|
||
|
||
`template<auto f> constexpr unspecified not_fn() noexcept;
|
||
`
|
||
|
||
[6](#func.not.fn-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13170)
|
||
|
||
In the text that follows:
|
||
|
||
- [(6.1)](#func.not.fn-6.1)
|
||
|
||
F is the type of f,
|
||
|
||
- [(6.2)](#func.not.fn-6.2)
|
||
|
||
g is a value of the result of a not_fn invocation,
|
||
|
||
- [(6.3)](#func.not.fn-6.3)
|
||
|
||
call_args is an argument pack
|
||
used in a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call")) of g[.](#func.not.fn-6.sentence-1)
|
||
|
||
[7](#func.not.fn-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13182)
|
||
|
||
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
|
||
then f != nullptr is true[.](#func.not.fn-7.sentence-1)
|
||
|
||
[8](#func.not.fn-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13187)
|
||
|
||
*Returns*: A perfect forwarding call wrapper ([[func.require]](#func.require "22.10.4 Requirements")) g that
|
||
does not have state entities, and
|
||
has the call pattern !invoke(f, call_args...)[.](#func.not.fn-8.sentence-1)
|
||
|
||
### [22.10.14](#func.bind.partial) Function templates bind_front and bind_back [[func.bind.partial]](func.bind.partial)
|
||
|
||
[ð](#lib:bind_front)
|
||
|
||
`template<class F, class... Args>
|
||
constexpr unspecified bind_front(F&& f, Args&&... args);
|
||
template<class F, class... Args>
|
||
constexpr unspecified bind_back(F&& f, Args&&... args);
|
||
`
|
||
|
||
[1](#func.bind.partial-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13206)
|
||
|
||
Within this subclause:
|
||
|
||
- [(1.1)](#func.bind.partial-1.1)
|
||
|
||
g is a value of
|
||
the result of a bind_front or bind_back invocation,
|
||
|
||
- [(1.2)](#func.bind.partial-1.2)
|
||
|
||
FD is the type decay_t<F>,
|
||
|
||
- [(1.3)](#func.bind.partial-1.3)
|
||
|
||
fd is the target object of g ([[func.def]](#func.def "22.10.3 Definitions"))
|
||
of type FD,
|
||
direct-non-list-initialized with std::forward<F>(f),
|
||
|
||
- [(1.4)](#func.bind.partial-1.4)
|
||
|
||
BoundArgs is a pack
|
||
that denotes decay_t<Args>...,
|
||
|
||
- [(1.5)](#func.bind.partial-1.5)
|
||
|
||
bound_args is
|
||
a pack of bound argument entities of g ([[func.def]](#func.def "22.10.3 Definitions"))
|
||
of types BoundArgs...,
|
||
direct-non-list-initialized with std::forward<Args>(args)...,
|
||
respectively, and
|
||
|
||
- [(1.6)](#func.bind.partial-1.6)
|
||
|
||
call_args is an argument pack used in
|
||
a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call")) of g[.](#func.bind.partial-1.sentence-1)
|
||
|
||
[2](#func.bind.partial-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13226)
|
||
|
||
*Mandates*: is_constructible_v<FD, F> && is_move_constructible_v<FD> &&(is_constructible_v<BoundArgs, Args> && ...) &&(is_move_constructible_v<BoundArgs> && ...) is true[.](#func.bind.partial-2.sentence-1)
|
||
|
||
[3](#func.bind.partial-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13236)
|
||
|
||
*Preconditions*: FD meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.bind.partial-3.sentence-1)
|
||
|
||
For each Ti in BoundArgs,
|
||
if Ti is an object type,Ti meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.bind.partial-3.sentence-2)
|
||
|
||
[4](#func.bind.partial-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13243)
|
||
|
||
*Returns*: A perfect forwarding call wrapper ([[func.require]](#func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements")) g with call pattern:
|
||
|
||
- [(4.1)](#func.bind.partial-4.1)
|
||
|
||
invoke(fd, bound_args..., call_args...) for a bind_front invocation, or
|
||
|
||
- [(4.2)](#func.bind.partial-4.2)
|
||
|
||
invoke(fd, call_args..., bound_args...) for a bind_back invocation[.](#func.bind.partial-4.sentence-1)
|
||
|
||
[5](#func.bind.partial-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13256)
|
||
|
||
*Throws*: Any exception thrown by
|
||
the initialization of the state entities of g ([[func.def]](#func.def "22.10.3 Definitions"))[.](#func.bind.partial-5.sentence-1)
|
||
|
||
[ð](#lib:bind_front_)
|
||
|
||
`template<auto f, class... Args>
|
||
constexpr unspecified bind_front(Args&&... args);
|
||
template<auto f, class... Args>
|
||
constexpr unspecified bind_back(Args&&... args);
|
||
`
|
||
|
||
[6](#func.bind.partial-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13272)
|
||
|
||
Within this subclause:
|
||
|
||
- [(6.1)](#func.bind.partial-6.1)
|
||
|
||
F is the type of f,
|
||
|
||
- [(6.2)](#func.bind.partial-6.2)
|
||
|
||
g is a value of the result of
|
||
a bind_front or bind_back invocation,
|
||
|
||
- [(6.3)](#func.bind.partial-6.3)
|
||
|
||
BoundArgs is a pack that denotes decay_t<Args>...,
|
||
|
||
- [(6.4)](#func.bind.partial-6.4)
|
||
|
||
bound_args is a pack of bound argument entities ofg ([[func.def]](#func.def "22.10.3 Definitions")) of types BoundArgs...,
|
||
direct-non-list-initialized with std::forward<Args>(args)...,
|
||
respectively, and
|
||
|
||
- [(6.5)](#func.bind.partial-6.5)
|
||
|
||
call_args is an argument pack used in
|
||
a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call")) of g[.](#func.bind.partial-6.sentence-1)
|
||
|
||
[7](#func.bind.partial-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13292)
|
||
|
||
*Mandates*:
|
||
|
||
- [(7.1)](#func.bind.partial-7.1)
|
||
|
||
(is_constructible_v<BoundArgs, Args> && ...) is true, and
|
||
|
||
- [(7.2)](#func.bind.partial-7.2)
|
||
|
||
(is_move_constructible_v<BoundArgs> && ...) is true, and
|
||
|
||
- [(7.3)](#func.bind.partial-7.3)
|
||
|
||
if is_pointer_v<F> || is_member_pointer_v<F> is true,
|
||
then f != nullptr is true[.](#func.bind.partial-7.sentence-1)
|
||
|
||
[8](#func.bind.partial-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13304)
|
||
|
||
*Preconditions*: For each Ti in BoundArgs,Ti meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.bind.partial-8.sentence-1)
|
||
|
||
[9](#func.bind.partial-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13309)
|
||
|
||
*Returns*: A perfect forwarding call wrapper ([[func.require]](#func.require "22.10.4 Requirements")) g that
|
||
does not have a target object, and has the call pattern:
|
||
|
||
- [(9.1)](#func.bind.partial-9.1)
|
||
|
||
invoke(f, bound_args..., call_args...) for a bind_front invocation, or
|
||
|
||
- [(9.2)](#func.bind.partial-9.2)
|
||
|
||
invoke(f, call_args..., bound_args...) for a bind_back invocation[.](#func.bind.partial-9.sentence-1)
|
||
|
||
[10](#func.bind.partial-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13322)
|
||
|
||
*Throws*: Any exception thrown by the initialization of bound_args[.](#func.bind.partial-10.sentence-1)
|
||
|
||
### [22.10.15](#func.bind) Function object binders [[func.bind]](func.bind)
|
||
|
||
#### [22.10.15.1](#func.bind.general) General [[func.bind.general]](func.bind.general)
|
||
|
||
[1](#func.bind.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13332)
|
||
|
||
Subclause [[func.bind]](#func.bind "22.10.15 Function object binders") describes a uniform mechanism for binding
|
||
arguments of callable objects[.](#func.bind.general-1.sentence-1)
|
||
|
||
#### [22.10.15.2](#func.bind.isbind) Class template is_bind_expression [[func.bind.isbind]](func.bind.isbind)
|
||
|
||
[ð](#lib:is_bind_expression)
|
||
|
||
namespace std {template<class T> struct is_bind_expression; // see below}
|
||
|
||
[1](#func.bind.isbind-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13345)
|
||
|
||
The class template is_bind_expression can be used to detect function objects
|
||
generated by bind[.](#func.bind.isbind-1.sentence-1)
|
||
|
||
The function template bind uses is_bind_expression to detect subexpressions[.](#func.bind.isbind-1.sentence-2)
|
||
|
||
[2](#func.bind.isbind-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13350)
|
||
|
||
Specializations of the is_bind_expression template shall meet
|
||
the [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#func.bind.isbind-2.sentence-1)
|
||
|
||
The implementation
|
||
provides a definition that has a base characteristic oftrue_type if T is a type returned from bind,
|
||
otherwise it has a base characteristic of false_type[.](#func.bind.isbind-2.sentence-2)
|
||
|
||
A program may specialize this template for a program-defined type T to have a base characteristic of true_type to indicate thatT should be treated as a subexpression in a bind call[.](#func.bind.isbind-2.sentence-3)
|
||
|
||
#### [22.10.15.3](#func.bind.isplace) Class template is_placeholder [[func.bind.isplace]](func.bind.isplace)
|
||
|
||
[ð](#lib:is_placeholder)
|
||
|
||
namespace std {template<class T> struct is_placeholder; // see below}
|
||
|
||
[1](#func.bind.isplace-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13369)
|
||
|
||
The class template is_placeholder can be used to detect the standard placeholders_1, _2, and so on ([[func.bind.place]](#func.bind.place "22.10.15.5 Placeholders"))[.](#func.bind.isplace-1.sentence-1)
|
||
|
||
The function template bind usesis_placeholder to detect placeholders[.](#func.bind.isplace-1.sentence-2)
|
||
|
||
[2](#func.bind.isplace-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13386)
|
||
|
||
Specializations of the is_placeholder template shall meet
|
||
the [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#func.bind.isplace-2.sentence-1)
|
||
|
||
The implementation
|
||
provides a definition that has the base characteristic ofintegral_constant<int, *J*> if T is the type ofstd::placeholders::_*J*, otherwise it has a
|
||
base characteristic of integral_constant<int, 0>[.](#func.bind.isplace-2.sentence-2)
|
||
|
||
A program
|
||
may specialize this template for a program-defined type T to
|
||
have a base characteristic of integral_constant<int, N> with N > 0 to indicate that T should be
|
||
treated as a placeholder type[.](#func.bind.isplace-2.sentence-3)
|
||
|
||
#### [22.10.15.4](#func.bind.bind) Function template bind [[func.bind.bind]](func.bind.bind)
|
||
|
||
[1](#func.bind.bind-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13401)
|
||
|
||
In the text that follows:
|
||
|
||
- [(1.1)](#func.bind.bind-1.1)
|
||
|
||
g is a value of the result of a bind invocation,
|
||
|
||
- [(1.2)](#func.bind.bind-1.2)
|
||
|
||
FD is the type decay_t<F>,
|
||
|
||
- [(1.3)](#func.bind.bind-1.3)
|
||
|
||
fd is an lvalue that
|
||
is a target object of g ([[func.def]](#func.def "22.10.3 Definitions")) of type FD direct-non-list-initialized with std::forward<F>(f),
|
||
|
||
- [(1.4)](#func.bind.bind-1.4)
|
||
|
||
Ti is the ith type in the template parameter pack BoundArgs,
|
||
|
||
- [(1.5)](#func.bind.bind-1.5)
|
||
|
||
TDi is the type decay_t<Ti>,
|
||
|
||
- [(1.6)](#func.bind.bind-1.6)
|
||
|
||
ti is the ith argument in the function parameter pack bound_args,
|
||
|
||
- [(1.7)](#func.bind.bind-1.7)
|
||
|
||
tdi is a bound argument entity
|
||
of g ([[func.def]](#func.def "22.10.3 Definitions")) of type TDi direct-non-list-initialized with std::forward<Ti>(ti),
|
||
|
||
- [(1.8)](#func.bind.bind-1.8)
|
||
|
||
Uj is the jth deduced type of the UnBoundArgs&&... parameter
|
||
of the argument forwarding call wrapper, and
|
||
|
||
- [(1.9)](#func.bind.bind-1.9)
|
||
|
||
uj is the jth argument associated with Uj[.](#func.bind.bind-1.sentence-1)
|
||
|
||
[ð](#lib:bind_)
|
||
|
||
`template<class F, class... BoundArgs>
|
||
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
|
||
template<class R, class F, class... BoundArgs>
|
||
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
|
||
`
|
||
|
||
[2](#func.bind.bind-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13430)
|
||
|
||
*Mandates*: is_constructible_v<FD, F> is true[.](#func.bind.bind-2.sentence-1)
|
||
|
||
For each Ti in BoundArgs, is_constructible_v<TDi, Ti> is true[.](#func.bind.bind-2.sentence-2)
|
||
|
||
[3](#func.bind.bind-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13435)
|
||
|
||
*Preconditions*: FD and each TDi meet
|
||
the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.bind.bind-3.sentence-1)
|
||
|
||
*INVOKE*(fd, w1, w2, …,wN) ([[func.require]](#func.require "22.10.4 Requirements")) is a valid expression for some
|
||
values w1, w2, …, wN, whereN has the value sizeof...(bound_args)[.](#func.bind.bind-3.sentence-2)
|
||
|
||
[4](#func.bind.bind-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13444)
|
||
|
||
*Returns*: An argument forwarding call wrapper g ([[func.require]](#func.require "22.10.4 Requirements"))[.](#func.bind.bind-4.sentence-1)
|
||
|
||
A program that attempts to invoke a volatile-qualified g is ill-formed[.](#func.bind.bind-4.sentence-2)
|
||
|
||
When g is not volatile-qualified, invocation ofg(u1, u2, …, uM) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) to*INVOKE*(static_cast<Vfd>(vfd), static_cast<V1>(v1), static_cast<V2>(v2), …, static_cast<VN>(vN)) for the first overload, and*INVOKE*<R>(static_cast<Vfd>(vfd), static_cast<V1>(v1), static_cast<V2>(v2), …, static_cast<VN>(vN)) for the second overload,
|
||
where the values and types of the target argument vfd and
|
||
of the bound argumentsv1, v2, …, vN are determined as specified below[.](#func.bind.bind-4.sentence-3)
|
||
|
||
[5](#func.bind.bind-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13466)
|
||
|
||
*Throws*: Any exception thrown by the initialization of
|
||
the state entities of g[.](#func.bind.bind-5.sentence-1)
|
||
|
||
[6](#func.bind.bind-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13471)
|
||
|
||
[*Note [1](#func.bind.bind-note-1)*:
|
||
|
||
If all of FD and TDi meet
|
||
the requirements of [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), then
|
||
the return type meets the requirements of [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#func.bind.bind-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[7](#func.bind.bind-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13479)
|
||
|
||
The values of the [*bound arguments*](#def:bound_arguments) v1, v2, …, vN and their
|
||
corresponding types V1, V2, …, VN depend on the
|
||
types TDi derived from
|
||
the call to bind and the
|
||
cv-qualifiers cv of the call wrapper g as follows:
|
||
|
||
- [(7.1)](#func.bind.bind-7.1)
|
||
|
||
if TDi is reference_wrapper<T>, the
|
||
argument is tdi.get() and its type Vi is T&;
|
||
|
||
- [(7.2)](#func.bind.bind-7.2)
|
||
|
||
if the value of is_bind_expression_v<TDi> is true, the argument isstatic_cast<cv TDi&>(tdi)(std::forward<Uj>(uj)...) and its type Vi isinvoke_result_t<cv TDi&, Uj...>&&;
|
||
|
||
- [(7.3)](#func.bind.bind-7.3)
|
||
|
||
if the value j of is_placeholder_v<TDi> is not zero, the argument is std::forward<Uj>(uj) and its type Vi is Uj&&;
|
||
|
||
- [(7.4)](#func.bind.bind-7.4)
|
||
|
||
otherwise, the value is tdi and its type Vi is cv TDi&[.](#func.bind.bind-7.sentence-1)
|
||
|
||
[8](#func.bind.bind-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13507)
|
||
|
||
The value of the target argument vfd is fd and
|
||
its corresponding type Vfd is cv FD&[.](#func.bind.bind-8.sentence-1)
|
||
|
||
#### [22.10.15.5](#func.bind.place) Placeholders [[func.bind.place]](func.bind.place)
|
||
|
||
namespace std::placeholders {// *M* is the number of placeholders*see below* _1; *see below* _2;
|
||
⋮ *see below* _*M*;}
|
||
|
||
[1](#func.bind.place-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13539)
|
||
|
||
The number *M* of placeholders isimplementation-defined[.](#func.bind.place-1.sentence-1)
|
||
|
||
[2](#func.bind.place-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13543)
|
||
|
||
All placeholder types meet the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements, and
|
||
their default constructors and copy/move
|
||
constructors are constexpr functions that
|
||
do not throw exceptions[.](#func.bind.place-2.sentence-1)
|
||
|
||
It is implementation-defined whether
|
||
placeholder types meet the [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements,
|
||
but if so, their copy assignment operators are
|
||
constexpr functions that do not throw exceptions[.](#func.bind.place-2.sentence-2)
|
||
|
||
[3](#func.bind.place-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13554)
|
||
|
||
Placeholders should be defined as:inline constexpr *unspecified* _1{};
|
||
|
||
If they are not, they are declared as:extern *unspecified* _1;
|
||
|
||
[4](#func.bind.place-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13565)
|
||
|
||
Placeholders are freestanding items ([[freestanding.item]](freestanding.item "16.3.3.7 Freestanding items"))[.](#func.bind.place-4.sentence-1)
|
||
|
||
### [22.10.16](#func.memfn) Function template mem_fn [[func.memfn]](func.memfn)
|
||
|
||
[ð](#lib:mem_fn)
|
||
|
||
`template<class R, class T> constexpr unspecified mem_fn(R T::* pm) noexcept;
|
||
`
|
||
|
||
[1](#func.memfn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13578)
|
||
|
||
*Returns*: A simple call wrapper ([[func.require]](#func.require#term.simple.call.wrapper "22.10.4 Requirements")) fn with call pattern invoke(pmd, call_args...), wherepmd is the target object of fn of type R T::* direct-non-list-initialized with pm, andcall_args is an argument pack
|
||
used in a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call")) of fn[.](#func.memfn-1.sentence-1)
|
||
|
||
### [22.10.17](#func.wrap) Polymorphic function wrappers [[func.wrap]](func.wrap)
|
||
|
||
#### [22.10.17.1](#func.wrap.general) General [[func.wrap.general]](func.wrap.general)
|
||
|
||
[1](#func.wrap.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13594)
|
||
|
||
Subclause [[func.wrap]](#func.wrap "22.10.17 Polymorphic function wrappers") describes polymorphic wrapper classes that
|
||
encapsulate arbitrary callable objects[.](#func.wrap.general-1.sentence-1)
|
||
|
||
[2](#func.wrap.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13598)
|
||
|
||
Let t be an object of a type that is a specialization offunction, copyable_function, or move_only_function,
|
||
such that the target object x of t has a type that
|
||
is a specialization offunction, copyable_function, or move_only_function[.](#func.wrap.general-2.sentence-1)
|
||
|
||
Each argument of the
|
||
invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that
|
||
has the same type, even if the corresponding parameter is not of reference type[.](#func.wrap.general-2.sentence-2)
|
||
|
||
[*Example [1](#func.wrap.general-example-1)*: move_only_function<void(T)> f{copyable_function<void(T)>{[](T) {}}};
|
||
T t;
|
||
f(t); // it is unspecified how many copies of T are made â *end example*]
|
||
|
||
[3](#func.wrap.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13616)
|
||
|
||
*Recommended practice*: Implementations should avoid double wrapping when
|
||
constructing polymorphic wrappers from one another[.](#func.wrap.general-3.sentence-1)
|
||
|
||
#### [22.10.17.2](#func.wrap.badcall) Class bad_function_call [[func.wrap.badcall]](func.wrap.badcall)
|
||
|
||
[1](#func.wrap.badcall-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13624)
|
||
|
||
An exception of type bad_function_call is thrown byfunction::operator() ([[func.wrap.func.inv]](#func.wrap.func.inv "22.10.17.3.5 Invocation"))
|
||
when the function wrapper object has no target[.](#func.wrap.badcall-1.sentence-1)
|
||
|
||
namespace std {class bad_function_call : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconst char* what() const noexcept override; };}
|
||
|
||
[ð](#lib:what,bad_function_call)
|
||
|
||
`const char* what() const noexcept override;
|
||
`
|
||
|
||
[2](#func.wrap.badcall-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13645)
|
||
|
||
*Returns*: Animplementation-defined ntbs[.](#func.wrap.badcall-2.sentence-1)
|
||
|
||
#### [22.10.17.3](#func.wrap.func) Class template function [[func.wrap.func]](func.wrap.func)
|
||
|
||
#### [22.10.17.3.1](#func.wrap.func.general) General [[func.wrap.func.general]](func.wrap.func.general)
|
||
|
||
[ð](#lib:result_type,function)
|
||
|
||
namespace std {template<class R, class... ArgTypes>class function<R(ArgTypes...)> {public:using result_type = R; // [[func.wrap.func.con]](#func.wrap.func.con "22.10.17.3.2 Constructors and destructor"), construct/copy/destroy function() noexcept;
|
||
function(nullptr_t) noexcept;
|
||
function(const function&);
|
||
function(function&&) noexcept; template<class F> function(F&&);
|
||
|
||
function& operator=(const function&);
|
||
function& operator=(function&&);
|
||
function& operator=(nullptr_t) noexcept; template<class F> function& operator=(F&&); template<class F> function& operator=(reference_wrapper<F>) noexcept; ~function(); // [[func.wrap.func.mod]](#func.wrap.func.mod "22.10.17.3.3 Modifiers"), function modifiersvoid swap(function&) noexcept; // [[func.wrap.func.cap]](#func.wrap.func.cap "22.10.17.3.4 Capacity"), function capacityexplicit operator bool() const noexcept; // [[func.wrap.func.inv]](#func.wrap.func.inv "22.10.17.3.5 Invocation"), function invocation R operator()(ArgTypes...) const; // [[func.wrap.func.targ]](#func.wrap.func.targ "22.10.17.3.6 Target access"), function target accessconst type_info& target_type() const noexcept; template<class T> T* target() noexcept; template<class T> const T* target() const noexcept; }; template<class R, class... ArgTypes> function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>; template<class F> function(F) -> function<*see below*>;}
|
||
|
||
[1](#func.wrap.func.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13701)
|
||
|
||
The function class template provides polymorphic wrappers that
|
||
generalize the notion of a function pointer[.](#func.wrap.func.general-1.sentence-1)
|
||
|
||
Wrappers can store, copy,
|
||
and call arbitrary callable objects ([[func.def]](#func.def "22.10.3 Definitions")), given a call
|
||
signature ([[func.def]](#func.def "22.10.3 Definitions"))[.](#func.wrap.func.general-1.sentence-2)
|
||
|
||
[2](#func.wrap.func.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13707)
|
||
|
||
The function class template is a call
|
||
wrapper ([[func.def]](#func.def "22.10.3 Definitions")) whose call signature ([[func.def]](#func.def "22.10.3 Definitions"))
|
||
is R(ArgTypes...)[.](#func.wrap.func.general-2.sentence-1)
|
||
|
||
[3](#func.wrap.func.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13712)
|
||
|
||
[*Note [1](#func.wrap.func.general-note-1)*:
|
||
|
||
The types deduced by the deduction guides for function might change in future revisions of C++[.](#func.wrap.func.general-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.3.2](#func.wrap.func.con) Constructors and destructor [[func.wrap.func.con]](func.wrap.func.con)
|
||
|
||
[ð](#lib:function,constructor)
|
||
|
||
`function() noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.con-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13726)
|
||
|
||
*Postconditions*: !*this[.](#func.wrap.func.con-1.sentence-1)
|
||
|
||
[ð](#lib:function,constructor_)
|
||
|
||
`function(nullptr_t) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.func.con-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13737)
|
||
|
||
*Postconditions*: !*this[.](#func.wrap.func.con-2.sentence-1)
|
||
|
||
[ð](#lib:function,constructor__)
|
||
|
||
`function(const function& f);
|
||
`
|
||
|
||
[3](#func.wrap.func.con-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13748)
|
||
|
||
*Postconditions*: !*this if !f; otherwise,
|
||
the target object of *this is a copy of the target object of f[.](#func.wrap.func.con-3.sentence-1)
|
||
|
||
[4](#func.wrap.func.con-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13753)
|
||
|
||
*Throws*: Nothing if f's target is
|
||
a specialization of reference_wrapper or
|
||
a function pointer[.](#func.wrap.func.con-4.sentence-1)
|
||
|
||
Otherwise, may throw bad_alloc or any exception thrown by the copy constructor of the stored callable object[.](#func.wrap.func.con-4.sentence-2)
|
||
|
||
[5](#func.wrap.func.con-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13760)
|
||
|
||
*Recommended practice*: Implementations should avoid the use of
|
||
dynamically allocated memory for small callable objects, for example, wheref's target is an object holding only a pointer or reference
|
||
to an object and a member function pointer[.](#func.wrap.func.con-5.sentence-1)
|
||
|
||
[ð](#lib:function,constructor___)
|
||
|
||
`function(function&& f) noexcept;
|
||
`
|
||
|
||
[6](#func.wrap.func.con-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13774)
|
||
|
||
*Postconditions*: If !f, *this has no target;
|
||
otherwise, the target of *this is equivalent to
|
||
the target of f before the construction, andf is in a valid state with an unspecified value[.](#func.wrap.func.con-6.sentence-1)
|
||
|
||
[7](#func.wrap.func.con-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13781)
|
||
|
||
*Recommended practice*: Implementations should avoid the use of
|
||
dynamically allocated memory for small callable objects, for example,
|
||
where f's target is an object holding only a pointer or reference
|
||
to an object and a member function pointer[.](#func.wrap.func.con-7.sentence-1)
|
||
|
||
[ð](#lib:function,constructor____)
|
||
|
||
`template<class F> function(F&& f);
|
||
`
|
||
|
||
[8](#func.wrap.func.con-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13795)
|
||
|
||
Let FD be decay_t<F>[.](#func.wrap.func.con-8.sentence-1)
|
||
|
||
[9](#func.wrap.func.con-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13798)
|
||
|
||
*Constraints*:
|
||
|
||
- [(9.1)](#func.wrap.func.con-9.1)
|
||
|
||
is_same_v<remove_cvref_t<F>, function> is false, and
|
||
|
||
- [(9.2)](#func.wrap.func.con-9.2)
|
||
|
||
is_invocable_r_v<R, FD&, ArgTypes...> is true[.](#func.wrap.func.con-9.sentence-1)
|
||
|
||
[10](#func.wrap.func.con-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13807)
|
||
|
||
*Mandates*:
|
||
|
||
- [(10.1)](#func.wrap.func.con-10.1)
|
||
|
||
is_copy_constructible_v<FD> is true, and
|
||
|
||
- [(10.2)](#func.wrap.func.con-10.2)
|
||
|
||
is_constructible_v<FD, F> is true[.](#func.wrap.func.con-10.sentence-1)
|
||
|
||
[11](#func.wrap.func.con-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13816)
|
||
|
||
*Preconditions*: FD meets the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.func.con-11.sentence-1)
|
||
|
||
[12](#func.wrap.func.con-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13820)
|
||
|
||
*Postconditions*: !*this is true if any of the following hold:
|
||
|
||
- [(12.1)](#func.wrap.func.con-12.1)
|
||
|
||
f is a null function pointer value[.](#func.wrap.func.con-12.1.sentence-1)
|
||
|
||
- [(12.2)](#func.wrap.func.con-12.2)
|
||
|
||
f is a null member pointer value[.](#func.wrap.func.con-12.2.sentence-1)
|
||
|
||
- [(12.3)](#func.wrap.func.con-12.3)
|
||
|
||
remove_cvref_t<F> is
|
||
a specialization of the function class template, and!f is true[.](#func.wrap.func.con-12.3.sentence-1)
|
||
|
||
[13](#func.wrap.func.con-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13831)
|
||
|
||
Otherwise, *this has a target object of type FD direct-non-list-initialized with std::forward<F>(f)[.](#func.wrap.func.con-13.sentence-1)
|
||
|
||
[14](#func.wrap.func.con-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13835)
|
||
|
||
*Throws*: Nothing if FD is
|
||
a specialization of reference_wrapper or
|
||
a function pointer type[.](#func.wrap.func.con-14.sentence-1)
|
||
|
||
Otherwise, may throw bad_alloc or
|
||
any exception thrown by the initialization of the target object[.](#func.wrap.func.con-14.sentence-2)
|
||
|
||
[15](#func.wrap.func.con-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13843)
|
||
|
||
*Recommended practice*: Implementations should avoid the use of
|
||
dynamically allocated memory for small callable objects, for example,
|
||
where f refers to an object holding only a pointer or
|
||
reference to an object and a member function pointer[.](#func.wrap.func.con-15.sentence-1)
|
||
|
||
[ð](#func.wrap.func.con-itemdecl:6)
|
||
|
||
`template<class F> function(F) -> function<see below>;
|
||
`
|
||
|
||
[16](#func.wrap.func.con-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13857)
|
||
|
||
*Constraints*: &F::operator() is well-formed when treated as an unevaluated operand and either
|
||
|
||
- [(16.1)](#func.wrap.func.con-16.1)
|
||
|
||
F::operator() is a non-static member function anddecltype(&F::operator()) is either of the formR(G::*)(A...) cv &opt noexceptopt or of the formR(*)(G, A...) noexceptopt for a type G, or
|
||
|
||
- [(16.2)](#func.wrap.func.con-16.2)
|
||
|
||
F::operator() is a static member function anddecltype(&F::operator()) is of the formR(*)(A...) noexceptopt[.](#func.wrap.func.con-16.sentence-1)
|
||
|
||
[17](#func.wrap.func.con-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13874)
|
||
|
||
*Remarks*: The deduced type is function<R(A...)>[.](#func.wrap.func.con-17.sentence-1)
|
||
|
||
[18](#func.wrap.func.con-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13878)
|
||
|
||
[*Example [1](#func.wrap.func.con-example-1)*: void f() {int i{5};
|
||
function g = [&](double) { return i; }; // deduces function<int(double)>} â *end example*]
|
||
|
||
[ð](#lib:operator=,function)
|
||
|
||
`function& operator=(const function& f);
|
||
`
|
||
|
||
[19](#func.wrap.func.con-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13895)
|
||
|
||
*Effects*: As if by function(f).swap(*this);
|
||
|
||
[20](#func.wrap.func.con-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13899)
|
||
|
||
*Returns*: *this[.](#func.wrap.func.con-20.sentence-1)
|
||
|
||
[ð](#lib:operator=,function_)
|
||
|
||
`function& operator=(function&& f);
|
||
`
|
||
|
||
[21](#func.wrap.func.con-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13910)
|
||
|
||
*Effects*: Replaces the target of *this with the target of f[.](#func.wrap.func.con-21.sentence-1)
|
||
|
||
[22](#func.wrap.func.con-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13915)
|
||
|
||
*Returns*: *this[.](#func.wrap.func.con-22.sentence-1)
|
||
|
||
[ð](#lib:operator=,function__)
|
||
|
||
`function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[23](#func.wrap.func.con-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13926)
|
||
|
||
*Effects*: If *this != nullptr, destroys the target of this[.](#func.wrap.func.con-23.sentence-1)
|
||
|
||
[24](#func.wrap.func.con-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13930)
|
||
|
||
*Postconditions*: !(*this)[.](#func.wrap.func.con-24.sentence-1)
|
||
|
||
[25](#func.wrap.func.con-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13934)
|
||
|
||
*Returns*: *this[.](#func.wrap.func.con-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,function___)
|
||
|
||
`template<class F> function& operator=(F&& f);
|
||
`
|
||
|
||
[26](#func.wrap.func.con-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13945)
|
||
|
||
*Constraints*: is_invocable_r_v<R, decay_t<F>&, ArgTypes...> is true[.](#func.wrap.func.con-26.sentence-1)
|
||
|
||
[27](#func.wrap.func.con-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13949)
|
||
|
||
*Effects*: As if by: function(std::forward<F>(f)).swap(*this);
|
||
|
||
[28](#func.wrap.func.con-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13953)
|
||
|
||
*Returns*: *this[.](#func.wrap.func.con-28.sentence-1)
|
||
|
||
[ð](#lib:operator=,function____)
|
||
|
||
`template<class F> function& operator=(reference_wrapper<F> f) noexcept;
|
||
`
|
||
|
||
[29](#func.wrap.func.con-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13964)
|
||
|
||
*Effects*: As if by: function(f).swap(*this);
|
||
|
||
[30](#func.wrap.func.con-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13968)
|
||
|
||
*Returns*: *this[.](#func.wrap.func.con-30.sentence-1)
|
||
|
||
[ð](#lib:function,destructor)
|
||
|
||
`~function();
|
||
`
|
||
|
||
[31](#func.wrap.func.con-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13979)
|
||
|
||
*Effects*: If *this != nullptr, destroys the target of this[.](#func.wrap.func.con-31.sentence-1)
|
||
|
||
#### [22.10.17.3.3](#func.wrap.func.mod) Modifiers [[func.wrap.func.mod]](func.wrap.func.mod)
|
||
|
||
[ð](#lib:swap,function)
|
||
|
||
`void swap(function& other) noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13992)
|
||
|
||
*Effects*: Interchanges the target objects of *this and other[.](#func.wrap.func.mod-1.sentence-1)
|
||
|
||
#### [22.10.17.3.4](#func.wrap.func.cap) Capacity [[func.wrap.func.cap]](func.wrap.func.cap)
|
||
|
||
[ð](#lib:operator_bool,function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.cap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14005)
|
||
|
||
*Returns*: true if *this has a target, otherwise false[.](#func.wrap.func.cap-1.sentence-1)
|
||
|
||
#### [22.10.17.3.5](#func.wrap.func.inv) Invocation [[func.wrap.func.inv]](func.wrap.func.inv)
|
||
|
||
[ð](#lib:function,invocation)
|
||
|
||
`R operator()(ArgTypes... args) const;
|
||
`
|
||
|
||
[1](#func.wrap.func.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14019)
|
||
|
||
*Returns*: *INVOKE*<R>(f, std::forward<ArgTypes>(args)...) ([[func.require]](#func.require "22.10.4 Requirements")),
|
||
where f is the target object ([[func.def]](#func.def "22.10.3 Definitions")) of *this[.](#func.wrap.func.inv-1.sentence-1)
|
||
|
||
[2](#func.wrap.func.inv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14024)
|
||
|
||
*Throws*: bad_function_call if !*this; otherwise, any
|
||
exception thrown by the target object[.](#func.wrap.func.inv-2.sentence-1)
|
||
|
||
#### [22.10.17.3.6](#func.wrap.func.targ) Target access [[func.wrap.func.targ]](func.wrap.func.targ)
|
||
|
||
[ð](#lib:target_type,function)
|
||
|
||
`const type_info& target_type() const noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.targ-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14038)
|
||
|
||
*Returns*: If *this has a target of type T, typeid(T); otherwise, typeid(void)[.](#func.wrap.func.targ-1.sentence-1)
|
||
|
||
[ð](#lib:target,function)
|
||
|
||
`template<class T> T* target() noexcept;
|
||
template<class T> const T* target() const noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.func.targ-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14051)
|
||
|
||
*Returns*: If target_type() == typeid(T) a pointer to the stored function target; otherwise a null pointer[.](#func.wrap.func.targ-2.sentence-1)
|
||
|
||
#### [22.10.17.3.7](#func.wrap.func.nullptr) Null pointer comparison operator functions [[func.wrap.func.nullptr]](func.wrap.func.nullptr)
|
||
|
||
[ð](#lib:operator==,function)
|
||
|
||
`template<class R, class... ArgTypes>
|
||
bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.nullptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14066)
|
||
|
||
*Returns*: !f[.](#func.wrap.func.nullptr-1.sentence-1)
|
||
|
||
#### [22.10.17.3.8](#func.wrap.func.alg) Specialized algorithms [[func.wrap.func.alg]](func.wrap.func.alg)
|
||
|
||
[ð](#lib:swap,function_)
|
||
|
||
`template<class R, class... ArgTypes>
|
||
void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.func.alg-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14080)
|
||
|
||
*Effects*: As if by: f1.swap(f2);
|
||
|
||
#### [22.10.17.4](#func.wrap.move) Move-only wrapper [[func.wrap.move]](func.wrap.move)
|
||
|
||
#### [22.10.17.4.1](#func.wrap.move.general) General [[func.wrap.move.general]](func.wrap.move.general)
|
||
|
||
[1](#func.wrap.move.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14089)
|
||
|
||
The header provides partial specializations of move_only_function for each combination of the possible replacements
|
||
of the placeholders cv, *ref*, and *noex* where
|
||
|
||
- [(1.1)](#func.wrap.move.general-1.1)
|
||
|
||
cv is either const or empty,
|
||
|
||
- [(1.2)](#func.wrap.move.general-1.2)
|
||
|
||
*ref* is either &, &&, or empty, and
|
||
|
||
- [(1.3)](#func.wrap.move.general-1.3)
|
||
|
||
*noex* is either true or false[.](#func.wrap.move.general-1.sentence-1)
|
||
|
||
[2](#func.wrap.move.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14102)
|
||
|
||
For each of the possible combinations of the placeholders mentioned above,
|
||
there is a placeholder *inv-quals* defined as follows:
|
||
|
||
- [(2.1)](#func.wrap.move.general-2.1)
|
||
|
||
If *ref* is empty, let *inv-quals* be cv&,
|
||
|
||
- [(2.2)](#func.wrap.move.general-2.2)
|
||
|
||
otherwise, let *inv-quals* be cv *ref*[.](#func.wrap.move.general-2.sentence-1)
|
||
|
||
#### [22.10.17.4.2](#func.wrap.move.class) Class template move_only_function [[func.wrap.move.class]](func.wrap.move.class)
|
||
|
||
[ð](#lib:move_only_function)
|
||
|
||
namespace std {template<class R, class... ArgTypes>class move_only_function<R(ArgTypes...) cv *ref* noexcept(*noex*)> {public:using result_type = R; // [[func.wrap.move.ctor]](#func.wrap.move.ctor "22.10.17.4.3 Constructors, assignments, and destructor"), constructors, assignments, and destructor move_only_function() noexcept;
|
||
move_only_function(nullptr_t) noexcept;
|
||
move_only_function(move_only_function&&) noexcept; template<class F> move_only_function(F&&); template<class T, class... Args>explicit move_only_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>explicit move_only_function(in_place_type_t<T>, initializer_list<U>, Args&&...);
|
||
|
||
move_only_function& operator=(move_only_function&&);
|
||
move_only_function& operator=(nullptr_t) noexcept; template<class F> move_only_function& operator=(F&&); ~move_only_function(); // [[func.wrap.move.inv]](#func.wrap.move.inv "22.10.17.4.4 Invocation"), invocationexplicit operator bool() const noexcept;
|
||
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.move.util]](#func.wrap.move.util "22.10.17.4.5 Utility"), utilityvoid swap(move_only_function&) noexcept; friend void swap(move_only_function&, move_only_function&) noexcept; friend bool operator==(const move_only_function&, nullptr_t) noexcept; private:template<class VT>static constexpr bool *is-callable-from* = *see below*; // *exposition only*};}
|
||
|
||
[1](#func.wrap.move.class-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14154)
|
||
|
||
The move_only_function class template provides polymorphic wrappers
|
||
that generalize the notion of a callable object ([[func.def]](#func.def "22.10.3 Definitions"))[.](#func.wrap.move.class-1.sentence-1)
|
||
|
||
These wrappers can store, move, and call arbitrary callable objects,
|
||
given a call signature[.](#func.wrap.move.class-1.sentence-2)
|
||
|
||
[2](#func.wrap.move.class-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14160)
|
||
|
||
*Recommended practice*: Implementations should avoid the use of dynamically allocated memory
|
||
for a small contained value[.](#func.wrap.move.class-2.sentence-1)
|
||
|
||
[*Note [1](#func.wrap.move.class-note-1)*:
|
||
|
||
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true[.](#func.wrap.move.class-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.4.3](#func.wrap.move.ctor) Constructors, assignments, and destructor [[func.wrap.move.ctor]](func.wrap.move.ctor)
|
||
|
||
[ð](#:move_only_function::is-callable-from)
|
||
|
||
`template<class VT>
|
||
static constexpr bool is-callable-from = see below;
|
||
`
|
||
|
||
[1](#func.wrap.move.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14178)
|
||
|
||
If *noex* is true,*is-callable-from*<VT> is equal to:is_nothrow_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_nothrow_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
|
||
|
||
Otherwise, *is-callable-from*<VT> is equal to:is_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
|
||
|
||
[ð](#lib:move_only_function,constructor)
|
||
|
||
`move_only_function() noexcept;
|
||
move_only_function(nullptr_t) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.move.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14199)
|
||
|
||
*Postconditions*: *this has no target object[.](#func.wrap.move.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,constructor_)
|
||
|
||
`move_only_function(move_only_function&& f) noexcept;
|
||
`
|
||
|
||
[3](#func.wrap.move.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14210)
|
||
|
||
*Postconditions*: The target object of *this is
|
||
the target object f had before construction, andf is in a valid state with an unspecified value[.](#func.wrap.move.ctor-3.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,constructor__)
|
||
|
||
`template<class F> move_only_function(F&& f);
|
||
`
|
||
|
||
[4](#func.wrap.move.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14223)
|
||
|
||
Let VT be decay_t<F>[.](#func.wrap.move.ctor-4.sentence-1)
|
||
|
||
[5](#func.wrap.move.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14226)
|
||
|
||
*Constraints*:
|
||
|
||
- [(5.1)](#func.wrap.move.ctor-5.1)
|
||
|
||
remove_cvref_t<F> is not the same type as move_only_function, and
|
||
|
||
- [(5.2)](#func.wrap.move.ctor-5.2)
|
||
|
||
remove_cvref_t<F> is not a specialization of in_place_type_t, and
|
||
|
||
- [(5.3)](#func.wrap.move.ctor-5.3)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.move.ctor-5.sentence-1)
|
||
|
||
[6](#func.wrap.move.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14237)
|
||
|
||
*Mandates*: is_constructible_v<VT, F> is true[.](#func.wrap.move.ctor-6.sentence-1)
|
||
|
||
[7](#func.wrap.move.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14241)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements, and
|
||
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.move.ctor-7.sentence-1)
|
||
|
||
[8](#func.wrap.move.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14247)
|
||
|
||
*Postconditions*: *this has no target object if any of the following hold:
|
||
|
||
- [(8.1)](#func.wrap.move.ctor-8.1)
|
||
|
||
f is a null function pointer value, or
|
||
|
||
- [(8.2)](#func.wrap.move.ctor-8.2)
|
||
|
||
f is a null member pointer value, or
|
||
|
||
- [(8.3)](#func.wrap.move.ctor-8.3)
|
||
|
||
remove_cvref_t<F> is a specialization of
|
||
the move_only_function class template,
|
||
and f has no target object[.](#func.wrap.move.ctor-8.sentence-1)
|
||
|
||
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#func.wrap.move.ctor-8.sentence-2)
|
||
|
||
[9](#func.wrap.move.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14263)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.move.ctor-9.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#func.wrap.move.ctor-9.sentence-2)
|
||
|
||
[ð](#lib:move_only_function,constructor___)
|
||
|
||
`template<class T, class... Args>
|
||
explicit move_only_function(in_place_type_t<T>, Args&&... args);
|
||
`
|
||
|
||
[10](#func.wrap.move.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14277)
|
||
|
||
Let VT be decay_t<T>[.](#func.wrap.move.ctor-10.sentence-1)
|
||
|
||
[11](#func.wrap.move.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14280)
|
||
|
||
*Constraints*:
|
||
|
||
- [(11.1)](#func.wrap.move.ctor-11.1)
|
||
|
||
is_constructible_v<VT, Args...> is true, and
|
||
|
||
- [(11.2)](#func.wrap.move.ctor-11.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.move.ctor-11.sentence-1)
|
||
|
||
[12](#func.wrap.move.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14289)
|
||
|
||
*Mandates*: VT is the same type as T[.](#func.wrap.move.ctor-12.sentence-1)
|
||
|
||
[13](#func.wrap.move.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14293)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements, and
|
||
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.move.ctor-13.sentence-1)
|
||
|
||
[14](#func.wrap.move.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14299)
|
||
|
||
*Postconditions*: *this has a target object of type VT direct-non-list-initialized with std::forward<Args>(args)...[.](#func.wrap.move.ctor-14.sentence-1)
|
||
|
||
[15](#func.wrap.move.ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14304)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.move.ctor-15.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#func.wrap.move.ctor-15.sentence-2)
|
||
|
||
[ð](#lib:move_only_function,constructor____)
|
||
|
||
`template<class T, class U, class... Args>
|
||
explicit move_only_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
|
||
`
|
||
|
||
[16](#func.wrap.move.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14318)
|
||
|
||
Let VT be decay_t<T>[.](#func.wrap.move.ctor-16.sentence-1)
|
||
|
||
[17](#func.wrap.move.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14321)
|
||
|
||
*Constraints*:
|
||
|
||
- [(17.1)](#func.wrap.move.ctor-17.1)
|
||
|
||
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
|
||
|
||
- [(17.2)](#func.wrap.move.ctor-17.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.move.ctor-17.sentence-1)
|
||
|
||
[18](#func.wrap.move.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14331)
|
||
|
||
*Mandates*: VT is the same type as T[.](#func.wrap.move.ctor-18.sentence-1)
|
||
|
||
[19](#func.wrap.move.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14335)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements, and
|
||
if is_move_constructible_v<VT> is true,VT meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.move.ctor-19.sentence-1)
|
||
|
||
[20](#func.wrap.move.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14341)
|
||
|
||
*Postconditions*: *this has a target object of type VT direct-non-list-initialized withilist, std::forward<Args>(args)...[.](#func.wrap.move.ctor-20.sentence-1)
|
||
|
||
[21](#func.wrap.move.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14347)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.move.ctor-21.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#func.wrap.move.ctor-21.sentence-2)
|
||
|
||
[ð](#lib:operator=,move_only_function)
|
||
|
||
`move_only_function& operator=(move_only_function&& f);
|
||
`
|
||
|
||
[22](#func.wrap.move.ctor-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14360)
|
||
|
||
*Effects*: Equivalent to: move_only_function(std::move(f)).swap(*this);
|
||
|
||
[23](#func.wrap.move.ctor-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14364)
|
||
|
||
*Returns*: *this[.](#func.wrap.move.ctor-23.sentence-1)
|
||
|
||
[ð](#lib:operator=,move_only_function_)
|
||
|
||
`move_only_function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[24](#func.wrap.move.ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14375)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#func.wrap.move.ctor-24.sentence-1)
|
||
|
||
[25](#func.wrap.move.ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14379)
|
||
|
||
*Returns*: *this[.](#func.wrap.move.ctor-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,move_only_function__)
|
||
|
||
`template<class F> move_only_function& operator=(F&& f);
|
||
`
|
||
|
||
[26](#func.wrap.move.ctor-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14390)
|
||
|
||
*Effects*: Equivalent to: move_only_function(std::forward<F>(f)).swap(*this);
|
||
|
||
[27](#func.wrap.move.ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14394)
|
||
|
||
*Returns*: *this[.](#func.wrap.move.ctor-27.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,destructor)
|
||
|
||
`~move_only_function();
|
||
`
|
||
|
||
[28](#func.wrap.move.ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14405)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#func.wrap.move.ctor-28.sentence-1)
|
||
|
||
#### [22.10.17.4.4](#func.wrap.move.inv) Invocation [[func.wrap.move.inv]](func.wrap.move.inv)
|
||
|
||
[ð](#lib:operator_bool,move_only_function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.move.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14418)
|
||
|
||
*Returns*: true if *this has a target object, otherwise false[.](#func.wrap.move.inv-1.sentence-1)
|
||
|
||
[ð](#lib:operator(),move_only_function)
|
||
|
||
`R operator()(ArgTypes... args) cv ref noexcept(noex);
|
||
`
|
||
|
||
[2](#func.wrap.move.inv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14429)
|
||
|
||
*Preconditions*: *this has a target object[.](#func.wrap.move.inv-2.sentence-1)
|
||
|
||
[3](#func.wrap.move.inv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14433)
|
||
|
||
*Effects*: Equivalent to:return *INVOKE*<R>(static_cast<F *inv-quals*>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this andF is the type of f[.](#func.wrap.move.inv-3.sentence-1)
|
||
|
||
#### [22.10.17.4.5](#func.wrap.move.util) Utility [[func.wrap.move.util]](func.wrap.move.util)
|
||
|
||
[ð](#lib:swap,move_only_function)
|
||
|
||
`void swap(move_only_function& other) noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.move.util-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14451)
|
||
|
||
*Effects*: Exchanges the target objects of *this and other[.](#func.wrap.move.util-1.sentence-1)
|
||
|
||
[ð](#lib:swap,move_only_function_)
|
||
|
||
`friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.move.util-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14462)
|
||
|
||
*Effects*: Equivalent to f1.swap(f2)[.](#func.wrap.move.util-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,move_only_function)
|
||
|
||
`friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
|
||
`
|
||
|
||
[3](#func.wrap.move.util-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14473)
|
||
|
||
*Returns*: true if f has no target object, otherwise false[.](#func.wrap.move.util-3.sentence-1)
|
||
|
||
#### [22.10.17.5](#func.wrap.copy) Copyable wrapper [[func.wrap.copy]](func.wrap.copy)
|
||
|
||
#### [22.10.17.5.1](#func.wrap.copy.general) General [[func.wrap.copy.general]](func.wrap.copy.general)
|
||
|
||
[1](#func.wrap.copy.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14482)
|
||
|
||
The header provides partial specializations of copyable_function for each combination of the possible replacements
|
||
of the placeholders cv, *ref*, and *noex* where
|
||
|
||
- [(1.1)](#func.wrap.copy.general-1.1)
|
||
|
||
cv is either const or empty,
|
||
|
||
- [(1.2)](#func.wrap.copy.general-1.2)
|
||
|
||
*ref* is either &, &&, or empty, and
|
||
|
||
- [(1.3)](#func.wrap.copy.general-1.3)
|
||
|
||
*noex* is either true or false[.](#func.wrap.copy.general-1.sentence-1)
|
||
|
||
[2](#func.wrap.copy.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14495)
|
||
|
||
For each of the possible combinations of the placeholders mentioned above,
|
||
there is a placeholder *inv-quals* defined as follows:
|
||
|
||
- [(2.1)](#func.wrap.copy.general-2.1)
|
||
|
||
If *ref* is empty, let *inv-quals* be cv&,
|
||
|
||
- [(2.2)](#func.wrap.copy.general-2.2)
|
||
|
||
otherwise, let *inv-quals* be cv *ref*[.](#func.wrap.copy.general-2.sentence-1)
|
||
|
||
#### [22.10.17.5.2](#func.wrap.copy.class) Class template copyable_function [[func.wrap.copy.class]](func.wrap.copy.class)
|
||
|
||
[ð](#lib:copyable_function)
|
||
|
||
namespace std {template<class R, class... ArgTypes>class copyable_function<R(ArgTypes...) cv *ref* noexcept(*noex*)> {public:using result_type = R; // [[func.wrap.copy.ctor]](#func.wrap.copy.ctor "22.10.17.5.3 Constructors, assignments, and destructor"), constructors, assignments, and destructor copyable_function() noexcept;
|
||
copyable_function(nullptr_t) noexcept;
|
||
copyable_function(const copyable_function&);
|
||
copyable_function(copyable_function&&) noexcept; template<class F> copyable_function(F&&); template<class T, class... Args>explicit copyable_function(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>explicit copyable_function(in_place_type_t<T>, initializer_list<U>, Args&&...);
|
||
|
||
copyable_function& operator=(const copyable_function&);
|
||
copyable_function& operator=(copyable_function&&);
|
||
copyable_function& operator=(nullptr_t) noexcept; template<class F> copyable_function& operator=(F&&); ~copyable_function(); // [[func.wrap.copy.inv]](#func.wrap.copy.inv "22.10.17.5.4 Invocation"), invocationexplicit operator bool() const noexcept;
|
||
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.copy.util]](#func.wrap.copy.util "22.10.17.5.5 Utility"), utilityvoid swap(copyable_function&) noexcept; friend void swap(copyable_function&, copyable_function&) noexcept; friend bool operator==(const copyable_function&, nullptr_t) noexcept; private:template<class VT>static constexpr bool *is-callable-from* = *see below*; // *exposition only*};}
|
||
|
||
[1](#func.wrap.copy.class-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14549)
|
||
|
||
The copyable_function class template provides polymorphic wrappers
|
||
that generalize the notion of a callable object ([[func.def]](#func.def "22.10.3 Definitions"))[.](#func.wrap.copy.class-1.sentence-1)
|
||
|
||
These wrappers can store, copy, move, and call arbitrary callable objects,
|
||
given a call signature[.](#func.wrap.copy.class-1.sentence-2)
|
||
|
||
[2](#func.wrap.copy.class-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14555)
|
||
|
||
*Recommended practice*: Implementations should avoid the use of dynamically allocated memory
|
||
for a small contained value[.](#func.wrap.copy.class-2.sentence-1)
|
||
|
||
[*Note [1](#func.wrap.copy.class-note-1)*:
|
||
|
||
Such small-object optimization can only be applied to a type T for which is_nothrow_move_constructible_v<T> is true[.](#func.wrap.copy.class-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.5.3](#func.wrap.copy.ctor) Constructors, assignments, and destructor [[func.wrap.copy.ctor]](func.wrap.copy.ctor)
|
||
|
||
[ð](#:copyable_function::is-callable-from)
|
||
|
||
`template<class VT>
|
||
static constexpr bool is-callable-from = see below;
|
||
`
|
||
|
||
[1](#func.wrap.copy.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14573)
|
||
|
||
If *noex* is true,*is-callable-from*<VT> is equal to:is_nothrow_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_nothrow_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
|
||
|
||
Otherwise, *is-callable-from*<VT> is equal to:is_invocable_r_v<R, VT cv *ref*, ArgTypes...> && is_invocable_r_v<R, VT *inv-quals*, ArgTypes...>
|
||
|
||
[ð](#lib:copyable_function,constructor)
|
||
|
||
`copyable_function() noexcept;
|
||
copyable_function(nullptr_t) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.copy.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14594)
|
||
|
||
*Postconditions*: *this has no target object[.](#func.wrap.copy.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,constructor_)
|
||
|
||
`copyable_function(const copyable_function& f);
|
||
`
|
||
|
||
[3](#func.wrap.copy.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14605)
|
||
|
||
*Postconditions*: *this has no target object if f had no target object[.](#func.wrap.copy.ctor-3.sentence-1)
|
||
|
||
Otherwise, the target object of *this is a copy of the target object of f[.](#func.wrap.copy.ctor-3.sentence-2)
|
||
|
||
[4](#func.wrap.copy.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14611)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.copy.ctor-4.sentence-1)
|
||
|
||
May throw bad_alloc[.](#func.wrap.copy.ctor-4.sentence-2)
|
||
|
||
[ð](#lib:copyable_function,constructor__)
|
||
|
||
`copyable_function(copyable_function&& f) noexcept;
|
||
`
|
||
|
||
[5](#func.wrap.copy.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14623)
|
||
|
||
*Postconditions*: The target object of *this is
|
||
the target object f had before construction, andf is in a valid state with an unspecified value[.](#func.wrap.copy.ctor-5.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,constructor___)
|
||
|
||
`template<class F> copyable_function(F&& f);
|
||
`
|
||
|
||
[6](#func.wrap.copy.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14636)
|
||
|
||
Let VT be decay_t<F>[.](#func.wrap.copy.ctor-6.sentence-1)
|
||
|
||
[7](#func.wrap.copy.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14639)
|
||
|
||
*Constraints*:
|
||
|
||
- [(7.1)](#func.wrap.copy.ctor-7.1)
|
||
|
||
remove_cvref_t<F> is not the same type as copyable_function, and
|
||
|
||
- [(7.2)](#func.wrap.copy.ctor-7.2)
|
||
|
||
remove_cvref_t<F> is not a specialization of in_place_type_t, and
|
||
|
||
- [(7.3)](#func.wrap.copy.ctor-7.3)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.copy.ctor-7.sentence-1)
|
||
|
||
[8](#func.wrap.copy.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14650)
|
||
|
||
*Mandates*:
|
||
|
||
- [(8.1)](#func.wrap.copy.ctor-8.1)
|
||
|
||
is_constructible_v<VT, F> is true, and
|
||
|
||
- [(8.2)](#func.wrap.copy.ctor-8.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#func.wrap.copy.ctor-8.sentence-1)
|
||
|
||
[9](#func.wrap.copy.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14659)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.copy.ctor-9.sentence-1)
|
||
|
||
[10](#func.wrap.copy.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14664)
|
||
|
||
*Postconditions*: *this has no target object if any of the following hold:
|
||
|
||
- [(10.1)](#func.wrap.copy.ctor-10.1)
|
||
|
||
f is a null function pointer value, or
|
||
|
||
- [(10.2)](#func.wrap.copy.ctor-10.2)
|
||
|
||
f is a null member pointer value, or
|
||
|
||
- [(10.3)](#func.wrap.copy.ctor-10.3)
|
||
|
||
remove_cvref_t<F> is a specialization of
|
||
the copyable_function class template,
|
||
and f has no target object[.](#func.wrap.copy.ctor-10.sentence-1)
|
||
|
||
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#func.wrap.copy.ctor-10.sentence-2)
|
||
|
||
[11](#func.wrap.copy.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14680)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.copy.ctor-11.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#func.wrap.copy.ctor-11.sentence-2)
|
||
|
||
[ð](#lib:copyable_function,constructor____)
|
||
|
||
`template<class T, class... Args>
|
||
explicit copyable_function(in_place_type_t<T>, Args&&... args);
|
||
`
|
||
|
||
[12](#func.wrap.copy.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14694)
|
||
|
||
Let VT be decay_t<T>[.](#func.wrap.copy.ctor-12.sentence-1)
|
||
|
||
[13](#func.wrap.copy.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14697)
|
||
|
||
*Constraints*:
|
||
|
||
- [(13.1)](#func.wrap.copy.ctor-13.1)
|
||
|
||
is_constructible_v<VT, Args...> is true, and
|
||
|
||
- [(13.2)](#func.wrap.copy.ctor-13.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.copy.ctor-13.sentence-1)
|
||
|
||
[14](#func.wrap.copy.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14706)
|
||
|
||
*Mandates*:
|
||
|
||
- [(14.1)](#func.wrap.copy.ctor-14.1)
|
||
|
||
VT is the same type as T, and
|
||
|
||
- [(14.2)](#func.wrap.copy.ctor-14.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#func.wrap.copy.ctor-14.sentence-1)
|
||
|
||
[15](#func.wrap.copy.ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14715)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.copy.ctor-15.sentence-1)
|
||
|
||
[16](#func.wrap.copy.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14720)
|
||
|
||
*Postconditions*: *this has a target object of type VT direct-non-list-initialized with std::forward<Args>(args)...[.](#func.wrap.copy.ctor-16.sentence-1)
|
||
|
||
[17](#func.wrap.copy.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14725)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.copy.ctor-17.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a pointer or a specialization of reference_wrapper[.](#func.wrap.copy.ctor-17.sentence-2)
|
||
|
||
[ð](#lib:copyable_function,constructor_____)
|
||
|
||
`template<class T, class U, class... Args>
|
||
explicit copyable_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
|
||
`
|
||
|
||
[18](#func.wrap.copy.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14739)
|
||
|
||
Let VT be decay_t<T>[.](#func.wrap.copy.ctor-18.sentence-1)
|
||
|
||
[19](#func.wrap.copy.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14742)
|
||
|
||
*Constraints*:
|
||
|
||
- [(19.1)](#func.wrap.copy.ctor-19.1)
|
||
|
||
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
|
||
|
||
- [(19.2)](#func.wrap.copy.ctor-19.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#func.wrap.copy.ctor-19.sentence-1)
|
||
|
||
[20](#func.wrap.copy.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14752)
|
||
|
||
*Mandates*:
|
||
|
||
- [(20.1)](#func.wrap.copy.ctor-20.1)
|
||
|
||
VT is the same type as T, and
|
||
|
||
- [(20.2)](#func.wrap.copy.ctor-20.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#func.wrap.copy.ctor-20.sentence-1)
|
||
|
||
[21](#func.wrap.copy.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14761)
|
||
|
||
*Preconditions*: VT meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.wrap.copy.ctor-21.sentence-1)
|
||
|
||
[22](#func.wrap.copy.ctor-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14766)
|
||
|
||
*Postconditions*: *this has a target object of type VT direct-non-list-initialized withilist, std::forward<Args>(args)...[.](#func.wrap.copy.ctor-22.sentence-1)
|
||
|
||
[23](#func.wrap.copy.ctor-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14772)
|
||
|
||
*Throws*: Any exception thrown by the initialization of the target object[.](#func.wrap.copy.ctor-23.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a pointer or a specialization of reference_wrapper[.](#func.wrap.copy.ctor-23.sentence-2)
|
||
|
||
[ð](#lib:operator=,copyable_function)
|
||
|
||
`copyable_function& operator=(const copyable_function& f);
|
||
`
|
||
|
||
[24](#func.wrap.copy.ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14785)
|
||
|
||
*Effects*: Equivalent to: copyable_function(f).swap(*this);
|
||
|
||
[25](#func.wrap.copy.ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14789)
|
||
|
||
*Returns*: *this[.](#func.wrap.copy.ctor-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function_)
|
||
|
||
`copyable_function& operator=(copyable_function&& f);
|
||
`
|
||
|
||
[26](#func.wrap.copy.ctor-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14800)
|
||
|
||
*Effects*: Equivalent to: copyable_function(std::move(f)).swap(*this);
|
||
|
||
[27](#func.wrap.copy.ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14804)
|
||
|
||
*Returns*: *this[.](#func.wrap.copy.ctor-27.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function__)
|
||
|
||
`copyable_function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[28](#func.wrap.copy.ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14815)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#func.wrap.copy.ctor-28.sentence-1)
|
||
|
||
[29](#func.wrap.copy.ctor-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14819)
|
||
|
||
*Returns*: *this[.](#func.wrap.copy.ctor-29.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function___)
|
||
|
||
`template<class F> copyable_function& operator=(F&& f);
|
||
`
|
||
|
||
[30](#func.wrap.copy.ctor-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14830)
|
||
|
||
*Effects*: Equivalent to: copyable_function(std::forward<F>(f)).swap(*this);
|
||
|
||
[31](#func.wrap.copy.ctor-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14834)
|
||
|
||
*Returns*: *this[.](#func.wrap.copy.ctor-31.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,destructor)
|
||
|
||
`~copyable_function();
|
||
`
|
||
|
||
[32](#func.wrap.copy.ctor-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14845)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#func.wrap.copy.ctor-32.sentence-1)
|
||
|
||
#### [22.10.17.5.4](#func.wrap.copy.inv) Invocation [[func.wrap.copy.inv]](func.wrap.copy.inv)
|
||
|
||
[ð](#lib:operator_bool,copyable_function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.copy.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14858)
|
||
|
||
*Returns*: true if *this has a target object, otherwise false[.](#func.wrap.copy.inv-1.sentence-1)
|
||
|
||
[ð](#lib:operator(),copyable_function)
|
||
|
||
`R operator()(ArgTypes... args) cv ref noexcept(noex);
|
||
`
|
||
|
||
[2](#func.wrap.copy.inv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14869)
|
||
|
||
*Preconditions*: *this has a target object[.](#func.wrap.copy.inv-2.sentence-1)
|
||
|
||
[3](#func.wrap.copy.inv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14873)
|
||
|
||
*Effects*: Equivalent to:return *INVOKE*<R>(static_cast<F *inv-quals*>(f), std::forward<ArgTypes>(args)...); where f is an lvalue designating the target object of *this andF is the type of f[.](#func.wrap.copy.inv-3.sentence-1)
|
||
|
||
#### [22.10.17.5.5](#func.wrap.copy.util) Utility [[func.wrap.copy.util]](func.wrap.copy.util)
|
||
|
||
[ð](#lib:swap,copyable_function)
|
||
|
||
`void swap(copyable_function& other) noexcept;
|
||
`
|
||
|
||
[1](#func.wrap.copy.util-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14891)
|
||
|
||
*Effects*: Exchanges the target objects of *this and other[.](#func.wrap.copy.util-1.sentence-1)
|
||
|
||
[ð](#lib:swap,copyable_function_)
|
||
|
||
`friend void swap(copyable_function& f1, copyable_function& f2) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.copy.util-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14902)
|
||
|
||
*Effects*: Equivalent to f1.swap(f2)[.](#func.wrap.copy.util-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,copyable_function)
|
||
|
||
`friend bool operator==(const copyable_function& f, nullptr_t) noexcept;
|
||
`
|
||
|
||
[3](#func.wrap.copy.util-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14913)
|
||
|
||
*Returns*: true if f has no target object, otherwise false[.](#func.wrap.copy.util-3.sentence-1)
|
||
|
||
#### [22.10.17.6](#func.wrap.ref) Non-owning wrapper [[func.wrap.ref]](func.wrap.ref)
|
||
|
||
#### [22.10.17.6.1](#func.wrap.ref.general) General [[func.wrap.ref.general]](func.wrap.ref.general)
|
||
|
||
[1](#func.wrap.ref.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14922)
|
||
|
||
The header provides partial specializations of function_ref for each combination of the possible replacements of
|
||
the placeholders cv and *noex* where:
|
||
|
||
- [(1.1)](#func.wrap.ref.general-1.1)
|
||
|
||
cv is either const or empty, and
|
||
|
||
- [(1.2)](#func.wrap.ref.general-1.2)
|
||
|
||
*noex* is either true or false[.](#func.wrap.ref.general-1.sentence-1)
|
||
|
||
#### [22.10.17.6.2](#func.wrap.ref.class) Class template function_ref [[func.wrap.ref.class]](func.wrap.ref.class)
|
||
|
||
[ð](#lib:function_ref)
|
||
|
||
namespace std {template<class R, class... ArgTypes>class function_ref<R(ArgTypes...) cv noexcept(*noex*)> {public:// [[func.wrap.ref.ctor]](#func.wrap.ref.ctor "22.10.17.6.3 Constructors and assignment operators"), constructors and assignment operatorstemplate<class F> function_ref(F*) noexcept; template<class F> constexpr function_ref(F&&) noexcept; template<auto f> constexpr function_ref(nontype_t<f>) noexcept; template<auto f, class U> constexpr function_ref(nontype_t<f>, U&&) noexcept; template<auto f, class T> constexpr function_ref(nontype_t<f>, cv T*) noexcept; constexpr function_ref(const function_ref&) noexcept = default; constexpr function_ref& operator=(const function_ref&) noexcept = default; template<class T> function_ref& operator=(T) = delete; // [[func.wrap.ref.inv]](#func.wrap.ref.inv "22.10.17.6.4 Invocation"), invocation R operator()(ArgTypes...) const noexcept(*noex*); private:template<class... T>static constexpr bool *is-invocable-using* = *see below*; // *exposition only* R (**thunk-ptr*)(*BoundEntityType*, Args&&...) noexcept(*noex*); // *exposition only**BoundEntityType* *bound-entity*; // *exposition only*}; // [[func.wrap.ref.deduct]](#func.wrap.ref.deduct "22.10.17.6.5 Deduction guides"), deduction guidestemplate<class F> function_ref(F*) -> function_ref<F>; template<auto f> function_ref(nontype_t<f>) -> function_ref<*see below*>; template<auto f, class T> function_ref(nontype_t<f>, T&&) -> function_ref<*see below*>;}
|
||
|
||
[1](#func.wrap.ref.class-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14971)
|
||
|
||
An object of classfunction_ref<R(Args...) cv noexcept(*noex*)> stores a pointer to function *thunk-ptr* and
|
||
an object *bound-entity*[.](#func.wrap.ref.class-1.sentence-1)
|
||
|
||
*bound-entity* has
|
||
an unspecified trivially copyable type *BoundEntityType*, that
|
||
models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]") and
|
||
is capable of storing a pointer to object value or a pointer to function value[.](#func.wrap.ref.class-1.sentence-2)
|
||
|
||
The type of *thunk-ptr* isR(*)(*BoundEntityType*, Args&&...) noexcept(*noex*)[.](#func.wrap.ref.class-1.sentence-3)
|
||
|
||
[2](#func.wrap.ref.class-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14983)
|
||
|
||
Each specialization of function_ref is
|
||
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General"))
|
||
that models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")[.](#func.wrap.ref.class-2.sentence-1)
|
||
|
||
[3](#func.wrap.ref.class-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14988)
|
||
|
||
Within [[func.wrap.ref]](#func.wrap.ref "22.10.17.6 Non-owning wrapper"),*call-args* is an argument pack with elements such thatdecltype((*call-args*))... denoteArgs&&... respectively[.](#func.wrap.ref.class-3.sentence-1)
|
||
|
||
#### [22.10.17.6.3](#func.wrap.ref.ctor) Constructors and assignment operators [[func.wrap.ref.ctor]](func.wrap.ref.ctor)
|
||
|
||
[ð](#:function_ref::is-invocable-using)
|
||
|
||
`template<class... T>
|
||
static constexpr bool is-invocable-using = see below;
|
||
`
|
||
|
||
[1](#func.wrap.ref.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15003)
|
||
|
||
If *noex* is true,*is-invocable-using*<T...> is equal to:is_nothrow_invocable_r_v<R, T..., ArgTypes...>
|
||
|
||
Otherwise, *is-invocable-using*<T...> is equal to:is_invocable_r_v<R, T..., ArgTypes...>
|
||
|
||
[ð](#lib:function_ref,constructor)
|
||
|
||
`template<class F> function_ref(F* f) noexcept;
|
||
`
|
||
|
||
[2](#func.wrap.ref.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15021)
|
||
|
||
*Constraints*:
|
||
|
||
- [(2.1)](#func.wrap.ref.ctor-2.1)
|
||
|
||
is_function_v<F> is true, and
|
||
|
||
- [(2.2)](#func.wrap.ref.ctor-2.2)
|
||
|
||
*is-invocable-using*<F> is true[.](#func.wrap.ref.ctor-2.sentence-1)
|
||
|
||
[3](#func.wrap.ref.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15028)
|
||
|
||
*Preconditions*: f is not a null pointer[.](#func.wrap.ref.ctor-3.sentence-1)
|
||
|
||
[4](#func.wrap.ref.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15032)
|
||
|
||
*Effects*: Initializes*bound-entity* with f, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#func.wrap.ref.ctor-4.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor_)
|
||
|
||
`template<class F> constexpr function_ref(F&& f) noexcept;
|
||
`
|
||
|
||
[5](#func.wrap.ref.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15049)
|
||
|
||
Let T be remove_reference_t<F>[.](#func.wrap.ref.ctor-5.sentence-1)
|
||
|
||
[6](#func.wrap.ref.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15052)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#func.wrap.ref.ctor-6.1)
|
||
|
||
remove_cvref_t<F> is not the same type as function_ref,
|
||
|
||
- [(6.2)](#func.wrap.ref.ctor-6.2)
|
||
|
||
is_member_pointer_v<T> is false, and
|
||
|
||
- [(6.3)](#func.wrap.ref.ctor-6.3)
|
||
|
||
*is-invocable-using*<cv T&> is true[.](#func.wrap.ref.ctor-6.sentence-1)
|
||
|
||
[7](#func.wrap.ref.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15060)
|
||
|
||
*Effects*: Initializes*bound-entity* with addressof(f), and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) toinvoke_r<R>(static_cast<cv T&>(f), *call-args*...)[.](#func.wrap.ref.ctor-7.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor__)
|
||
|
||
`template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
|
||
`
|
||
|
||
[8](#func.wrap.ref.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15077)
|
||
|
||
Let F be decltype(f)[.](#func.wrap.ref.ctor-8.sentence-1)
|
||
|
||
[9](#func.wrap.ref.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15080)
|
||
|
||
*Constraints*: *is-invocable-using*<F> is true[.](#func.wrap.ref.ctor-9.sentence-1)
|
||
|
||
[10](#func.wrap.ref.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15084)
|
||
|
||
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
|
||
then f != nullptr is true[.](#func.wrap.ref.ctor-10.sentence-1)
|
||
|
||
[11](#func.wrap.ref.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15089)
|
||
|
||
*Effects*: Initializes*bound-entity* with a pointer to an unspecified object or
|
||
null pointer value, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) toinvoke_r<R>(f, *call-args*...)[.](#func.wrap.ref.ctor-11.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor___)
|
||
|
||
`template<auto f, class U>
|
||
constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
|
||
`
|
||
|
||
[12](#func.wrap.ref.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15108)
|
||
|
||
Let T be remove_reference_t<U> andF be decltype(f)[.](#func.wrap.ref.ctor-12.sentence-1)
|
||
|
||
[13](#func.wrap.ref.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15112)
|
||
|
||
*Constraints*:
|
||
|
||
- [(13.1)](#func.wrap.ref.ctor-13.1)
|
||
|
||
is_rvalue_reference_v<U&&> is false, and
|
||
|
||
- [(13.2)](#func.wrap.ref.ctor-13.2)
|
||
|
||
*is-invocable-using*<F, cv T&> is true[.](#func.wrap.ref.ctor-13.sentence-1)
|
||
|
||
[14](#func.wrap.ref.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15119)
|
||
|
||
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
|
||
then f != nullptr is true[.](#func.wrap.ref.ctor-14.sentence-1)
|
||
|
||
[15](#func.wrap.ref.ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15124)
|
||
|
||
*Effects*: Initializes*bound-entity* with addressof(obj), and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) toinvoke_r<R>(f, static_cast<cv T&>(obj), *call-args*...)[.](#func.wrap.ref.ctor-15.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor____)
|
||
|
||
`template<auto f, class T>
|
||
constexpr function_ref(nontype_t<f>, cv T* obj) noexcept;
|
||
`
|
||
|
||
[16](#func.wrap.ref.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15142)
|
||
|
||
Let F be decltype(f)[.](#func.wrap.ref.ctor-16.sentence-1)
|
||
|
||
[17](#func.wrap.ref.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15145)
|
||
|
||
*Constraints*: *is-invocable-using*<F, cv T*> is true[.](#func.wrap.ref.ctor-17.sentence-1)
|
||
|
||
[18](#func.wrap.ref.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15149)
|
||
|
||
*Mandates*: If is_pointer_v<F> || is_member_pointer_v<F> is true,
|
||
then f != nullptr is true[.](#func.wrap.ref.ctor-18.sentence-1)
|
||
|
||
[19](#func.wrap.ref.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15154)
|
||
|
||
*Preconditions*: If is_member_pointer_v<F> is true,obj is not a null pointer[.](#func.wrap.ref.ctor-19.sentence-1)
|
||
|
||
[20](#func.wrap.ref.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15159)
|
||
|
||
*Effects*: Initializes*bound-entity* with obj, and*thunk-ptr* with the address of a function *thunk* such that*thunk*(*bound-entity*, *call-args*...) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) toinvoke_r<R>(f, obj, *call-args*...)[.](#func.wrap.ref.ctor-20.sentence-1)
|
||
|
||
[ð](#lib:operator=,function_ref)
|
||
|
||
`template<class T> function_ref& operator=(T) = delete;
|
||
`
|
||
|
||
[21](#func.wrap.ref.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15176)
|
||
|
||
*Constraints*:
|
||
|
||
- [(21.1)](#func.wrap.ref.ctor-21.1)
|
||
|
||
T is not the same type as function_ref,
|
||
|
||
- [(21.2)](#func.wrap.ref.ctor-21.2)
|
||
|
||
is_pointer_v<T> is false, and
|
||
|
||
- [(21.3)](#func.wrap.ref.ctor-21.3)
|
||
|
||
T is not a specialization of nontype_t[.](#func.wrap.ref.ctor-21.sentence-1)
|
||
|
||
#### [22.10.17.6.4](#func.wrap.ref.inv) Invocation [[func.wrap.ref.inv]](func.wrap.ref.inv)
|
||
|
||
[ð](#lib:operator(),function_ref)
|
||
|
||
`R operator()(ArgTypes... args) const noexcept(noex);
|
||
`
|
||
|
||
[1](#func.wrap.ref.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15193)
|
||
|
||
*Effects*: Equivalent to:return *thunk-ptr*(*bound-entity*, std::forward<ArgTypes>(args)...);
|
||
|
||
#### [22.10.17.6.5](#func.wrap.ref.deduct) Deduction guides [[func.wrap.ref.deduct]](func.wrap.ref.deduct)
|
||
|
||
[ð](#func.wrap.ref.deduct-itemdecl:1)
|
||
|
||
`template<class F>
|
||
function_ref(F*) -> function_ref<F>;
|
||
`
|
||
|
||
[1](#func.wrap.ref.deduct-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15207)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#func.wrap.ref.deduct-1.sentence-1)
|
||
|
||
[ð](#func.wrap.ref.deduct-itemdecl:2)
|
||
|
||
`template<auto f>
|
||
function_ref(nontype_t<f>) -> function_ref<see below>;
|
||
`
|
||
|
||
[2](#func.wrap.ref.deduct-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15218)
|
||
|
||
Let F be remove_pointer_t<decltype(f)>[.](#func.wrap.ref.deduct-2.sentence-1)
|
||
|
||
[3](#func.wrap.ref.deduct-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15221)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#func.wrap.ref.deduct-3.sentence-1)
|
||
|
||
[4](#func.wrap.ref.deduct-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15225)
|
||
|
||
*Remarks*: The deduced type is function_ref<F>[.](#func.wrap.ref.deduct-4.sentence-1)
|
||
|
||
[ð](#func.wrap.ref.deduct-itemdecl:3)
|
||
|
||
`template<auto f, class T>
|
||
function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
|
||
`
|
||
|
||
[5](#func.wrap.ref.deduct-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15236)
|
||
|
||
Let F be decltype(f)[.](#func.wrap.ref.deduct-5.sentence-1)
|
||
|
||
[6](#func.wrap.ref.deduct-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15239)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#func.wrap.ref.deduct-6.1)
|
||
|
||
F is of the formR(G::*)(A...) cv &opt noexcept(E) for a type G, or
|
||
|
||
- [(6.2)](#func.wrap.ref.deduct-6.2)
|
||
|
||
F is of the formM G::* for a type G and an object type M,
|
||
in which case
|
||
let R be invoke_result_t<F, T&>,A... be an empty pack, andE be false, or
|
||
|
||
- [(6.3)](#func.wrap.ref.deduct-6.3)
|
||
|
||
F is of the formR(*)(G, A...) noexcept(E) for a type G[.](#func.wrap.ref.deduct-6.sentence-1)
|
||
|
||
[7](#func.wrap.ref.deduct-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15259)
|
||
|
||
*Remarks*: The deduced type is function_ref<R(A...) noexcept(E)>[.](#func.wrap.ref.deduct-7.sentence-1)
|
||
|
||
### [22.10.18](#func.search) Searchers [[func.search]](func.search)
|
||
|
||
#### [22.10.18.1](#func.search.general) General [[func.search.general]](func.search.general)
|
||
|
||
[1](#func.search.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15269)
|
||
|
||
Subclause [[func.search]](#func.search "22.10.18 Searchers") provides function object types ([function.objects]) for
|
||
operations that search for a sequence [pat_first, pat_last) in another
|
||
sequence [first, last) that is provided to the object's function call
|
||
operator[.](#func.search.general-1.sentence-1)
|
||
|
||
The first sequence (the pattern to be searched for) is provided to
|
||
the object's constructor, and the second (the sequence to be searched) is
|
||
provided to the function call operator[.](#func.search.general-1.sentence-2)
|
||
|
||
[2](#func.search.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15277)
|
||
|
||
Each specialization of a class template specified in [[func.search]](#func.search "22.10.18 Searchers") shall meet the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.search.general-2.sentence-1)
|
||
|
||
Template parameters named
|
||
|
||
- [(2.1)](#func.search.general-2.1)
|
||
|
||
ForwardIterator,
|
||
|
||
- [(2.2)](#func.search.general-2.2)
|
||
|
||
ForwardIterator1,
|
||
|
||
- [(2.3)](#func.search.general-2.3)
|
||
|
||
ForwardIterator2,
|
||
|
||
- [(2.4)](#func.search.general-2.4)
|
||
|
||
RandomAccessIterator,
|
||
|
||
- [(2.5)](#func.search.general-2.5)
|
||
|
||
RandomAccessIterator1,
|
||
|
||
- [(2.6)](#func.search.general-2.6)
|
||
|
||
RandomAccessIterator2, and
|
||
|
||
- [(2.7)](#func.search.general-2.7)
|
||
|
||
BinaryPredicate
|
||
|
||
of templates specified in[[func.search]](#func.search "22.10.18 Searchers") shall meet the same requirements and semantics as
|
||
specified in [[algorithms.general]](algorithms.general "26.1 General")[.](#func.search.general-2.sentence-2)
|
||
|
||
Template parameters named Hash shall meet the [*Cpp17Hash*](hash.requirements#:Cpp17Hash "16.4.4.5 Cpp17Hash requirements [hash.requirements]") requirements (Table [37](hash.requirements#tab:cpp17.hash "Table 37: Cpp17Hash requirements"))[.](#func.search.general-2.sentence-3)
|
||
|
||
[3](#func.search.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15296)
|
||
|
||
The Boyer-Moore searcher implements the Boyer-Moore search algorithm[.](#func.search.general-3.sentence-1)
|
||
|
||
The Boyer-Moore-Horspool searcher implements the Boyer-Moore-Horspool search algorithm[.](#func.search.general-3.sentence-2)
|
||
|
||
In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool[.](#func.search.general-3.sentence-3)
|
||
|
||
#### [22.10.18.2](#func.search.default) Class template default_searcher [[func.search.default]](func.search.default)
|
||
|
||
[ð](#lib:default_searcher)
|
||
|
||
namespace std {template<class ForwardIterator1, class BinaryPredicate = equal_to<>>class default_searcher {public:constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last,
|
||
BinaryPredicate pred = BinaryPredicate()); template<class ForwardIterator2>constexpr pair<ForwardIterator2, ForwardIterator2>operator()(ForwardIterator2 first, ForwardIterator2 last) const; private: ForwardIterator1 pat_first_; // *exposition only* ForwardIterator1 pat_last_; // *exposition only* BinaryPredicate pred_; // *exposition only*};}
|
||
|
||
[ð](#lib:default_searcher,constructor)
|
||
|
||
`constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last,
|
||
BinaryPredicate pred = BinaryPredicate());
|
||
`
|
||
|
||
[1](#func.search.default-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15331)
|
||
|
||
*Effects*: Constructs a default_searcher object, initializing pat_first_ with pat_first, pat_last_ with pat_last, andpred_ with pred[.](#func.search.default-1.sentence-1)
|
||
|
||
[2](#func.search.default-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15338)
|
||
|
||
*Throws*: Any exception thrown by the copy constructor of BinaryPredicate orForwardIterator1[.](#func.search.default-2.sentence-1)
|
||
|
||
[ð](#lib:operator(),default_searcher)
|
||
|
||
`template<class ForwardIterator2>
|
||
constexpr pair<ForwardIterator2, ForwardIterator2>
|
||
operator()(ForwardIterator2 first, ForwardIterator2 last) const;
|
||
`
|
||
|
||
[3](#func.search.default-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15352)
|
||
|
||
*Effects*: Returns a pair of iterators i and j such that
|
||
|
||
- [(3.1)](#func.search.default-3.1)
|
||
|
||
i == search(first, last, pat_first_, pat_last_, pred_), and
|
||
|
||
- [(3.2)](#func.search.default-3.2)
|
||
|
||
if i == last, then j == last,
|
||
otherwise j == next(i, distance(pat_first_, pat_last_))[.](#func.search.default-3.sentence-1)
|
||
|
||
#### [22.10.18.3](#func.search.bm) Class template boyer_moore_searcher [[func.search.bm]](func.search.bm)
|
||
|
||
[ð](#lib:boyer_moore_searcher)
|
||
|
||
namespace std {template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>>class boyer_moore_searcher {public: boyer_moore_searcher(RandomAccessIterator1 pat_first,
|
||
RandomAccessIterator1 pat_last,
|
||
Hash hf = Hash(),
|
||
BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2>operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // *exposition only* RandomAccessIterator1 pat_last_; // *exposition only* Hash hash_; // *exposition only* BinaryPredicate pred_; // *exposition only*};}
|
||
|
||
[ð](#lib:boyer_moore_searcher,constructor)
|
||
|
||
`boyer_moore_searcher(RandomAccessIterator1 pat_first,
|
||
RandomAccessIterator1 pat_last,
|
||
Hash hf = Hash(),
|
||
BinaryPredicate pred = BinaryPredicate());
|
||
`
|
||
|
||
[1](#func.search.bm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15399)
|
||
|
||
*Preconditions*: The value type of RandomAccessIterator1 meets
|
||
the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and[*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.search.bm-1.sentence-1)
|
||
|
||
[2](#func.search.bm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15406)
|
||
|
||
Let V be iterator_traits<RandomAccessIterator1>::value_type[.](#func.search.bm-2.sentence-1)
|
||
|
||
For any two values A and B of type V,
|
||
if pred(A, B) == true, then hf(A) == hf(B) is true[.](#func.search.bm-2.sentence-2)
|
||
|
||
[3](#func.search.bm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15411)
|
||
|
||
*Effects*: Initializespat_first_ with pat_first,pat_last_ with pat_last,hash_ with hf, andpred_ with pred[.](#func.search.bm-3.sentence-1)
|
||
|
||
[4](#func.search.bm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15420)
|
||
|
||
*Throws*: Any exception thrown by the copy constructor of RandomAccessIterator1,
|
||
or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1,
|
||
or the copy constructor or operator() of BinaryPredicate or Hash[.](#func.search.bm-4.sentence-1)
|
||
|
||
May throw bad_alloc if additional memory needed for internal data structures cannot be allocated[.](#func.search.bm-4.sentence-2)
|
||
|
||
[ð](#lib:operator(),boyer_moore_searcher)
|
||
|
||
`template<class RandomAccessIterator2>
|
||
pair<RandomAccessIterator2, RandomAccessIterator2>
|
||
operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
|
||
`
|
||
|
||
[5](#func.search.bm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15436)
|
||
|
||
*Mandates*: RandomAccessIterator1 and RandomAccessIterator2 have the same value type[.](#func.search.bm-5.sentence-1)
|
||
|
||
[6](#func.search.bm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15441)
|
||
|
||
*Effects*: Finds a subsequence of equal values in a sequence[.](#func.search.bm-6.sentence-1)
|
||
|
||
[7](#func.search.bm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15445)
|
||
|
||
*Returns*: A pair of iterators i and j such that
|
||
|
||
- [(7.1)](#func.search.bm-7.1)
|
||
|
||
i is the first iterator
|
||
in the range [first, last - (pat_last_ - pat_first_)) such that
|
||
for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds:pred(*(i + n), *(pat_first_ + n)) != false, and
|
||
|
||
- [(7.2)](#func.search.bm-7.2)
|
||
|
||
j == next(i, distance(pat_first_, pat_last_))[.](#func.search.bm-7.sentence-1)
|
||
|
||
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty,
|
||
otherwise returns make_pair(last, last) if no such iterator is found[.](#func.search.bm-7.sentence-2)
|
||
|
||
[8](#func.search.bm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15459)
|
||
|
||
*Complexity*: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate[.](#func.search.bm-8.sentence-1)
|
||
|
||
#### [22.10.18.4](#func.search.bmh) Class template boyer_moore_horspool_searcher [[func.search.bmh]](func.search.bmh)
|
||
|
||
[ð](#lib:boyer_moore_horspool_searcher)
|
||
|
||
namespace std {template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>>class boyer_moore_horspool_searcher {public: boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first,
|
||
RandomAccessIterator1 pat_last,
|
||
Hash hf = Hash(),
|
||
BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2>operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // *exposition only* RandomAccessIterator1 pat_last_; // *exposition only* Hash hash_; // *exposition only* BinaryPredicate pred_; // *exposition only*};}
|
||
|
||
[ð](#lib:boyer_moore_horspool_searcher,constructor)
|
||
|
||
`boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first,
|
||
RandomAccessIterator1 pat_last,
|
||
Hash hf = Hash(),
|
||
BinaryPredicate pred = BinaryPredicate());
|
||
`
|
||
|
||
[1](#func.search.bmh-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15501)
|
||
|
||
*Preconditions*: The value type of RandomAccessIterator1 meets the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func.search.bmh-1.sentence-1)
|
||
|
||
[2](#func.search.bmh-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15506)
|
||
|
||
Let V be iterator_traits<RandomAccessIterator1>::value_type[.](#func.search.bmh-2.sentence-1)
|
||
|
||
For any two values A and B of type V,
|
||
if pred(A, B) == true, then hf(A) == hf(B) is true[.](#func.search.bmh-2.sentence-2)
|
||
|
||
[3](#func.search.bmh-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15511)
|
||
|
||
*Effects*: Initializespat_first_ with pat_first,pat_last_ with pat_last,hash_ with hf, andpred_ with pred[.](#func.search.bmh-3.sentence-1)
|
||
|
||
[4](#func.search.bmh-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15520)
|
||
|
||
*Throws*: Any exception thrown by the copy constructor of RandomAccessIterator1,
|
||
or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1,
|
||
or the copy constructor or operator() of BinaryPredicate or Hash[.](#func.search.bmh-4.sentence-1)
|
||
|
||
May throw bad_alloc if additional memory needed for internal data structures cannot be allocated[.](#func.search.bmh-4.sentence-2)
|
||
|
||
[ð](#lib:operator(),boyer_moore_horspool_searcher)
|
||
|
||
`template<class RandomAccessIterator2>
|
||
pair<RandomAccessIterator2, RandomAccessIterator2>
|
||
operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
|
||
`
|
||
|
||
[5](#func.search.bmh-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15536)
|
||
|
||
*Mandates*: RandomAccessIterator1 and RandomAccessIterator2 have the same value type[.](#func.search.bmh-5.sentence-1)
|
||
|
||
[6](#func.search.bmh-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15541)
|
||
|
||
*Effects*: Finds a subsequence of equal values in a sequence[.](#func.search.bmh-6.sentence-1)
|
||
|
||
[7](#func.search.bmh-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15545)
|
||
|
||
*Returns*: A pair of iterators i and j such that
|
||
|
||
- [(7.1)](#func.search.bmh-7.1)
|
||
|
||
i is the first iterator in the range
|
||
[first, last - (pat_last_ - pat_first_)) such that
|
||
for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds:pred(*(i + n), *(pat_first_ + n)) != false, and
|
||
|
||
- [(7.2)](#func.search.bmh-7.2)
|
||
|
||
j == next(i, distance(pat_first_, pat_last_))[.](#func.search.bmh-7.sentence-1)
|
||
|
||
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty,
|
||
otherwise returns make_pair(last, last) if no such iterator is found[.](#func.search.bmh-7.sentence-2)
|
||
|
||
[8](#func.search.bmh-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15559)
|
||
|
||
*Complexity*: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate[.](#func.search.bmh-8.sentence-1)
|
||
|
||
### [22.10.19](#unord.hash) Class template hash [[unord.hash]](unord.hash)
|
||
|
||
[1](#unord.hash-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15566)
|
||
|
||
The unordered associative containers defined in [[unord]](unord "23.5 Unordered associative containers") use
|
||
specializations of the class template hash ([[functional.syn]](#functional.syn "22.10.2 Header <functional> synopsis"))
|
||
as the default hash function[.](#unord.hash-1.sentence-1)
|
||
|
||
[2](#unord.hash-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15573)
|
||
|
||
Each specialization of hash is either enabled or disabled,
|
||
as described below[.](#unord.hash-2.sentence-1)
|
||
|
||
[*Note [1](#unord.hash-note-1)*:
|
||
|
||
Enabled specializations meet the [*Cpp17Hash*](hash.requirements#:Cpp17Hash "16.4.4.5 Cpp17Hash requirements [hash.requirements]") requirements, and
|
||
disabled specializations do not[.](#unord.hash-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
Each header that declares the template hash provides enabled specializations of hash for nullptr_t and
|
||
all cv-unqualified arithmetic, enumeration, and pointer types[.](#unord.hash-2.sentence-3)
|
||
|
||
For any type Key for which neither the library nor the user provides
|
||
an explicit or partial specialization of the class template hash,hash<Key> is disabled[.](#unord.hash-2.sentence-4)
|
||
|
||
[3](#unord.hash-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15587)
|
||
|
||
If the library provides an explicit or partial specialization of hash<Key>,
|
||
that specialization is enabled except as noted otherwise,
|
||
and its member functions are noexcept except as noted otherwise[.](#unord.hash-3.sentence-1)
|
||
|
||
[4](#unord.hash-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15592)
|
||
|
||
If H is a disabled specialization of hash,
|
||
these values are false:is_default_constructible_v<H>,is_copy_constructible_v<H>,is_move_constructible_v<H>,is_copy_assignable_v<H>, andis_move_assignable_v<H>[.](#unord.hash-4.sentence-1)
|
||
|
||
Disabled specializations of hash are not function object types ([function.objects])[.](#unord.hash-4.sentence-2)
|
||
|
||
[*Note [2](#unord.hash-note-2)*:
|
||
|
||
This means that the specialization of hash exists, but
|
||
any attempts to use it as a [*Cpp17Hash*](hash.requirements#:Cpp17Hash "16.4.4.5 Cpp17Hash requirements [hash.requirements]") will be ill-formed[.](#unord.hash-4.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[5](#unord.hash-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15607)
|
||
|
||
An enabled specialization hash<Key> will:
|
||
|
||
- [(5.1)](#unord.hash-5.1)
|
||
|
||
meet the [*Cpp17Hash*](hash.requirements#:Cpp17Hash "16.4.4.5 Cpp17Hash requirements [hash.requirements]") requirements (Table [37](hash.requirements#tab:cpp17.hash "Table 37: Cpp17Hash requirements")),
|
||
with Key as the function
|
||
call argument type, the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [30](utility.arg.requirements#tab:cpp17.defaultconstructible "Table 30: Cpp17DefaultConstructible requirements")),
|
||
the [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [34](utility.arg.requirements#tab:cpp17.copyassignable "Table 34: Cpp17CopyAssignable requirements (in addition to Cpp17MoveAssignable)")),
|
||
the [*Cpp17Swappable*](swappable.requirements#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")),
|
||
|
||
- [(5.2)](#unord.hash-5.2)
|
||
|
||
meet the requirement that if k1 == k2 is true, h(k1) == h(k2) is
|
||
also true, where h is an object of type hash<Key> and k1 and k2 are objects of type Key;
|
||
|
||
- [(5.3)](#unord.hash-5.3)
|
||
|
||
meet the requirement that the expression h(k), where h is an object of type hash<Key> and k is an object of typeKey, shall not throw an exception unless hash<Key> is a
|
||
program-defined specialization[.](#unord.hash-5.sentence-1)
|