1769 lines
63 KiB
Markdown
1769 lines
63 KiB
Markdown
[func.wrap]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.10 Function objects [[function.objects]](function.objects#func.wrap)
|
||
|
||
### 22.10.17 Polymorphic function wrappers [func.wrap]
|
||
|
||
#### [22.10.17.1](#general) General [[func.wrap.general]](func.wrap.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13594)
|
||
|
||
Subclause [func.wrap] describes polymorphic wrapper classes that
|
||
encapsulate arbitrary callable objects[.](#general-1.sentence-1)
|
||
|
||
[2](#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[.](#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[.](#general-2.sentence-2)
|
||
|
||
[*Example [1](#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](#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[.](#general-3.sentence-1)
|
||
|
||
#### [22.10.17.2](#badcall) Class bad_function_call [[func.wrap.badcall]](func.wrap.badcall)
|
||
|
||
[1](#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.inv "22.10.17.3.5 Invocation"))
|
||
when the function wrapper object has no target[.](#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](#badcall-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13645)
|
||
|
||
*Returns*: Animplementation-defined ntbs[.](#badcall-2.sentence-1)
|
||
|
||
#### [22.10.17.3](#func) Class template function [[func.wrap.func]](func.wrap.func)
|
||
|
||
#### [22.10.17.3.1](#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.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.mod "22.10.17.3.3 Modifiers"), function modifiersvoid swap(function&) noexcept; // [[func.wrap.func.cap]](#func.cap "22.10.17.3.4 Capacity"), function capacityexplicit operator bool() const noexcept; // [[func.wrap.func.inv]](#func.inv "22.10.17.3.5 Invocation"), function invocation R operator()(ArgTypes...) const; // [[func.wrap.func.targ]](#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.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.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.general-1.sentence-2)
|
||
|
||
[2](#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.general-2.sentence-1)
|
||
|
||
[3](#func.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13712)
|
||
|
||
[*Note [1](#func.general-note-1)*:
|
||
|
||
The types deduced by the deduction guides for function might change in future revisions of C++[.](#func.general-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.3.2](#func.con) Constructors and destructor [[func.wrap.func.con]](func.wrap.func.con)
|
||
|
||
[ð](#lib:function,constructor)
|
||
|
||
`function() noexcept;
|
||
`
|
||
|
||
[1](#func.con-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13726)
|
||
|
||
*Postconditions*: !*this[.](#func.con-1.sentence-1)
|
||
|
||
[ð](#lib:function,constructor_)
|
||
|
||
`function(nullptr_t) noexcept;
|
||
`
|
||
|
||
[2](#func.con-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13737)
|
||
|
||
*Postconditions*: !*this[.](#func.con-2.sentence-1)
|
||
|
||
[ð](#lib:function,constructor__)
|
||
|
||
`function(const function& f);
|
||
`
|
||
|
||
[3](#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.con-3.sentence-1)
|
||
|
||
[4](#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.con-4.sentence-1)
|
||
|
||
Otherwise, may throw bad_alloc or any exception thrown by the copy constructor of the stored callable object[.](#func.con-4.sentence-2)
|
||
|
||
[5](#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.con-5.sentence-1)
|
||
|
||
[ð](#lib:function,constructor___)
|
||
|
||
`function(function&& f) noexcept;
|
||
`
|
||
|
||
[6](#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.con-6.sentence-1)
|
||
|
||
[7](#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.con-7.sentence-1)
|
||
|
||
[ð](#lib:function,constructor____)
|
||
|
||
`template<class F> function(F&& f);
|
||
`
|
||
|
||
[8](#func.con-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13795)
|
||
|
||
Let FD be decay_t<F>[.](#func.con-8.sentence-1)
|
||
|
||
[9](#func.con-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13798)
|
||
|
||
*Constraints*:
|
||
|
||
- [(9.1)](#func.con-9.1)
|
||
|
||
is_same_v<remove_cvref_t<F>, function> is false, and
|
||
|
||
- [(9.2)](#func.con-9.2)
|
||
|
||
is_invocable_r_v<R, FD&, ArgTypes...> is true[.](#func.con-9.sentence-1)
|
||
|
||
[10](#func.con-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13807)
|
||
|
||
*Mandates*:
|
||
|
||
- [(10.1)](#func.con-10.1)
|
||
|
||
is_copy_constructible_v<FD> is true, and
|
||
|
||
- [(10.2)](#func.con-10.2)
|
||
|
||
is_constructible_v<FD, F> is true[.](#func.con-10.sentence-1)
|
||
|
||
[11](#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.con-11.sentence-1)
|
||
|
||
[12](#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.con-12.1)
|
||
|
||
f is a null function pointer value[.](#func.con-12.1.sentence-1)
|
||
|
||
- [(12.2)](#func.con-12.2)
|
||
|
||
f is a null member pointer value[.](#func.con-12.2.sentence-1)
|
||
|
||
- [(12.3)](#func.con-12.3)
|
||
|
||
remove_cvref_t<F> is
|
||
a specialization of the function class template, and!f is true[.](#func.con-12.3.sentence-1)
|
||
|
||
[13](#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.con-13.sentence-1)
|
||
|
||
[14](#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.con-14.sentence-1)
|
||
|
||
Otherwise, may throw bad_alloc or
|
||
any exception thrown by the initialization of the target object[.](#func.con-14.sentence-2)
|
||
|
||
[15](#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.con-15.sentence-1)
|
||
|
||
[ð](#func.con-itemdecl:6)
|
||
|
||
`template<class F> function(F) -> function<see below>;
|
||
`
|
||
|
||
[16](#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.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.con-16.2)
|
||
|
||
F::operator() is a static member function anddecltype(&F::operator()) is of the formR(*)(A...) noexceptopt[.](#func.con-16.sentence-1)
|
||
|
||
[17](#func.con-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13874)
|
||
|
||
*Remarks*: The deduced type is function<R(A...)>[.](#func.con-17.sentence-1)
|
||
|
||
[18](#func.con-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13878)
|
||
|
||
[*Example [1](#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.con-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13895)
|
||
|
||
*Effects*: As if by function(f).swap(*this);
|
||
|
||
[20](#func.con-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13899)
|
||
|
||
*Returns*: *this[.](#func.con-20.sentence-1)
|
||
|
||
[ð](#lib:operator=,function_)
|
||
|
||
`function& operator=(function&& f);
|
||
`
|
||
|
||
[21](#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.con-21.sentence-1)
|
||
|
||
[22](#func.con-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13915)
|
||
|
||
*Returns*: *this[.](#func.con-22.sentence-1)
|
||
|
||
[ð](#lib:operator=,function__)
|
||
|
||
`function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[23](#func.con-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13926)
|
||
|
||
*Effects*: If *this != nullptr, destroys the target of this[.](#func.con-23.sentence-1)
|
||
|
||
[24](#func.con-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13930)
|
||
|
||
*Postconditions*: !(*this)[.](#func.con-24.sentence-1)
|
||
|
||
[25](#func.con-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13934)
|
||
|
||
*Returns*: *this[.](#func.con-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,function___)
|
||
|
||
`template<class F> function& operator=(F&& f);
|
||
`
|
||
|
||
[26](#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.con-26.sentence-1)
|
||
|
||
[27](#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.con-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13953)
|
||
|
||
*Returns*: *this[.](#func.con-28.sentence-1)
|
||
|
||
[ð](#lib:operator=,function____)
|
||
|
||
`template<class F> function& operator=(reference_wrapper<F> f) noexcept;
|
||
`
|
||
|
||
[29](#func.con-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13964)
|
||
|
||
*Effects*: As if by: function(f).swap(*this);
|
||
|
||
[30](#func.con-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13968)
|
||
|
||
*Returns*: *this[.](#func.con-30.sentence-1)
|
||
|
||
[ð](#lib:function,destructor)
|
||
|
||
`~function();
|
||
`
|
||
|
||
[31](#func.con-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13979)
|
||
|
||
*Effects*: If *this != nullptr, destroys the target of this[.](#func.con-31.sentence-1)
|
||
|
||
#### [22.10.17.3.3](#func.mod) Modifiers [[func.wrap.func.mod]](func.wrap.func.mod)
|
||
|
||
[ð](#lib:swap,function)
|
||
|
||
`void swap(function& other) noexcept;
|
||
`
|
||
|
||
[1](#func.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13992)
|
||
|
||
*Effects*: Interchanges the target objects of *this and other[.](#func.mod-1.sentence-1)
|
||
|
||
#### [22.10.17.3.4](#func.cap) Capacity [[func.wrap.func.cap]](func.wrap.func.cap)
|
||
|
||
[ð](#lib:operator_bool,function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#func.cap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14005)
|
||
|
||
*Returns*: true if *this has a target, otherwise false[.](#func.cap-1.sentence-1)
|
||
|
||
#### [22.10.17.3.5](#func.inv) Invocation [[func.wrap.func.inv]](func.wrap.func.inv)
|
||
|
||
[ð](#lib:function,invocation)
|
||
|
||
`R operator()(ArgTypes... args) const;
|
||
`
|
||
|
||
[1](#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.inv-1.sentence-1)
|
||
|
||
[2](#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.inv-2.sentence-1)
|
||
|
||
#### [22.10.17.3.6](#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.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.targ-1.sentence-1)
|
||
|
||
[ð](#lib:target,function)
|
||
|
||
`template<class T> T* target() noexcept;
|
||
template<class T> const T* target() const noexcept;
|
||
`
|
||
|
||
[2](#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.targ-2.sentence-1)
|
||
|
||
#### [22.10.17.3.7](#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.nullptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14066)
|
||
|
||
*Returns*: !f[.](#func.nullptr-1.sentence-1)
|
||
|
||
#### [22.10.17.3.8](#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.alg-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14080)
|
||
|
||
*Effects*: As if by: f1.swap(f2);
|
||
|
||
#### [22.10.17.4](#move) Move-only wrapper [[func.wrap.move]](func.wrap.move)
|
||
|
||
#### [22.10.17.4.1](#move.general) General [[func.wrap.move.general]](func.wrap.move.general)
|
||
|
||
[1](#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)](#move.general-1.1)
|
||
|
||
cv is either const or empty,
|
||
|
||
- [(1.2)](#move.general-1.2)
|
||
|
||
*ref* is either &, &&, or empty, and
|
||
|
||
- [(1.3)](#move.general-1.3)
|
||
|
||
*noex* is either true or false[.](#move.general-1.sentence-1)
|
||
|
||
[2](#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)](#move.general-2.1)
|
||
|
||
If *ref* is empty, let *inv-quals* be cv&,
|
||
|
||
- [(2.2)](#move.general-2.2)
|
||
|
||
otherwise, let *inv-quals* be cv *ref*[.](#move.general-2.sentence-1)
|
||
|
||
#### [22.10.17.4.2](#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]](#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]](#move.inv "22.10.17.4.4 Invocation"), invocationexplicit operator bool() const noexcept;
|
||
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.move.util]](#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](#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"))[.](#move.class-1.sentence-1)
|
||
|
||
These wrappers can store, move, and call arbitrary callable objects,
|
||
given a call signature[.](#move.class-1.sentence-2)
|
||
|
||
[2](#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[.](#move.class-2.sentence-1)
|
||
|
||
[*Note [1](#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[.](#move.class-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.4.3](#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](#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](#move.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14199)
|
||
|
||
*Postconditions*: *this has no target object[.](#move.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,constructor_)
|
||
|
||
`move_only_function(move_only_function&& f) noexcept;
|
||
`
|
||
|
||
[3](#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[.](#move.ctor-3.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,constructor__)
|
||
|
||
`template<class F> move_only_function(F&& f);
|
||
`
|
||
|
||
[4](#move.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14223)
|
||
|
||
Let VT be decay_t<F>[.](#move.ctor-4.sentence-1)
|
||
|
||
[5](#move.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14226)
|
||
|
||
*Constraints*:
|
||
|
||
- [(5.1)](#move.ctor-5.1)
|
||
|
||
remove_cvref_t<F> is not the same type as move_only_function, and
|
||
|
||
- [(5.2)](#move.ctor-5.2)
|
||
|
||
remove_cvref_t<F> is not a specialization of in_place_type_t, and
|
||
|
||
- [(5.3)](#move.ctor-5.3)
|
||
|
||
*is-callable-from*<VT> is true[.](#move.ctor-5.sentence-1)
|
||
|
||
[6](#move.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14237)
|
||
|
||
*Mandates*: is_constructible_v<VT, F> is true[.](#move.ctor-6.sentence-1)
|
||
|
||
[7](#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[.](#move.ctor-7.sentence-1)
|
||
|
||
[8](#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)](#move.ctor-8.1)
|
||
|
||
f is a null function pointer value, or
|
||
|
||
- [(8.2)](#move.ctor-8.2)
|
||
|
||
f is a null member pointer value, or
|
||
|
||
- [(8.3)](#move.ctor-8.3)
|
||
|
||
remove_cvref_t<F> is a specialization of
|
||
the move_only_function class template,
|
||
and f has no target object[.](#move.ctor-8.sentence-1)
|
||
|
||
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#move.ctor-8.sentence-2)
|
||
|
||
[9](#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[.](#move.ctor-9.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#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](#move.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14277)
|
||
|
||
Let VT be decay_t<T>[.](#move.ctor-10.sentence-1)
|
||
|
||
[11](#move.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14280)
|
||
|
||
*Constraints*:
|
||
|
||
- [(11.1)](#move.ctor-11.1)
|
||
|
||
is_constructible_v<VT, Args...> is true, and
|
||
|
||
- [(11.2)](#move.ctor-11.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#move.ctor-11.sentence-1)
|
||
|
||
[12](#move.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14289)
|
||
|
||
*Mandates*: VT is the same type as T[.](#move.ctor-12.sentence-1)
|
||
|
||
[13](#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[.](#move.ctor-13.sentence-1)
|
||
|
||
[14](#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)...[.](#move.ctor-14.sentence-1)
|
||
|
||
[15](#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[.](#move.ctor-15.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#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](#move.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14318)
|
||
|
||
Let VT be decay_t<T>[.](#move.ctor-16.sentence-1)
|
||
|
||
[17](#move.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14321)
|
||
|
||
*Constraints*:
|
||
|
||
- [(17.1)](#move.ctor-17.1)
|
||
|
||
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
|
||
|
||
- [(17.2)](#move.ctor-17.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#move.ctor-17.sentence-1)
|
||
|
||
[18](#move.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14331)
|
||
|
||
*Mandates*: VT is the same type as T[.](#move.ctor-18.sentence-1)
|
||
|
||
[19](#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[.](#move.ctor-19.sentence-1)
|
||
|
||
[20](#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)...[.](#move.ctor-20.sentence-1)
|
||
|
||
[21](#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[.](#move.ctor-21.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#move.ctor-21.sentence-2)
|
||
|
||
[ð](#lib:operator=,move_only_function)
|
||
|
||
`move_only_function& operator=(move_only_function&& f);
|
||
`
|
||
|
||
[22](#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](#move.ctor-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14364)
|
||
|
||
*Returns*: *this[.](#move.ctor-23.sentence-1)
|
||
|
||
[ð](#lib:operator=,move_only_function_)
|
||
|
||
`move_only_function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[24](#move.ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14375)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#move.ctor-24.sentence-1)
|
||
|
||
[25](#move.ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14379)
|
||
|
||
*Returns*: *this[.](#move.ctor-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,move_only_function__)
|
||
|
||
`template<class F> move_only_function& operator=(F&& f);
|
||
`
|
||
|
||
[26](#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](#move.ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14394)
|
||
|
||
*Returns*: *this[.](#move.ctor-27.sentence-1)
|
||
|
||
[ð](#lib:move_only_function,destructor)
|
||
|
||
`~move_only_function();
|
||
`
|
||
|
||
[28](#move.ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14405)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#move.ctor-28.sentence-1)
|
||
|
||
#### [22.10.17.4.4](#move.inv) Invocation [[func.wrap.move.inv]](func.wrap.move.inv)
|
||
|
||
[ð](#lib:operator_bool,move_only_function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#move.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14418)
|
||
|
||
*Returns*: true if *this has a target object, otherwise false[.](#move.inv-1.sentence-1)
|
||
|
||
[ð](#lib:operator(),move_only_function)
|
||
|
||
`R operator()(ArgTypes... args) cv ref noexcept(noex);
|
||
`
|
||
|
||
[2](#move.inv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14429)
|
||
|
||
*Preconditions*: *this has a target object[.](#move.inv-2.sentence-1)
|
||
|
||
[3](#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[.](#move.inv-3.sentence-1)
|
||
|
||
#### [22.10.17.4.5](#move.util) Utility [[func.wrap.move.util]](func.wrap.move.util)
|
||
|
||
[ð](#lib:swap,move_only_function)
|
||
|
||
`void swap(move_only_function& other) noexcept;
|
||
`
|
||
|
||
[1](#move.util-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14451)
|
||
|
||
*Effects*: Exchanges the target objects of *this and other[.](#move.util-1.sentence-1)
|
||
|
||
[ð](#lib:swap,move_only_function_)
|
||
|
||
`friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
|
||
`
|
||
|
||
[2](#move.util-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14462)
|
||
|
||
*Effects*: Equivalent to f1.swap(f2)[.](#move.util-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,move_only_function)
|
||
|
||
`friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
|
||
`
|
||
|
||
[3](#move.util-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14473)
|
||
|
||
*Returns*: true if f has no target object, otherwise false[.](#move.util-3.sentence-1)
|
||
|
||
#### [22.10.17.5](#copy) Copyable wrapper [[func.wrap.copy]](func.wrap.copy)
|
||
|
||
#### [22.10.17.5.1](#copy.general) General [[func.wrap.copy.general]](func.wrap.copy.general)
|
||
|
||
[1](#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)](#copy.general-1.1)
|
||
|
||
cv is either const or empty,
|
||
|
||
- [(1.2)](#copy.general-1.2)
|
||
|
||
*ref* is either &, &&, or empty, and
|
||
|
||
- [(1.3)](#copy.general-1.3)
|
||
|
||
*noex* is either true or false[.](#copy.general-1.sentence-1)
|
||
|
||
[2](#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)](#copy.general-2.1)
|
||
|
||
If *ref* is empty, let *inv-quals* be cv&,
|
||
|
||
- [(2.2)](#copy.general-2.2)
|
||
|
||
otherwise, let *inv-quals* be cv *ref*[.](#copy.general-2.sentence-1)
|
||
|
||
#### [22.10.17.5.2](#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]](#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]](#copy.inv "22.10.17.5.4 Invocation"), invocationexplicit operator bool() const noexcept;
|
||
R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.copy.util]](#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](#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"))[.](#copy.class-1.sentence-1)
|
||
|
||
These wrappers can store, copy, move, and call arbitrary callable objects,
|
||
given a call signature[.](#copy.class-1.sentence-2)
|
||
|
||
[2](#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[.](#copy.class-2.sentence-1)
|
||
|
||
[*Note [1](#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[.](#copy.class-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [22.10.17.5.3](#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](#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](#copy.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14594)
|
||
|
||
*Postconditions*: *this has no target object[.](#copy.ctor-2.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,constructor_)
|
||
|
||
`copyable_function(const copyable_function& f);
|
||
`
|
||
|
||
[3](#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[.](#copy.ctor-3.sentence-1)
|
||
|
||
Otherwise, the target object of *this is a copy of the target object of f[.](#copy.ctor-3.sentence-2)
|
||
|
||
[4](#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[.](#copy.ctor-4.sentence-1)
|
||
|
||
May throw bad_alloc[.](#copy.ctor-4.sentence-2)
|
||
|
||
[ð](#lib:copyable_function,constructor__)
|
||
|
||
`copyable_function(copyable_function&& f) noexcept;
|
||
`
|
||
|
||
[5](#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[.](#copy.ctor-5.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,constructor___)
|
||
|
||
`template<class F> copyable_function(F&& f);
|
||
`
|
||
|
||
[6](#copy.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14636)
|
||
|
||
Let VT be decay_t<F>[.](#copy.ctor-6.sentence-1)
|
||
|
||
[7](#copy.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14639)
|
||
|
||
*Constraints*:
|
||
|
||
- [(7.1)](#copy.ctor-7.1)
|
||
|
||
remove_cvref_t<F> is not the same type as copyable_function, and
|
||
|
||
- [(7.2)](#copy.ctor-7.2)
|
||
|
||
remove_cvref_t<F> is not a specialization of in_place_type_t, and
|
||
|
||
- [(7.3)](#copy.ctor-7.3)
|
||
|
||
*is-callable-from*<VT> is true[.](#copy.ctor-7.sentence-1)
|
||
|
||
[8](#copy.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14650)
|
||
|
||
*Mandates*:
|
||
|
||
- [(8.1)](#copy.ctor-8.1)
|
||
|
||
is_constructible_v<VT, F> is true, and
|
||
|
||
- [(8.2)](#copy.ctor-8.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#copy.ctor-8.sentence-1)
|
||
|
||
[9](#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[.](#copy.ctor-9.sentence-1)
|
||
|
||
[10](#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)](#copy.ctor-10.1)
|
||
|
||
f is a null function pointer value, or
|
||
|
||
- [(10.2)](#copy.ctor-10.2)
|
||
|
||
f is a null member pointer value, or
|
||
|
||
- [(10.3)](#copy.ctor-10.3)
|
||
|
||
remove_cvref_t<F> is a specialization of
|
||
the copyable_function class template,
|
||
and f has no target object[.](#copy.ctor-10.sentence-1)
|
||
|
||
Otherwise, *this has a target object of type VT direct-non-list-initialized with std::forward<F>(f)[.](#copy.ctor-10.sentence-2)
|
||
|
||
[11](#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[.](#copy.ctor-11.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a function pointer or a specialization of reference_wrapper[.](#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](#copy.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14694)
|
||
|
||
Let VT be decay_t<T>[.](#copy.ctor-12.sentence-1)
|
||
|
||
[13](#copy.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14697)
|
||
|
||
*Constraints*:
|
||
|
||
- [(13.1)](#copy.ctor-13.1)
|
||
|
||
is_constructible_v<VT, Args...> is true, and
|
||
|
||
- [(13.2)](#copy.ctor-13.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#copy.ctor-13.sentence-1)
|
||
|
||
[14](#copy.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14706)
|
||
|
||
*Mandates*:
|
||
|
||
- [(14.1)](#copy.ctor-14.1)
|
||
|
||
VT is the same type as T, and
|
||
|
||
- [(14.2)](#copy.ctor-14.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#copy.ctor-14.sentence-1)
|
||
|
||
[15](#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[.](#copy.ctor-15.sentence-1)
|
||
|
||
[16](#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)...[.](#copy.ctor-16.sentence-1)
|
||
|
||
[17](#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[.](#copy.ctor-17.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a pointer or a specialization of reference_wrapper[.](#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](#copy.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14739)
|
||
|
||
Let VT be decay_t<T>[.](#copy.ctor-18.sentence-1)
|
||
|
||
[19](#copy.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14742)
|
||
|
||
*Constraints*:
|
||
|
||
- [(19.1)](#copy.ctor-19.1)
|
||
|
||
is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and
|
||
|
||
- [(19.2)](#copy.ctor-19.2)
|
||
|
||
*is-callable-from*<VT> is true[.](#copy.ctor-19.sentence-1)
|
||
|
||
[20](#copy.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14752)
|
||
|
||
*Mandates*:
|
||
|
||
- [(20.1)](#copy.ctor-20.1)
|
||
|
||
VT is the same type as T, and
|
||
|
||
- [(20.2)](#copy.ctor-20.2)
|
||
|
||
is_copy_constructible_v<VT> is true[.](#copy.ctor-20.sentence-1)
|
||
|
||
[21](#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[.](#copy.ctor-21.sentence-1)
|
||
|
||
[22](#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)...[.](#copy.ctor-22.sentence-1)
|
||
|
||
[23](#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[.](#copy.ctor-23.sentence-1)
|
||
|
||
May throw bad_alloc unless VT is
|
||
a pointer or a specialization of reference_wrapper[.](#copy.ctor-23.sentence-2)
|
||
|
||
[ð](#lib:operator=,copyable_function)
|
||
|
||
`copyable_function& operator=(const copyable_function& f);
|
||
`
|
||
|
||
[24](#copy.ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14785)
|
||
|
||
*Effects*: Equivalent to: copyable_function(f).swap(*this);
|
||
|
||
[25](#copy.ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14789)
|
||
|
||
*Returns*: *this[.](#copy.ctor-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function_)
|
||
|
||
`copyable_function& operator=(copyable_function&& f);
|
||
`
|
||
|
||
[26](#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](#copy.ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14804)
|
||
|
||
*Returns*: *this[.](#copy.ctor-27.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function__)
|
||
|
||
`copyable_function& operator=(nullptr_t) noexcept;
|
||
`
|
||
|
||
[28](#copy.ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14815)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#copy.ctor-28.sentence-1)
|
||
|
||
[29](#copy.ctor-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14819)
|
||
|
||
*Returns*: *this[.](#copy.ctor-29.sentence-1)
|
||
|
||
[ð](#lib:operator=,copyable_function___)
|
||
|
||
`template<class F> copyable_function& operator=(F&& f);
|
||
`
|
||
|
||
[30](#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](#copy.ctor-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14834)
|
||
|
||
*Returns*: *this[.](#copy.ctor-31.sentence-1)
|
||
|
||
[ð](#lib:copyable_function,destructor)
|
||
|
||
`~copyable_function();
|
||
`
|
||
|
||
[32](#copy.ctor-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14845)
|
||
|
||
*Effects*: Destroys the target object of *this, if any[.](#copy.ctor-32.sentence-1)
|
||
|
||
#### [22.10.17.5.4](#copy.inv) Invocation [[func.wrap.copy.inv]](func.wrap.copy.inv)
|
||
|
||
[ð](#lib:operator_bool,copyable_function)
|
||
|
||
`explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[1](#copy.inv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14858)
|
||
|
||
*Returns*: true if *this has a target object, otherwise false[.](#copy.inv-1.sentence-1)
|
||
|
||
[ð](#lib:operator(),copyable_function)
|
||
|
||
`R operator()(ArgTypes... args) cv ref noexcept(noex);
|
||
`
|
||
|
||
[2](#copy.inv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14869)
|
||
|
||
*Preconditions*: *this has a target object[.](#copy.inv-2.sentence-1)
|
||
|
||
[3](#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[.](#copy.inv-3.sentence-1)
|
||
|
||
#### [22.10.17.5.5](#copy.util) Utility [[func.wrap.copy.util]](func.wrap.copy.util)
|
||
|
||
[ð](#lib:swap,copyable_function)
|
||
|
||
`void swap(copyable_function& other) noexcept;
|
||
`
|
||
|
||
[1](#copy.util-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14891)
|
||
|
||
*Effects*: Exchanges the target objects of *this and other[.](#copy.util-1.sentence-1)
|
||
|
||
[ð](#lib:swap,copyable_function_)
|
||
|
||
`friend void swap(copyable_function& f1, copyable_function& f2) noexcept;
|
||
`
|
||
|
||
[2](#copy.util-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14902)
|
||
|
||
*Effects*: Equivalent to f1.swap(f2)[.](#copy.util-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,copyable_function)
|
||
|
||
`friend bool operator==(const copyable_function& f, nullptr_t) noexcept;
|
||
`
|
||
|
||
[3](#copy.util-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14913)
|
||
|
||
*Returns*: true if f has no target object, otherwise false[.](#copy.util-3.sentence-1)
|
||
|
||
#### [22.10.17.6](#ref) Non-owning wrapper [[func.wrap.ref]](func.wrap.ref)
|
||
|
||
#### [22.10.17.6.1](#ref.general) General [[func.wrap.ref.general]](func.wrap.ref.general)
|
||
|
||
[1](#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)](#ref.general-1.1)
|
||
|
||
cv is either const or empty, and
|
||
|
||
- [(1.2)](#ref.general-1.2)
|
||
|
||
*noex* is either true or false[.](#ref.general-1.sentence-1)
|
||
|
||
#### [22.10.17.6.2](#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]](#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]](#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]](#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](#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*[.](#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[.](#ref.class-1.sentence-2)
|
||
|
||
The type of *thunk-ptr* isR(*)(*BoundEntityType*, Args&&...) noexcept(*noex*)[.](#ref.class-1.sentence-3)
|
||
|
||
[2](#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]")[.](#ref.class-2.sentence-1)
|
||
|
||
[3](#ref.class-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14988)
|
||
|
||
Within [[func.wrap.ref]](#ref "22.10.17.6 Non-owning wrapper"),*call-args* is an argument pack with elements such thatdecltype((*call-args*))... denoteArgs&&... respectively[.](#ref.class-3.sentence-1)
|
||
|
||
#### [22.10.17.6.3](#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](#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](#ref.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15021)
|
||
|
||
*Constraints*:
|
||
|
||
- [(2.1)](#ref.ctor-2.1)
|
||
|
||
is_function_v<F> is true, and
|
||
|
||
- [(2.2)](#ref.ctor-2.2)
|
||
|
||
*is-invocable-using*<F> is true[.](#ref.ctor-2.sentence-1)
|
||
|
||
[3](#ref.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15028)
|
||
|
||
*Preconditions*: f is not a null pointer[.](#ref.ctor-3.sentence-1)
|
||
|
||
[4](#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*...)[.](#ref.ctor-4.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor_)
|
||
|
||
`template<class F> constexpr function_ref(F&& f) noexcept;
|
||
`
|
||
|
||
[5](#ref.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15049)
|
||
|
||
Let T be remove_reference_t<F>[.](#ref.ctor-5.sentence-1)
|
||
|
||
[6](#ref.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15052)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#ref.ctor-6.1)
|
||
|
||
remove_cvref_t<F> is not the same type as function_ref,
|
||
|
||
- [(6.2)](#ref.ctor-6.2)
|
||
|
||
is_member_pointer_v<T> is false, and
|
||
|
||
- [(6.3)](#ref.ctor-6.3)
|
||
|
||
*is-invocable-using*<cv T&> is true[.](#ref.ctor-6.sentence-1)
|
||
|
||
[7](#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*...)[.](#ref.ctor-7.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor__)
|
||
|
||
`template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
|
||
`
|
||
|
||
[8](#ref.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15077)
|
||
|
||
Let F be decltype(f)[.](#ref.ctor-8.sentence-1)
|
||
|
||
[9](#ref.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15080)
|
||
|
||
*Constraints*: *is-invocable-using*<F> is true[.](#ref.ctor-9.sentence-1)
|
||
|
||
[10](#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[.](#ref.ctor-10.sentence-1)
|
||
|
||
[11](#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*...)[.](#ref.ctor-11.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor___)
|
||
|
||
`template<auto f, class U>
|
||
constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
|
||
`
|
||
|
||
[12](#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)[.](#ref.ctor-12.sentence-1)
|
||
|
||
[13](#ref.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15112)
|
||
|
||
*Constraints*:
|
||
|
||
- [(13.1)](#ref.ctor-13.1)
|
||
|
||
is_rvalue_reference_v<U&&> is false, and
|
||
|
||
- [(13.2)](#ref.ctor-13.2)
|
||
|
||
*is-invocable-using*<F, cv T&> is true[.](#ref.ctor-13.sentence-1)
|
||
|
||
[14](#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[.](#ref.ctor-14.sentence-1)
|
||
|
||
[15](#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*...)[.](#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](#ref.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15142)
|
||
|
||
Let F be decltype(f)[.](#ref.ctor-16.sentence-1)
|
||
|
||
[17](#ref.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15145)
|
||
|
||
*Constraints*: *is-invocable-using*<F, cv T*> is true[.](#ref.ctor-17.sentence-1)
|
||
|
||
[18](#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[.](#ref.ctor-18.sentence-1)
|
||
|
||
[19](#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[.](#ref.ctor-19.sentence-1)
|
||
|
||
[20](#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*...)[.](#ref.ctor-20.sentence-1)
|
||
|
||
[ð](#lib:operator=,function_ref)
|
||
|
||
`template<class T> function_ref& operator=(T) = delete;
|
||
`
|
||
|
||
[21](#ref.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15176)
|
||
|
||
*Constraints*:
|
||
|
||
- [(21.1)](#ref.ctor-21.1)
|
||
|
||
T is not the same type as function_ref,
|
||
|
||
- [(21.2)](#ref.ctor-21.2)
|
||
|
||
is_pointer_v<T> is false, and
|
||
|
||
- [(21.3)](#ref.ctor-21.3)
|
||
|
||
T is not a specialization of nontype_t[.](#ref.ctor-21.sentence-1)
|
||
|
||
#### [22.10.17.6.4](#ref.inv) Invocation [[func.wrap.ref.inv]](func.wrap.ref.inv)
|
||
|
||
[ð](#lib:operator(),function_ref)
|
||
|
||
`R operator()(ArgTypes... args) const noexcept(noex);
|
||
`
|
||
|
||
[1](#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](#ref.deduct) Deduction guides [[func.wrap.ref.deduct]](func.wrap.ref.deduct)
|
||
|
||
[ð](#ref.deduct-itemdecl:1)
|
||
|
||
`template<class F>
|
||
function_ref(F*) -> function_ref<F>;
|
||
`
|
||
|
||
[1](#ref.deduct-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15207)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#ref.deduct-1.sentence-1)
|
||
|
||
[ð](#ref.deduct-itemdecl:2)
|
||
|
||
`template<auto f>
|
||
function_ref(nontype_t<f>) -> function_ref<see below>;
|
||
`
|
||
|
||
[2](#ref.deduct-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15218)
|
||
|
||
Let F be remove_pointer_t<decltype(f)>[.](#ref.deduct-2.sentence-1)
|
||
|
||
[3](#ref.deduct-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15221)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#ref.deduct-3.sentence-1)
|
||
|
||
[4](#ref.deduct-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15225)
|
||
|
||
*Remarks*: The deduced type is function_ref<F>[.](#ref.deduct-4.sentence-1)
|
||
|
||
[ð](#ref.deduct-itemdecl:3)
|
||
|
||
`template<auto f, class T>
|
||
function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
|
||
`
|
||
|
||
[5](#ref.deduct-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15236)
|
||
|
||
Let F be decltype(f)[.](#ref.deduct-5.sentence-1)
|
||
|
||
[6](#ref.deduct-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15239)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#ref.deduct-6.1)
|
||
|
||
F is of the formR(G::*)(A...) cv &opt noexcept(E) for a type G, or
|
||
|
||
- [(6.2)](#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)](#ref.deduct-6.3)
|
||
|
||
F is of the formR(*)(G, A...) noexcept(E) for a type G[.](#ref.deduct-6.sentence-1)
|
||
|
||
[7](#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)>[.](#ref.deduct-7.sentence-1)
|