362 lines
13 KiB
Markdown
362 lines
13 KiB
Markdown
[func.wrap.ref]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.10 Function objects [[function.objects]](function.objects#func.wrap.ref)
|
||
|
||
### 22.10.17 Polymorphic function wrappers [[func.wrap]](func.wrap#ref)
|
||
|
||
#### 22.10.17.6 Non-owning wrapper [func.wrap.ref]
|
||
|
||
#### [22.10.17.6.1](#general) General [[func.wrap.ref.general]](func.wrap.ref.general)
|
||
|
||
[1](#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)](#general-1.1)
|
||
|
||
cv is either const or empty, and
|
||
|
||
- [(1.2)](#general-1.2)
|
||
|
||
*noex* is either true or false[.](#general-1.sentence-1)
|
||
|
||
#### [22.10.17.6.2](#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]](#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]](#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]](#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](#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*[.](#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[.](#class-1.sentence-2)
|
||
|
||
The type of *thunk-ptr* isR(*)(*BoundEntityType*, Args&&...) noexcept(*noex*)[.](#class-1.sentence-3)
|
||
|
||
[2](#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]")[.](#class-2.sentence-1)
|
||
|
||
[3](#class-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14988)
|
||
|
||
Within [func.wrap.ref],*call-args* is an argument pack with elements such thatdecltype((*call-args*))... denoteArgs&&... respectively[.](#class-3.sentence-1)
|
||
|
||
#### [22.10.17.6.3](#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](#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](#ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15021)
|
||
|
||
*Constraints*:
|
||
|
||
- [(2.1)](#ctor-2.1)
|
||
|
||
is_function_v<F> is true, and
|
||
|
||
- [(2.2)](#ctor-2.2)
|
||
|
||
*is-invocable-using*<F> is true[.](#ctor-2.sentence-1)
|
||
|
||
[3](#ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15028)
|
||
|
||
*Preconditions*: f is not a null pointer[.](#ctor-3.sentence-1)
|
||
|
||
[4](#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*...)[.](#ctor-4.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor_)
|
||
|
||
`template<class F> constexpr function_ref(F&& f) noexcept;
|
||
`
|
||
|
||
[5](#ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15049)
|
||
|
||
Let T be remove_reference_t<F>[.](#ctor-5.sentence-1)
|
||
|
||
[6](#ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15052)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#ctor-6.1)
|
||
|
||
remove_cvref_t<F> is not the same type as function_ref,
|
||
|
||
- [(6.2)](#ctor-6.2)
|
||
|
||
is_member_pointer_v<T> is false, and
|
||
|
||
- [(6.3)](#ctor-6.3)
|
||
|
||
*is-invocable-using*<cv T&> is true[.](#ctor-6.sentence-1)
|
||
|
||
[7](#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*...)[.](#ctor-7.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor__)
|
||
|
||
`template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
|
||
`
|
||
|
||
[8](#ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15077)
|
||
|
||
Let F be decltype(f)[.](#ctor-8.sentence-1)
|
||
|
||
[9](#ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15080)
|
||
|
||
*Constraints*: *is-invocable-using*<F> is true[.](#ctor-9.sentence-1)
|
||
|
||
[10](#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[.](#ctor-10.sentence-1)
|
||
|
||
[11](#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*...)[.](#ctor-11.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor___)
|
||
|
||
`template<auto f, class U>
|
||
constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
|
||
`
|
||
|
||
[12](#ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15108)
|
||
|
||
Let T be remove_reference_t<U> andF be decltype(f)[.](#ctor-12.sentence-1)
|
||
|
||
[13](#ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15112)
|
||
|
||
*Constraints*:
|
||
|
||
- [(13.1)](#ctor-13.1)
|
||
|
||
is_rvalue_reference_v<U&&> is false, and
|
||
|
||
- [(13.2)](#ctor-13.2)
|
||
|
||
*is-invocable-using*<F, cv T&> is true[.](#ctor-13.sentence-1)
|
||
|
||
[14](#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[.](#ctor-14.sentence-1)
|
||
|
||
[15](#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*...)[.](#ctor-15.sentence-1)
|
||
|
||
[ð](#lib:function_ref,constructor____)
|
||
|
||
`template<auto f, class T>
|
||
constexpr function_ref(nontype_t<f>, cv T* obj) noexcept;
|
||
`
|
||
|
||
[16](#ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15142)
|
||
|
||
Let F be decltype(f)[.](#ctor-16.sentence-1)
|
||
|
||
[17](#ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15145)
|
||
|
||
*Constraints*: *is-invocable-using*<F, cv T*> is true[.](#ctor-17.sentence-1)
|
||
|
||
[18](#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[.](#ctor-18.sentence-1)
|
||
|
||
[19](#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[.](#ctor-19.sentence-1)
|
||
|
||
[20](#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*...)[.](#ctor-20.sentence-1)
|
||
|
||
[ð](#lib:operator=,function_ref)
|
||
|
||
`template<class T> function_ref& operator=(T) = delete;
|
||
`
|
||
|
||
[21](#ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15176)
|
||
|
||
*Constraints*:
|
||
|
||
- [(21.1)](#ctor-21.1)
|
||
|
||
T is not the same type as function_ref,
|
||
|
||
- [(21.2)](#ctor-21.2)
|
||
|
||
is_pointer_v<T> is false, and
|
||
|
||
- [(21.3)](#ctor-21.3)
|
||
|
||
T is not a specialization of nontype_t[.](#ctor-21.sentence-1)
|
||
|
||
#### [22.10.17.6.4](#inv) Invocation [[func.wrap.ref.inv]](func.wrap.ref.inv)
|
||
|
||
[ð](#lib:operator(),function_ref)
|
||
|
||
`R operator()(ArgTypes... args) const noexcept(noex);
|
||
`
|
||
|
||
[1](#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](#deduct) Deduction guides [[func.wrap.ref.deduct]](func.wrap.ref.deduct)
|
||
|
||
[ð](#deduct-itemdecl:1)
|
||
|
||
`template<class F>
|
||
function_ref(F*) -> function_ref<F>;
|
||
`
|
||
|
||
[1](#deduct-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15207)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#deduct-1.sentence-1)
|
||
|
||
[ð](#deduct-itemdecl:2)
|
||
|
||
`template<auto f>
|
||
function_ref(nontype_t<f>) -> function_ref<see below>;
|
||
`
|
||
|
||
[2](#deduct-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15218)
|
||
|
||
Let F be remove_pointer_t<decltype(f)>[.](#deduct-2.sentence-1)
|
||
|
||
[3](#deduct-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15221)
|
||
|
||
*Constraints*: is_function_v<F> is true[.](#deduct-3.sentence-1)
|
||
|
||
[4](#deduct-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15225)
|
||
|
||
*Remarks*: The deduced type is function_ref<F>[.](#deduct-4.sentence-1)
|
||
|
||
[ð](#deduct-itemdecl:3)
|
||
|
||
`template<auto f, class T>
|
||
function_ref(nontype_t<f>, T&&) -> function_ref<see below>;
|
||
`
|
||
|
||
[5](#deduct-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15236)
|
||
|
||
Let F be decltype(f)[.](#deduct-5.sentence-1)
|
||
|
||
[6](#deduct-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15239)
|
||
|
||
*Constraints*:
|
||
|
||
- [(6.1)](#deduct-6.1)
|
||
|
||
F is of the formR(G::*)(A...) cv &opt noexcept(E) for a type G, or
|
||
|
||
- [(6.2)](#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)](#deduct-6.3)
|
||
|
||
F is of the formR(*)(G, A...) noexcept(E) for a type G[.](#deduct-6.sentence-1)
|
||
|
||
[7](#deduct-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L15259)
|
||
|
||
*Remarks*: The deduced type is function_ref<R(A...) noexcept(E)>[.](#deduct-7.sentence-1)
|