[func.wrap.copy]

# 22 General utilities library [[utilities]](./#utilities)

## 22.10 Function objects [[function.objects]](function.objects#func.wrap.copy)

### 22.10.17 Polymorphic function wrappers [[func.wrap]](func.wrap#copy)

#### 22.10.17.5 Copyable wrapper [func.wrap.copy]

#### [22.10.17.5.1](#general) General [[func.wrap.copy.general]](func.wrap.copy.general)

[1](#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)](#general-1.1)

cv is either const or empty,

- [(1.2)](#general-1.2)

*ref* is either &, &&, or empty, and

- [(1.3)](#general-1.3)

*noex* is either true or false[.](#general-1.sentence-1)

[2](#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)](#general-2.1)

If *ref* is empty, let *inv-quals* be cv&,

- [(2.2)](#general-2.2)

otherwise, let *inv-quals* be cv *ref*[.](#general-2.sentence-1)

#### [22.10.17.5.2](#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]](#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]](#inv "22.10.17.5.4 Invocation"), invocationexplicit operator bool() const noexcept;
 R operator()(ArgTypes...) cv *ref* noexcept(*noex*); // [[func.wrap.copy.util]](#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](#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"))[.](#class-1.sentence-1)

These wrappers can store, copy, move, and call arbitrary callable objects,
given a call signature[.](#class-1.sentence-2)

[2](#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[.](#class-2.sentence-1)

[*Note [1](#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[.](#class-2.sentence-2)

â *end note*]

#### [22.10.17.5.3](#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](#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](#ctor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14594)

*Postconditions*: *this has no target object[.](#ctor-2.sentence-1)

[ð](#lib:copyable_function,constructor_)

`copyable_function(const copyable_function& f);
`

[3](#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[.](#ctor-3.sentence-1)

Otherwise, the target object of *this is a copy of the target object of f[.](#ctor-3.sentence-2)

[4](#ctor-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14611)

*Throws*: Any exception thrown by the initialization of the target object[.](#ctor-4.sentence-1)

May throw bad_alloc[.](#ctor-4.sentence-2)

[ð](#lib:copyable_function,constructor__)

`copyable_function(copyable_function&& f) noexcept;
`

[5](#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[.](#ctor-5.sentence-1)

[ð](#lib:copyable_function,constructor___)

`template<class F> copyable_function(F&& f);
`

[6](#ctor-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14636)

Let VT be decay_t<F>[.](#ctor-6.sentence-1)

[7](#ctor-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14639)

*Constraints*: 

- [(7.1)](#ctor-7.1)

remove_cvref_t<F> is not the same type as copyable_function, and

- [(7.2)](#ctor-7.2)

remove_cvref_t<F> is not a specialization of in_place_type_t, and

- [(7.3)](#ctor-7.3)

*is-callable-from*<VT> is true[.](#ctor-7.sentence-1)

[8](#ctor-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14650)

*Mandates*: 

- [(8.1)](#ctor-8.1)

is_constructible_v<VT, F> is true, and

- [(8.2)](#ctor-8.2)

is_copy_constructible_v<VT> is true[.](#ctor-8.sentence-1)

[9](#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[.](#ctor-9.sentence-1)

[10](#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)](#ctor-10.1)

f is a null function pointer value, or

- [(10.2)](#ctor-10.2)

f is a null member pointer value, or

- [(10.3)](#ctor-10.3)

remove_cvref_t<F> is a specialization of
the copyable_function class template,
and f has no target object[.](#ctor-10.sentence-1)

Otherwise, *this has a target object of type VT direct-non-list-initialized with std​::​forward<F>(f)[.](#ctor-10.sentence-2)

[11](#ctor-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14680)

*Throws*: Any exception thrown by the initialization of the target object[.](#ctor-11.sentence-1)

May throw bad_alloc unless VT is
a function pointer or a specialization of reference_wrapper[.](#ctor-11.sentence-2)

[ð](#lib:copyable_function,constructor____)

`template<class T, class... Args>
  explicit copyable_function(in_place_type_t<T>, Args&&... args);
`

[12](#ctor-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14694)

Let VT be decay_t<T>[.](#ctor-12.sentence-1)

[13](#ctor-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14697)

*Constraints*: 

- [(13.1)](#ctor-13.1)

is_constructible_v<VT, Args...> is true, and

- [(13.2)](#ctor-13.2)

*is-callable-from*<VT> is true[.](#ctor-13.sentence-1)

[14](#ctor-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14706)

*Mandates*: 

- [(14.1)](#ctor-14.1)

VT is the same type as T, and

- [(14.2)](#ctor-14.2)

is_copy_constructible_v<VT> is true[.](#ctor-14.sentence-1)

[15](#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[.](#ctor-15.sentence-1)

[16](#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)...[.](#ctor-16.sentence-1)

[17](#ctor-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14725)

*Throws*: Any exception thrown by the initialization of the target object[.](#ctor-17.sentence-1)

May throw bad_alloc unless VT is
a pointer or a specialization of reference_wrapper[.](#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](#ctor-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14739)

Let VT be decay_t<T>[.](#ctor-18.sentence-1)

[19](#ctor-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14742)

*Constraints*: 

- [(19.1)](#ctor-19.1)

is_constructible_v<VT, initializer_list<U>&, Args...> istrue, and

- [(19.2)](#ctor-19.2)

*is-callable-from*<VT> is true[.](#ctor-19.sentence-1)

[20](#ctor-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14752)

*Mandates*: 

- [(20.1)](#ctor-20.1)

VT is the same type as T, and

- [(20.2)](#ctor-20.2)

is_copy_constructible_v<VT> is true[.](#ctor-20.sentence-1)

[21](#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[.](#ctor-21.sentence-1)

[22](#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)...[.](#ctor-22.sentence-1)

[23](#ctor-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14772)

*Throws*: Any exception thrown by the initialization of the target object[.](#ctor-23.sentence-1)

May throw bad_alloc unless VT is
a pointer or a specialization of reference_wrapper[.](#ctor-23.sentence-2)

[ð](#lib:operator=,copyable_function)

`copyable_function& operator=(const copyable_function& f);
`

[24](#ctor-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14785)

*Effects*: Equivalent to: copyable_function(f).swap(*this);

[25](#ctor-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14789)

*Returns*: *this[.](#ctor-25.sentence-1)

[ð](#lib:operator=,copyable_function_)

`copyable_function& operator=(copyable_function&& f);
`

[26](#ctor-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14800)

*Effects*: Equivalent to: copyable_function(std​::​move(f)).swap(*this);

[27](#ctor-27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14804)

*Returns*: *this[.](#ctor-27.sentence-1)

[ð](#lib:operator=,copyable_function__)

`copyable_function& operator=(nullptr_t) noexcept;
`

[28](#ctor-28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14815)

*Effects*: Destroys the target object of *this, if any[.](#ctor-28.sentence-1)

[29](#ctor-29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14819)

*Returns*: *this[.](#ctor-29.sentence-1)

[ð](#lib:operator=,copyable_function___)

`template<class F> copyable_function& operator=(F&& f);
`

[30](#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](#ctor-31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14834)

*Returns*: *this[.](#ctor-31.sentence-1)

[ð](#lib:copyable_function,destructor)

`~copyable_function();
`

[32](#ctor-32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14845)

*Effects*: Destroys the target object of *this, if any[.](#ctor-32.sentence-1)

#### [22.10.17.5.4](#inv) Invocation [[func.wrap.copy.inv]](func.wrap.copy.inv)

[ð](#lib:operator_bool,copyable_function)

`explicit operator bool() const noexcept;
`

[1](#inv-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14858)

*Returns*: true if *this has a target object, otherwise false[.](#inv-1.sentence-1)

[ð](#lib:operator(),copyable_function)

`R operator()(ArgTypes... args) cv ref noexcept(noex);
`

[2](#inv-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14869)

*Preconditions*: *this has a target object[.](#inv-2.sentence-1)

[3](#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[.](#inv-3.sentence-1)

#### [22.10.17.5.5](#util) Utility [[func.wrap.copy.util]](func.wrap.copy.util)

[ð](#lib:swap,copyable_function)

`void swap(copyable_function& other) noexcept;
`

[1](#util-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14891)

*Effects*: Exchanges the target objects of *this and other[.](#util-1.sentence-1)

[ð](#lib:swap,copyable_function_)

`friend void swap(copyable_function& f1, copyable_function& f2) noexcept;
`

[2](#util-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14902)

*Effects*: Equivalent to f1.swap(f2)[.](#util-2.sentence-1)

[ð](#lib:operator==,copyable_function)

`friend bool operator==(const copyable_function& f, nullptr_t) noexcept;
`

[3](#util-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L14913)

*Returns*: true if f has no target object, otherwise false[.](#util-3.sentence-1)
