23 General utilities library [utilities]

23.1 General [utilities.general]

This Clause describes utilities that are generally useful in C++ programs; some of these utilities are used by other elements of the C++ standard library.
These utilities are summarized in Table 34.
Table 34 — General utilities library summary
Subclause
Header(s)
Utility components
<utility>
Compile-time integer sequences
<utility>
Pairs
<utility>
Tuples
<tuple>
Optional objects
<optional>
Variants
<variant>
Storage for any type
<any>
Fixed-size sequences of bits
<bitset>
Memory
<memory>
<cstdlib>
Smart pointers
<memory>
Memory resources
<memory_­resource>
Scoped allocators
<scoped_­allocator>
Function objects
<functional>
Type traits
<type_­traits>
Compile-time rational arithmetic
<ratio>
Time utilities
<chrono>
<ctime>
Type indexes
<typeindex>
Execution policies
<execution>

23.2 Utility components [utility]

This subclause contains some basic function and class templates that are used throughout the rest of the library.

23.2.1 Header <utility> synopsis [utility.syn]

#include <initializer_list>     // see [initializer_list.syn]

namespace std {
  // [operators], operators
  namespace rel_ops {
    template<class T> bool operator!=(const T&, const T&);
    template<class T> bool operator> (const T&, const T&);
    template<class T> bool operator<=(const T&, const T&);
    template<class T> bool operator>=(const T&, const T&);
  }

  // [utility.swap], swap
  template <class T>
    void swap(T& a, T& b) noexcept(see below);
  template <class T, size_t N>
    void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);

  // [utility.exchange], exchange
  template <class T, class U = T>
    T exchange(T& obj, U&& new_val);

  // [forward], forward/move
  template <class T>
    constexpr T&& forward(remove_reference_t<T>& t) noexcept;
  template <class T>
    constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
  template <class T>
    constexpr remove_reference_t<T>&& move(T&&) noexcept;
  template <class T>
    constexpr conditional_t<
        !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&>
      move_if_noexcept(T& x) noexcept;

  // [utility.as_const], as_­const
  template <class T>
    constexpr add_const_t<T>& as_const(T& t) noexcept;
  template <class T>
    void as_const(const T&&) = delete;

  // [declval], declval
  template <class T>
    add_rvalue_reference_t<T> declval() noexcept;  // as unevaluated operand

  // [intseq], Compile-time integer sequences
  template<class T, T...>
    struct integer_sequence;
  template<size_t... I>
    using index_sequence = integer_sequence<size_t, I...>;

  template<class T, T N>
    using make_integer_sequence = integer_sequence<T, see below>;
  template<size_t N>
    using make_index_sequence = make_integer_sequence<size_t, N>;

  template<class... T>
    using index_sequence_for = make_index_sequence<sizeof...(T)>;

  // [pairs], class template pair
  template <class T1, class T2>
    struct pair;

  // [pairs.spec], pair specialized algorithms
  template <class T1, class T2>
    constexpr bool operator==(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator< (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator!=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator> (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator>=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator<=(const pair<T1, T2>&, const pair<T1, T2>&);

  template <class T1, class T2>
    void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));

  template <class T1, class T2>
    constexpr see below make_pair(T1&&, T2&&);

  // [pair.astuple], tuple-like access to pair
  template <class T> class tuple_size;
  template <size_t I, class T> class tuple_element;

  template <class T1, class T2> struct tuple_size<pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<0, pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<1, pair<T1, T2>>;

  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&&) noexcept;
  template <class T1, class T2>
    constexpr T1& get(pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr const T1& get(const pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr T1&& get(pair<T1, T2>&& p) noexcept;
  template <class T1, class T2>
    constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr T2& get(pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr const T2& get(const pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr T2&& get(pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;

  // [pair.piecewise], pair piecewise construction
  struct piecewise_construct_t {
    explicit piecewise_construct_t() = default;
  };
  inline constexpr piecewise_construct_t piecewise_construct{};
  template <class... Types> class tuple;        // defined in <tuple> ([tuple.syn])

  // in-place construction
  struct in_place_t {
    explicit in_place_t() = default;
  };
  inline constexpr in_place_t in_place{};
  template <class T>
    struct in_place_type_t {
      explicit in_place_type_t() = default;
    };
  template <class T> inline constexpr in_place_type_t<T> in_place_type{};
  template <size_t I>
    struct in_place_index_t {
      explicit in_place_index_t() = default;
    };
  template <size_t I> inline constexpr in_place_index_t<I> in_place_index{};


  // floating-point format for primitive numerical conversion
  enum class chars_format {
    scientific = unspecified,
    fixed = unspecified,
    hex = unspecified,
    general = fixed | scientific
  };



  // [utility.to.chars], primitive numerical output conversion
  struct to_chars_result {
    char* ptr;
    error_code ec;
  };

  to_chars_result to_chars(char* first, char* last, see below value, int base = 10);

  to_chars_result to_chars(char* first, char* last, float value);
  to_chars_result to_chars(char* first, char* last, double value);
  to_chars_result to_chars(char* first, char* last, long double value);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt, int precision);



  // [utility.from.chars], primitive numerical input conversion
  struct from_chars_result {
    const char* ptr;
    error_code ec;
  };

  from_chars_result from_chars(const char* first, const char* last,
                               see below& value, int base = 10);

  from_chars_result from_chars(const char* first, const char* last, float& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, double& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, long double& value,
                               chars_format fmt = chars_format::general);
}
The header <utility> defines several types and function templates that are described in this Clause.
It also defines the template pair and various function templates that operate on pair objects.
The type chars_­format is a bitmask type ([bitmask.types]) with elements scientific, fixed, and hex.

23.2.2 Operators [operators]

To avoid redundant definitions of operator!= out of operator== and operators >, <=, and >= out of operator<, the library provides the following:
template <class T> bool operator!=(const T& x, const T& y);
Requires: Type T is EqualityComparable (Table 20).
Returns: !(x == y).
template <class T> bool operator>(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: y < x.
template <class T> bool operator<=(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: !(y < x).
template <class T> bool operator>=(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: !(x < y).
In this library, whenever a declaration is provided for an operator!=, operator>, operator>=, or operator<=, and requirements and semantics are not explicitly provided, the requirements and semantics are as specified in this Clause.

23.2.3 swap [utility.swap]

template <class T> void swap(T& a, T& b) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­move_­assignable_­v<T> is true.
The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
Requires: Type T shall be MoveConstructible (Table 23) and MoveAssignable (Table 25).
Effects: Exchanges values stored in two locations.
template <class T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<T> is true.
Requires: a[i] shall be swappable with ([swappable.requirements]) b[i] for all i in the range [0, N).
Effects: As if by swap_­ranges(a, a + N, b).

23.2.4 exchange [utility.exchange]

template <class T, class U = T> T exchange(T& obj, U&& new_val);
Effects: Equivalent to:
T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;

23.2.5 Forward/move helpers [forward]

The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions.
All functions specified in this subclause are signal-safe ([csignal.syn]).
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Returns: static_­cast<T&&>(t).
Remarks: If the second form is instantiated with an lvalue reference type, the program is ill-formed.
[Example
:
template <class T, class A1, class A2>
shared_ptr<T> factory(A1&& a1, A2&& a2) {
  return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)));
}

struct A {
  A(int&, const double&);
};

void g() {
  shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int&
  int i = 2;
  shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK
}
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an rvalue.
In the second call to factory, A1 is deduced as int&, so i is forwarded to A's constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.414 is forwarded to A's constructor as an rvalue.
end example
]
template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
Returns: static_­cast<remove_­reference_­t<T>&&>(t).
[Example
:
template <class T, class A1>
shared_ptr<T> factory(A1&& a1) {
  return shared_ptr<T>(new T(std::forward<A1>(a1)));
}

struct A {
  A();
  A(const A&);      // copies from lvalues
  A(A&&);           // moves from rvalues
};

void g() {
  A a;
  shared_ptr<A> sp1 = factory<A>(a);                // “a” binds to A(const A&)
  shared_ptr<A> sp1 = factory<A>(std::move(a));     // “a” binds to A(A&&)
}
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue.
This binds to the constructor A(const A&), which copies the value from a.
In the second call to factory, because of the call std​::​move(a), A1 is deduced as A, so a is forwarded as an rvalue.
This binds to the constructor A(A&&), which moves the value from a.
end example
]
template <class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;
Returns: std​::​move(x).

23.2.6 Function template as_­const [utility.as_const]

template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
Returns: t.

23.2.7 Function template declval [declval]

The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands (Clause [expr]).
template <class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
Remarks: If this function is odr-used ([basic.def.odr]), the program is ill-formed.
Remarks: The template parameter T of declval may be an incomplete type.
[Example
:
template <class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&);
declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.
For another example see class template common_­type ([meta.trans.other]).
end example
]

23.2.8 Primitive numeric output conversion [utility.to.chars]

All functions named to_­chars convert value into a character string by successively filling the range [first, last), where [first, last) is required to be a valid range.
If the member ec of the return value is such that the value, when converted to bool, is false, the conversion was successful and the member ptr is the one-past-the-end pointer of the characters written.
Otherwise, the member ec has the value errc​::​value_­too_­large, the member ptr has the value last, and the contents of the range [first, last) are unspecified.
The functions that take a floating-point value but not a precision parameter ensure that the string representation consists of the smallest number of characters such that there is at least one digit before the radix point (if present) and parsing the representation using the corresponding from_­chars function recovers value exactly.
[Note
:
This guarantee applies only if to_­chars and from_­chars are executed on the same implementation.
end note
]
The functions taking a chars_­format parameter determine the conversion specifier for printf as follows: The conversion specifier is f if fmt is chars_­format​::​fixed, e if fmt is chars_­format​::​scientific, a (without leading "0x" in the result) if fmt is chars_­format​::​hex, and g if fmt is chars_­format​::​general.
to_chars_result to_chars(char* first, char* last, see below value, int base = 10);
Requires: base has a value between 2 and 36 (inclusive).
Effects: The value of value is converted to a string of digits in the given base (with no redundant leading zeroes).
Digits in the range 10.
35 (inclusive) are represented as lowercase characters a.
z.
If value is less than zero, the representation starts with a minus sign.
Throws: Nothing.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value.
to_chars_result to_chars(char* first, char* last, float value); to_chars_result to_chars(char* first, char* last, double value); to_chars_result to_chars(char* first, char* last, long double value);
Effects: value is converted to a string in the style of printf in the "C" locale.
The conversion specifier is f or e, chosen according to the requirement for a shortest representation (see above); a tie is resolved in favor of f.
Throws: Nothing.
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: value is converted to a string in the style of printf in the "C" locale.
Throws: Nothing.
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: value is converted to a string in the style of printf in the "C" locale with the given precision.
Throws: Nothing.
See also: ISO C 7.21.6.1.

23.2.9 Primitive numeric input conversion [utility.from.chars]

All functions named from_­chars analyze the string [first, last) for a pattern, where [first, last) is required to be a valid range.
If no characters match the pattern, value is unmodified, the member ptr of the return value is first and the member ec is equal to errc​::​invalid_­argument.
Otherwise, the characters matching the pattern are interpreted as a representation of a value of the type of value.
The member ptr of the return value points to the first character not matching the pattern, or has the value last if all characters match.
If the parsed value is not in the range representable by the type of value, value is unmodified and the member ec of the return value is equal to errc​::​result_­out_­of_­range.
Otherwise, value is set to the parsed value and the member ec is set such that the conversion to bool yields false.
from_chars_result from_chars(const char* first, const char* last, see below& value, int base = 10);
Requires: base has a value between 2 and 36 (inclusive).
Effects: The pattern is the expected form of the subject sequence in the "C" locale for the given nonzero base, as described for strtol, except that no "0x" or "0X" prefix shall appear if the value of base is 16, and except that a minus sign is the only sign that may appear, and only if value has a signed type.
Throws: Nothing.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the referenced type of the parameter value.
from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt = chars_format::general);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: The pattern is the expected form of the subject sequence in the "C" locale, as described for strtod, except that
  • the only sign that may appear is a minus sign;
  • if fmt has chars_­format​::​scientific set but not chars_­format​::​fixed, the otherwise optional exponent part shall appear;
  • if fmt has chars_­format​::​fixed set but not chars_­format​::​scientific, the optional exponent part shall not appear; and
  • if fmt is chars_­format​::​hex, the prefix "0x" or "0X" is assumed.
    [Example
    :
    The string 0x123 is parsed to have the value 0 with remaining characters x123.
    end example
    ]
In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern.
Throws: Nothing.
See also: ISO C 7.22.1.3, ISO C 7.22.1.4.

23.3 Compile-time integer sequences [intseq]

23.3.1 In general [intseq.general]

The library provides a class template that can represent an integer sequence.
When used as an argument to a function template the parameter pack defining the sequence can be deduced and used in a pack expansion.
[Note
:
The index_­sequence alias template is provided for the common case of an integer sequence of type size_­t; see also [tuple.apply].
end note
]

23.3.2 Class template integer_­sequence [intseq.intseq]

namespace std {
  template<class T, T... I>
    struct integer_sequence {
      using value_type = T;
      static constexpr size_t size() noexcept { return sizeof...(I); }
    };
}
T shall be an integer type.

23.3.3 Alias template make_­integer_­sequence [intseq.make]

template<class T, T N> using make_integer_sequence = integer_sequence<T, see below>;
If N is negative the program is ill-formed.
The alias template make_­integer_­sequence denotes a specialization of integer_­sequence with N template non-type arguments.
The type make_­integer_­sequence<T, N> denotes the type integer_­sequence<T, 0, 1, ..., N-1>.
[Note
:
make_­integer_­sequence<int, 0> denotes the type integer_­sequence<int>
end note
]

23.4 Pairs [pairs]

23.4.1 In general [pairs.general]

The library provides a template for heterogeneous pairs of values.
The library also provides a matching function template to simplify their construction and several templates that provide access to pair objects as if they were tuple objects (see [tuple.helper] and [tuple.elem]).

23.4.2 Class template pair [pairs.pair]

namespace std {
  template <class T1, class T2>
    struct pair {
      using first_type  = T1;
      using second_type = T2;

      T1 first;
      T2 second;

      pair(const pair&) = default;
      pair(pair&&) = default;
      EXPLICIT constexpr pair();
      EXPLICIT constexpr pair(const T1& x, const T2& y);
      template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
      template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
      template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
      template <class... Args1, class... Args2>
        pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);

      pair& operator=(const pair& p);
      template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
      pair& operator=(pair&& p) noexcept(see below);
      template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);

      void swap(pair& p) noexcept(see below);
    };

  template<class T1, class T2>
    pair(T1, T2) -> pair<T1, T2>;
}
Constructors and member functions of pair shall not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception.
The defaulted move and copy constructor, respectively, of pair shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function.
The destructor of pair shall be a trivial destructor if (is_­trivially_­destructible_­v<T1> && is_­trivially_­destructible_­v<T2>) is true.
EXPLICIT constexpr pair();
Effects: Value-initializes first and second.
Remarks: This constructor shall not participate in overload resolution unless is_­default_­constructible_­v<first_­type> is true and is_­default_­constructible_­v<second_­type> is true.
[Note
:
This behavior can be implemented by a constructor template with default template arguments.
end note
]
The constructor is explicit if and only if either first_­type or second_­type is not implicitly default-constructible.
[Note
:
This behavior can be implemented with a trait that checks whether a const first_­type& or a const second_­type& can be initialized with {}.
end note
]
EXPLICIT constexpr pair(const T1& x, const T2& y);
Effects: Initializes first with x and second with y.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<first_­type> is true and is_­copy_­constructible_­v<second_­type> is true.
The constructor is explicit if and only if is_­convertible_­v<const first_­type&, first_­type> is false or is_­convertible_­v<const second_­type&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
Effects: Initializes first with std​::​forward<U1>(x) and second with std​::​forward<U2>(y).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, U1&&> is true and is_­constructible_­v<second_­type, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, first_­type> is false or is_­convertible_­v<U2&&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
Effects: Initializes members from the corresponding members of the argument.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, const U1&> is true and is_­constructible_­v<second_­type, const U2&> is true.
The constructor is explicit if and only if is_­convertible_­v<const U1&, first_­type> is false or is_­convertible_­v<const U2&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
Effects: Initializes first with std​::​forward<U1>(p.first) and second with std​::​forward<U2>(​p.second).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, U1&&> is true and is_­constructible_­v<second_­type, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, first_­type> is false or is_­convertible_­v<U2&&, second_­type> is false.
template<class... Args1, class... Args2> pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
Requires: is_­constructible_­v<first_­type, Args1&&...> is true and is_­constructible_­v<second_­type, Args2&&...> is true.
Effects: Initializes first with arguments of types Args1... obtained by forwarding the elements of first_­args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_­args.
(Here, forwarding an element x of type U within a tuple object means calling std​::​forward<U>(x).)
This form of construction, whereby constructor arguments for first and second are each provided in a separate tuple object, is called piecewise construction.
pair& operator=(const pair& p);
Effects: Assigns p.first to first and p.second to second.
Remarks: This operator shall be defined as deleted unless is_­copy_­assignable_­v<first_­type> is true and is_­copy_­assignable_­v<second_­type> is true.
Returns: *this.
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
Effects: Assigns p.first to first and p.second to second.
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<first_­type&, const U1&> is true and is_­assignable_­v<second_­type&, const U2&> is true.
Returns: *this.
pair& operator=(pair&& p) noexcept(see below);
Effects: Assigns to first with std​::​forward<first_­type>(p.first) and to second with
std​::​forward<second_­type>(p.second).
Remarks: This operator shall be defined as deleted unless is_­move_­assignable_­v<first_­type> is true and is_­move_­assignable_­v<second_­type> is true.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
Returns: *this.
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
Effects: Assigns to first with std​::​forward<U>(p.first) and to second with
std​::​forward<V>(p.second).
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<first_­type&, U1&&> is true and is_­assignable_­v<second_­type&, U2&&> is true.
Returns: *this.
void swap(pair& p) noexcept(see below);
Requires: first shall be swappable with ([swappable.requirements]) p.first and second shall be swappable with p.second.
Effects: Swaps first with p.first and second with p.second.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>

23.4.3 Specialized algorithms [pairs.spec]

template <class T1, class T2> constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: x.first == y.first && x.second == y.second.
template <class T1, class T2> constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: x.first < y.first || (!(y.first < x.first) && x.second < y.second).
template <class T1, class T2> constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(x == y).
template <class T1, class T2> constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: y < x.
template <class T1, class T2> constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(x < y).
template <class T1, class T2> constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(y < x).
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<T1> is true and is_­swappable_­v<T2> is true.
template <class T1, class T2> constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
Returns: pair<V1, V2>(std​::​forward<T1>(x), std​::​forward<T2>(y)), where V1 and V2 are determined as follows: Let Ui be decay_­t<Ti> for each Ti.
If Ui is a specialization of reference_­wrapper, then Vi is Ui​::​type&, otherwise Vi is Ui.
[Example
:
In place of:
  return pair<int, double>(5, 3.1415926);   // explicit types
a C++ program may contain:
  return make_pair(5, 3.1415926);           // types are deduced
end example
]

23.4.4 Tuple-like access to pair [pair.astuple]

template <class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
tuple_element<0, pair<T1, T2>>::type
Value: The type T1.
tuple_element<1, pair<T1, T2>>::type
Value: The type T2.
template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
Returns: If I == 0 returns a reference to p.first; if I == 1 returns a reference to p.second; otherwise the program is ill-formed.
template <class T1, class T2> constexpr T1& get(pair<T1, T2>& p) noexcept; template <class T1, class T2> constexpr const T1& get(const pair<T1, T2>& p) noexcept; template <class T1, class T2> constexpr T1&& get(pair<T1, T2>&& p) noexcept; template <class T1, class T2> constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
Requires: T1 and T2 are distinct types.
Otherwise, the program is ill-formed.
Returns: A reference to p.first.
template <class T2, class T1> constexpr T2& get(pair<T1, T2>& p) noexcept; template <class T2, class T1> constexpr const T2& get(const pair<T1, T2>& p) noexcept; template <class T2, class T1> constexpr T2&& get(pair<T1, T2>&& p) noexcept; template <class T2, class T1> constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
Requires: T1 and T2 are distinct types.
Otherwise, the program is ill-formed.
Returns: A reference to p.second.

23.4.5 Piecewise construction [pair.piecewise]

struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{};
The struct piecewise_­construct_­t is an empty structure type used as a unique type to disambiguate constructor and function overloading.
Specifically, pair has a constructor with piecewise_­construct_­t as the first argument, immediately followed by two tuple ([tuple]) arguments used for piecewise construction of the elements of the pair object.

23.5 Tuples [tuple]

23.5.1 In general [tuple.general]

This subclause describes the tuple library that provides a tuple type as the class template tuple that can be instantiated with any number of arguments.
Each template argument specifies the type of an element in the tuple.
Consequently, tuples are heterogeneous, fixed-size collections of values.
An instantiation of tuple with two arguments is similar to an instantiation of pair with the same two arguments.

23.5.2 Header <tuple> synopsis [tuple.syn]

namespace std {
  // [tuple.tuple], class template tuple
  template <class... Types>
    class tuple;

  // [tuple.creation], tuple creation functions
  inline constexpr unspecified ignore;

  template <class... TTypes>
    constexpr tuple<VTypes...> make_tuple(TTypes&&...);

  template <class... TTypes>
    constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;

  template<class... TTypes>
    constexpr tuple<TTypes&...> tie(TTypes&...) noexcept;

  template <class... Tuples>
    constexpr tuple<CTypes...> tuple_cat(Tuples&&...);

  // [tuple.apply], calling a function with a tuple of arguments
  template <class F, class Tuple>
    constexpr decltype(auto) apply(F&& f, Tuple&& t);

  template <class T, class Tuple>
    constexpr T make_from_tuple(Tuple&& t);

  // [tuple.helper], tuple helper classes
  template <class T> class tuple_size;                  // not defined
  template <class T> class tuple_size<const T>;
  template <class T> class tuple_size<volatile T>;
  template <class T> class tuple_size<const volatile T>;

  template <class... Types> class tuple_size<tuple<Types...>>;

  template <size_t I, class T> class tuple_element;     // not defined
  template <size_t I, class T> class tuple_element<I, const T>;
  template <size_t I, class T> class tuple_element<I, volatile T>;
  template <size_t I, class T> class tuple_element<I, const volatile T>;

  template <size_t I, class... Types>
    class tuple_element<I, tuple<Types...>>;

  template <size_t I, class T>
    using tuple_element_t = typename tuple_element<I, T>::type;

  // [tuple.elem], element access
  template <size_t I, class... Types>
    constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
  template <size_t I, class... Types>
    constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept;
  template <size_t I, class... Types>
    constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept;
  template <size_t I, class... Types>
    constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept;
  template <class T, class... Types>
    constexpr T& get(tuple<Types...>& t) noexcept;
  template <class T, class... Types>
    constexpr T&& get(tuple<Types...>&& t) noexcept;
  template <class T, class... Types>
    constexpr const T& get(const tuple<Types...>& t) noexcept;
  template <class T, class... Types>
    constexpr const T&& get(const tuple<Types...>&& t) noexcept;

  // [tuple.rel], relational operators
  template<class... TTypes, class... UTypes>
    constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);

  // [tuple.traits], allocator-related traits
  template <class... Types, class Alloc>
    struct uses_allocator<tuple<Types...>, Alloc>;

  // [tuple.special], specialized algorithms
  template <class... Types>
    void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);

  // [tuple.helper], tuple helper classes
  template <class T>
    inline constexpr size_t tuple_size_v = tuple_size<T>::value;
}

23.5.3 Class template tuple [tuple.tuple]

namespace std {
  template <class... Types>
    class tuple  {
    public:
      // [tuple.cnstr], tuple construction
      EXPLICIT constexpr tuple();
      EXPLICIT constexpr tuple(const Types&...);         // only if sizeof...(Types) >= 1
      template <class... UTypes>
        EXPLICIT constexpr tuple(UTypes&&...);           // only if sizeof...(Types) >= 1

      tuple(const tuple&) = default;
      tuple(tuple&&) = default;

      template <class... UTypes>
        EXPLICIT constexpr tuple(const tuple<UTypes...>&);
      template <class... UTypes>
        EXPLICIT constexpr tuple(tuple<UTypes...>&&);

      template <class U1, class U2>
        EXPLICIT constexpr tuple(const pair<U1, U2>&);   // only if sizeof...(Types) == 2
      template <class U1, class U2>
        EXPLICIT constexpr tuple(pair<U1, U2>&&);        // only if sizeof...(Types) == 2

      // allocator-extended constructors
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a);
      template <class Alloc>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a, const tuple&);
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a, tuple&&);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
      template <class Alloc, class U1, class U2>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
      template <class Alloc, class U1, class U2>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);

      // [tuple.assign], tuple assignment
      tuple& operator=(const tuple&);
      tuple& operator=(tuple&&) noexcept(see below);

      template <class... UTypes>
        tuple& operator=(const tuple<UTypes...>&);
      template <class... UTypes>
        tuple& operator=(tuple<UTypes...>&&);

      template <class U1, class U2>
        tuple& operator=(const pair<U1, U2>&);              // only if sizeof...(Types) == 2
      template <class U1, class U2>
        tuple& operator=(pair<U1, U2>&&);                   // only if sizeof...(Types) == 2

      // [tuple.swap], tuple swap
      void swap(tuple&) noexcept(see below);
    };

  template<class... UTypes>
    tuple(UTypes...) -> tuple<UTypes...>;
  template<class T1, class T2>
    tuple(pair<T1, T2>) -> tuple<T1, T2>;
  template<class Alloc, class... UTypes>
    tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
  template<class Alloc, class T1, class T2>
    tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
  template<class Alloc, class... UTypes>
    tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
}

23.5.3.1 Construction [tuple.cnstr]

For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.
The defaulted move and copy constructor, respectively, of tuple shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function.
The defaulted move and copy constructor of tuple<> shall be constexpr functions.
The destructor of tuple shall be a trivial destructor if (is_­trivially_­destructible_­v<Types> && ...) is true.
In the constructor descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, T be the type in Types, and U be the type in a template parameter pack named UTypes, where indexing is zero-based.
EXPLICIT constexpr tuple();
Effects: Value-initializes each element.
Remarks: This constructor shall not participate in overload resolution unless is_­default_­constructible_­v<T> is true for all i.
[Note
:
This behavior can be implemented by a constructor template with default template arguments.
end note
]
The constructor is explicit if and only if T is not implicitly default-constructible for at least one i.
[Note
:
This behavior can be implemented with a trait that checks whether a const T& can be initialized with {}.
end note
]
EXPLICIT constexpr tuple(const Types&...);
Effects: Initializes each element with the value of the corresponding parameter.
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) >= 1 and is_­copy_­constructible_­v<T> is true for all i.
The constructor is explicit if and only if is_­convertible_­v<const T&, T> is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(UTypes&&... u);
Effects: Initializes the elements in the tuple with the corresponding value in std​::​forward<UTypes>(u).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and sizeof...(Types) >= 1 and is_­constructible_­v<T, U&&> is true for all i.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false for at least one i.
tuple(const tuple& u) = default;
Requires: is_­copy_­constructible_­v<T> is true for all i.
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
Requires: is_­move_­constructible_­v<T> is true for all i.
Effects: For all i, initializes the element of *this with std​::​forward<T>(get<i>(u)).
template <class... UTypes> EXPLICIT constexpr tuple(const tuple<UTypes...>& u);
Effects: Initializes each element of *this with the corresponding element of u.
Remarks: This constructor shall not participate in overload resolution unless
  • sizeof...(Types) == sizeof...(UTypes) and
  • is_­constructible_­v<T, const U&> is true for all i, and
  • sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
    !is_­convertible_­v<const tuple<U>&, T> && !is_­constructible_­v<T, const tuple<U>&>
    && !is_­same_­v<T, U>
    is true.
The constructor is explicit if and only if is_­convertible_­v<const U&, T> is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
Effects: For all i, initializes the element of *this with std​::​forward<U>(get<i>(u)).
Remarks: This constructor shall not participate in overload resolution unless
  • sizeof...(Types) == sizeof...(UTypes), and
  • is_­constructible_­v<T, U&&> is true for all i, and
  • sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
    !is_­convertible_­v<tuple<U>, T> && !is_­constructible_­v<T, tuple<U>> &&
    !is_­same_­v<T, U>
    is true.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false for at least one i.
template <class U1, class U2> EXPLICIT constexpr tuple(const pair<U1, U2>& u);
Effects: Initializes the first element with u.first and the second element with u.second.
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_­constructible_­v<T, const U1&> is true and is_­constructible_­v<T, const U2&> is true.
The constructor is explicit if and only if is_­convertible_­v<const U1&, T> is false or is_­convertible_­v<const U2&, T> is false.
template <class U1, class U2> EXPLICIT constexpr tuple(pair<U1, U2>&& u);
Effects: Initializes the first element with std​::​forward<U1>(u.first) and the second element with std​::​forward<U2>(u.second).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_­constructible_­v<T, U1&&> is true and is_­constructible_­v<T, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, T> is false or is_­convertible_­v<U2&&, T> is false.
template <class Alloc> tuple(allocator_arg_t, const Alloc& a); template <class Alloc> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, const tuple&); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, tuple&&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
Requires: Alloc shall meet the requirements for an Allocator ([allocator.requirements]).
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction ([allocator.uses.construction]).

23.5.3.2 Assignment [tuple.assign]

For each tuple assignment operator, an exception is thrown only if the assignment of one of the types in Types throws an exception.
In the function descriptions that follow, let i be in the range [0, sizeof...​(Types)) in order, T be the type in Types, and U be the type in a template parameter pack named UTypes, where indexing is zero-based.
tuple& operator=(const tuple& u);
Effects: Assigns each element of u to the corresponding element of *this.
Remarks: This operator shall be defined as deleted unless is_­copy_­assignable_­v<T> is true for all i.
Returns: *this.
tuple& operator=(tuple&& u) noexcept(see below);
Effects: For all i, assigns std​::​forward<T>(get<i>(u)) to get<i>(*this).
Remarks: This operator shall be defined as deleted unless is_­move_­assignable_­v<T> is true for all i.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_move_assignable_v<>
where is the type in Types.
Returns: *this.
template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
Effects: Assigns each element of u to the corresponding element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and is_­assignable_­v<T&, const U&> is true for all i.
Returns: *this.
template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);
Effects: For all i, assigns std​::​forward<U>(get<i>(u)) to get<i>(*this).
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<T&, U&&> == true for all i and sizeof...(Types) == sizeof...(UTypes).
Returns: *this.
template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_­assignable_­v<T&, const U1&> is true for the first type T in Types and is_­assignable_­v<T&, const U2&> is true for the second type T in Types.
Returns: *this.
template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
Effects: Assigns std​::​forward<U1>(u.first) to the first element of *this and
std​::​forward<U2>(u.second) to the second element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_­assignable_­v<T&, U1&&> is true for the first type T in Types and is_­assignable_­v<T&, U2&&> is true for the second type T in Types.
Returns: *this.

23.5.3.3 swap [tuple.swap]

void swap(tuple& rhs) noexcept(see below);
Requires: Each element in *this shall be swappable with ([swappable.requirements]) the corresponding element in rhs.
Effects: Calls swap for each element in *this and its corresponding element in rhs.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_swappable_v<>
where is the type in Types.
Throws: Nothing unless one of the element-wise swap calls throws an exception.

23.5.3.4 Tuple creation functions [tuple.creation]

In the function descriptions that follow, the members of a parameter pack XTypes are denoted by X for i in [0, sizeof...(XTypes)) in order, where indexing is zero-based.
template<class... TTypes> constexpr tuple<VTypes...> make_tuple(TTypes&&... t);
The pack VTypes is defined as follows.
Let U be decay_­t<T> for each T in TTypes.
If U is a specialization of reference_­wrapper, then V in VTypes is U​::​type&, otherwise V is U.
Returns: tuple<VTypes...>(std​::​forward<TTypes>(t)...).
[Example
:
int i; float j;
make_tuple(1, ref(i), cref(j))
creates a tuple of type tuple<int, int&, const float&>.
end example
]
template<class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
Effects: Constructs a tuple of references to the arguments in t suitable for forwarding as arguments to a function.
Because the result may contain references to temporary variables, a program shall ensure that the return value of this function does not outlive any of its arguments (e.g., the program should typically not store the result in a named variable).
Returns: tuple<TTypes&&...>(std​::​forward<TTypes>(t)...).
template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
Returns: tuple<TTypes&...>(t...).
When an argument in t is ignore, assigning any value to the corresponding tuple element has no effect.
[Example
:
tie functions allow one to create tuples that unpack tuples into variables.
ignore can be used for elements that are not needed:
int i; std::string s;
tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
// i == 42, s == "C++"
end example
]
template <class... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
In the following paragraphs, let T be the type in Tuples, U be remove_­reference_­t<T>, and tp be the parameter in the function parameter pack tpls, where all indexing is zero-based.
Requires: For all i, U shall be the type tuple<Args...>, where is the (possibly empty) cv-qualifier-seq and Args is the parameter pack representing the element types in U.
Let A be the type in Args.
For all A the following requirements shall be satisfied:
  • If T is deduced as an lvalue reference type, then is_­constructible_­v<A, &> == true, otherwise
  • is_­constructible_­v<A, &&> == true.
Remarks: The types in CTypes shall be equal to the ordered sequence of the extended types Args..., Args..., , Args..., where n is equal to sizeof...(Tuples).
Let e... be the ordered sequence of tuple elements of the resulting tuple object corresponding to the type sequence Args.
Returns: A tuple object constructed by initializing the type element e in e... with
get<>(std::forward<T>(tp))
for each valid and each group e in order.
[Note
:
An implementation may support additional types in the parameter pack Tuples that support the tuple-like protocol, such as pair and array.
end note
]

23.5.3.5 Calling a function with a tuple of arguments [tuple.apply]

template <class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t);
Effects: Given the exposition-only function:
template <class F, class Tuple, size_t... I>
constexpr decltype(auto)
    apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {                // exposition only
  return INVOKE(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
Equivalent to:
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
                  make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t);
Effects: Given the exposition-only function:
template <class T, class Tuple, size_t... I>
constexpr T make_from_tuple_impl(Tuple&& t, index_sequence<I...>) {     // exposition only
  return T(get<I>(std::forward<Tuple>(t))...);
}
Equivalent to:
return make_from_tuple_impl<T>(forward<Tuple>(t),
                               make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
[Note
:
The type of T must be supplied as an explicit template parameter, as it cannot be deduced from the argument list.
end note
]

23.5.3.6 Tuple helper classes [tuple.helper]

template <class T> struct tuple_size;
Remarks: All specializations of tuple_­size shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, N> for some N.
template <class... Types> class tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class... Types> class tuple_element<I, tuple<Types...>> { public: using type = TI; };
Requires: I < sizeof...(Types).
The program is ill-formed if I is out of bounds.
Type: TI is the type of the Ith element of Types, where indexing is zero-based.
template <class T> class tuple_size<const T>; template <class T> class tuple_size<volatile T>; template <class T> class tuple_size<const volatile T>;
Let TS denote tuple_­size<T> of the cv-unqualified type T.
If the expression TS​::​value is well-formed when treated as an unevaluated operand, then each of the three templates shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of
integral_constant<size_t, TS::value>
Otherwise, they shall have no member value.
Access checking is performed as if in a context unrelated to TS and T.
Only the validity of the immediate context of the expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
In addition to being available via inclusion of the <tuple> header, the three templates are available when either of the headers <array> or <utility> are included.
template <size_t I, class T> class tuple_element<I, const T>; template <size_t I, class T> class tuple_element<I, volatile T>; template <size_t I, class T> class tuple_element<I, const volatile T>;
Let TE denote tuple_­element_­t<I, T> of the cv-unqualified type T.
Then each of the three templates shall meet the TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the following type:
  • for the first specialization, add_­const_­t<TE>,
  • for the second specialization, add_­volatile_­t<TE>, and
  • for the third specialization, add_­cv_­t<TE>.
In addition to being available via inclusion of the <tuple> header, the three templates are available when either of the headers <array> or <utility> are included.

23.5.3.7 Element access [tuple.elem]

template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>& t) noexcept; template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&& t) noexcept; // Note A template <size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>& t) noexcept; // Note B template <size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
Requires: I < sizeof...(Types).
The program is ill-formed if I is out of bounds.
Returns: A reference to the Ith element of t, where indexing is zero-based.
[Note
:
[Note A] If a T in Types is some reference type X&, the return type is X&, not X&&.
However, if the element type is a non-reference type T, the return type is T&&.
end note
]
[Note
:
[Note B] Constness is shallow.
If a T in Types is some reference type X&, the return type is X&, not const X&.
However, if the element type is a non-reference type T, the return type is const T&.
This is consistent with how constness is defined to work for member variables of reference type.
end note
]
template <class T, class... Types> constexpr T& get(tuple<Types...>& t) noexcept; template <class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; template <class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; template <class T, class... Types> constexpr const T&& get(const tuple<Types...>&& t) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Returns: A reference to the element of t corresponding to the type T in Types....
[Example
:
  const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);
  const int& i1 = get<int>(t);        // OK. Not ambiguous. i1 == 1
  const int& i2 = get<const int>(t);  // OK. Not ambiguous. i2 == 2
  const double& d = get<double>(t);   // ERROR. ill-formed
end example
]
[Note
:
The reason get is a non-member function is that if this functionality had been provided as a member function, code where the type depended on a template parameter would have required using the template keyword.
end note
]

23.5.3.8 Relational operators [tuple.rel]

template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), get<i>(t) == get<i>(u) is a valid expression returning a type that is convertible to bool.
sizeof...(TTypes) == sizeof...(UTypes).
Returns: true if get<i>(t) == get<i>(u) for all i, otherwise false.
For any two zero-length tuples e and f, e == f returns true.
Effects: The elementary comparisons are performed in order from the zeroth index upwards.
No comparisons or element accesses are performed after the first equality comparison that evaluates to false.
template<class... TTypes, class... UTypes> constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), both get<i>(t) < get<i>(u) and get<i>(u) < get<i>(t) are valid expressions returning types that are convertible to bool.
sizeof...(TTypes) == sizeof...(UTypes).
Returns: The result of a lexicographical comparison between t and u.
The result is defined as: (bool)(get<0>(t) < get<0>(u)) || (!(bool)(get<0>(u) < get<0>(t)) && t < u), where r for some tuple r is a tuple containing all but the first element of r.
For any two zero-length tuples e and f, e < f returns false.
template<class... TTypes, class... UTypes> constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(t == u).
template<class... TTypes, class... UTypes> constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: u < t.
template<class... TTypes, class... UTypes> constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(u < t).
template<class... TTypes, class... UTypes> constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(t < u).
[Note
:
The above definitions for comparison functions do not require t (or u) to be constructed.
It may not even be possible, as t and u are not required to be copy constructible.
Also, all comparison functions are short circuited; they do not perform element accesses beyond what is required to determine the result of the comparison.
end note
]

23.5.3.9 Tuple traits [tuple.traits]

template <class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).
[Note
:
Specialization of this trait informs other library components that tuple can be constructed with an allocator, even though it does not have a nested allocator_­type.
end note
]

23.5.3.10 Tuple specialized algorithms [tuple.special]

template <class... Types> void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<T> is true for all i, where .
The expression inside noexcept is equivalent to:
noexcept(x.swap(y))
Effects: As if by x.swap(y).

23.6 Optional objects [optional]

23.6.1 In general [optional.general]

This subclause describes class template optional that represents optional objects.
An optional object is an object that contains the storage for another object and manages the lifetime of this contained object, if any.
The contained object may be initialized after the optional object has been initialized, and may be destroyed before the optional object has been destroyed.
The initialization state of the contained object is tracked by the optional object.

23.6.2 Header <optional> synopsis [optional.syn]

namespace std {
  // [optional.optional], class template optional
  template <class T>
    class optional;

  // [optional.nullopt], no-value state indicator
  struct nullopt_t{see below};
  inline constexpr nullopt_t nullopt(unspecified);

  // [optional.bad.access], class bad_­optional_­access
  class bad_optional_access;

  // [optional.relops], relational operators
  template <class T, class U>
  constexpr bool operator==(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator!=(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator<(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator>(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator<=(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator>=(const optional<T>&, const optional<U>&);

  // [optional.nullops], comparison with nullopt
  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;

  // [optional.comp_with_t], comparison with T
  template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator==(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator<(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator>(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&);

  // [optional.specalg], specialized algorithms
  template <class T>
    void swap(optional<T>&, optional<T>&) noexcept(see below);

  template <class T>
    constexpr optional<see below> make_optional(T&&);
  template <class T, class... Args>
    constexpr optional<T> make_optional(Args&&... args);
  template <class T, class U, class... Args>
    constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);

  // [optional.hash], hash support
  template <class T> struct hash;
  template <class T> struct hash<optional<T>>;
}
A program that necessitates the instantiation of template optional for a reference type, or for possibly cv-qualified types in_­place_­t or nullopt_­t is ill-formed.

23.6.3 Class template optional [optional.optional]

template <class T>
  class optional {
  public:
    using value_type = T;

    // [optional.ctor], constructors
    constexpr optional() noexcept;
    constexpr optional(nullopt_t) noexcept;
    constexpr optional(const optional&);
    constexpr optional(optional&&) noexcept(see below);
    template <class... Args>
      constexpr explicit optional(in_place_t, Args&&...);
    template <class U, class... Args>
      constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
    template <class U = T>
      EXPLICIT constexpr optional(U&&);
    template <class U>
      EXPLICIT optional(const optional<U>&);
    template <class U>
      EXPLICIT optional(optional<U>&&);

    // [optional.dtor], destructor
    ~optional();

    // [optional.assign], assignment
    optional& operator=(nullopt_t) noexcept;
    optional& operator=(const optional&);
    optional& operator=(optional&&) noexcept(see below);
    template <class U = T> optional& operator=(U&&);
    template <class U> optional& operator=(const optional<U>&);
    template <class U> optional& operator=(optional<U>&&);
    template <class... Args> T& emplace(Args&&...);
    template <class U, class... Args> T& emplace(initializer_list<U>, Args&&...);

    // [optional.swap], swap
    void swap(optional&) noexcept(see below);

    // [optional.observe], observers
    constexpr const T* operator->() const;
    constexpr T* operator->();
    constexpr const T& operator*() const&;
    constexpr T& operator*() &;
    constexpr T&& operator*() &&;
    constexpr const T&& operator*() const&&;
    constexpr explicit operator bool() const noexcept;
    constexpr bool has_value() const noexcept;
    constexpr const T& value() const&;
    constexpr T& value() &;
    constexpr T&& value() &&;
    constexpr const T&& value() const&&;
    template <class U> constexpr T value_or(U&&) const&;
    template <class U> constexpr T value_or(U&&) &&;

    // [optional.mod], modifiers
    void reset() noexcept;

  private:
    T *val; // exposition only
  };

template<class T> optional(T) -> optional<T>;
Any instance of optional<T> at any given time either contains a value or does not contain a value.
When an instance of optional<T> contains a value, it means that an object of type T, referred to as the optional object's contained value, is allocated within the storage of the optional object.
Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value.
The contained value shall be allocated in a region of the optional<T> storage suitably aligned for the type T.
When an object of type optional<T> is contextually converted to bool, the conversion returns true if the object contains a value; otherwise the conversion returns false.
Member val is provided for exposition only.
When an optional<T> object contains a value, val points to the contained value.
T shall be an object type and shall satisfy the requirements of Destructible (Table 27).

23.6.3.1 Constructors [optional.ctor]

constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept;
Postconditions: *this does not contain a value.
Remarks: No contained value is initialized.
For every object type T these constructors shall be constexpr constructors ([dcl.constexpr]).
constexpr optional(const optional& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall be defined as deleted unless is_­copy_­constructible_­v<T> is true.
If is_­trivially_­copy_­constructible_­v<T> is true, this constructor shall be a constexpr constructor.
constexpr optional(optional&& rhs) noexcept(see below);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs).
bool(rhs) is unchanged.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­move_­constructible_­v<T>.
This constructor shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true.
If is_­trivially_­move_­constructible_­v<T> is true, this constructor shall be a constexpr constructor.
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor.
This constructor shall not participate in overload resolution unless is_­constructible_­v<T, Args...> is true.
template <class U, class... Args> constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args&&...> is true.
If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor.
[Note
:
The following constructors are conditionally specified as explicit.
This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution.
end note
]
template <class U = T> EXPLICIT constexpr optional(U&& v);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​forward<U>(v).
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
This constructor shall not participate in overload resolution unless is_­constructible_­v<T, U&&> is true, is_­same_­v<decay_­t<U>, in_­place_­t> is false, and is_­same_­v<optional<T>, decay_­t<U>> is false.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false.
template <class U> EXPLICIT optional(const optional<U>& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless
  • is_­constructible_­v<T, const U&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false, and
  • is_­convertible_­v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_­convertible_­v<const U&, T> is false.
template <class U> EXPLICIT optional(optional<U>&& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs).
bool(rhs) is unchanged.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless
  • is_­constructible_­v<T, U&&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false, and
  • is_­convertible_­v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false.

23.6.3.2 Destructor [optional.dtor]

~optional();
Effects: If is_­trivially_­destructible_­v<T> != true and *this contains a value, calls
val->T::~T()
Remarks: If is_­trivially_­destructible_­v<T> == true then this destructor shall be a trivial destructor.

23.6.3.3 Assignment [optional.assign]

optional<T>& operator=(nullopt_t) noexcept;
Effects: If *this contains a value, calls val->T​::​~T() to destroy the contained value; otherwise no effect.
Returns: *this.
Postconditions: *this does not contain a value.
optional<T>& operator=(const optional& rhs);
Effects: See Table [tab:optional.assign.copy].
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns *rhs to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with *rhs
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's copy constructor, no effect.
If an exception is thrown during the call to T's copy assignment, the state of its contained value is as defined by the exception safety guarantee of T's copy assignment.
This operator shall be defined as deleted unless is_­copy_­constructible_­v<T> is true and is_­copy_­assignable_­v<T> is true.
optional<T>& operator=(optional&& rhs) noexcept(see below);
Effects: See Table [tab:optional.assign.move].
The result of the expression bool(rhs) remains unchanged.
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns std​::​move(*rhs) to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with std​::​move(*rhs)
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's move constructor, the state of *rhs.val is determined by the exception safety guarantee of T's move constructor.
If an exception is thrown during the call to T's move assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's move assignment.
This operator shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­move_­assignable_­v<T> is true.
template <class U = T> optional<T>& operator=(U&& v);
Effects: If *this contains a value, assigns std​::​forward<U>(v) to the contained value; otherwise initializes the contained value as if direct-non-list-initializing object of type T with std​::​forward<U>(v).
Returns: *this.
Postconditions: *this contains a value.
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of v is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and v is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless is_­same_­v<optional<T>, decay_­t<U>> is false, conjunction_­v<is_­scalar<T>, is_­same<T, decay_­t<U>>> is false, is_­constructible_­v<T, U> is true, and is_­assignable_­v<T&, U> is true.
template <class U> optional<T>& operator=(const optional<U>& rhs);
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns *rhs to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with *rhs
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless
  • is_­constructible_­v<T, const U&> is true,
  • is_­assignable_­v<T&, const U&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false,
  • is_­convertible_­v<const optional<U>&&, T> is false,
  • is_­assignable_­v<T&, optional<U>&> is false,
  • is_­assignable_­v<T&, optional<U>&&> is false,
  • is_­assignable_­v<T&, const optional<U>&> is false, and
  • is_­assignable_­v<T&, const optional<U>&&> is false.
template <class U> optional<T>& operator=(optional<U>&& rhs);
The result of the expression bool(rhs) remains unchanged.
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns std​::​move(*rhs) to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with std​::​move(*rhs)
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless
  • is_­constructible_­v<T, U> is true,
  • is_­assignable_­v<T&, U> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false,
  • is_­convertible_­v<const optional<U>&&, T> is false,
  • is_­assignable_­v<T&, optional<U>&> is false,
  • is_­assignable_­v<T&, optional<U>&&> is false,
  • is_­assignable_­v<T&, const optional<U>&> is false, and
  • is_­assignable_­v<T&, const optional<U>&&> is false.
template <class... Args> T& emplace(Args&&... args);
Requires: is_­constructible_­v<T, Args&&...> is true.
Effects: Calls *this = nullopt.
Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
template <class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Effects: Calls *this = nullopt.
Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
This function shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args&&...> is true.

23.6.3.4 Swap [optional.swap]

void swap(optional& rhs) noexcept(see below);
Requires: Lvalues of type T shall be swappable and is_­move_­constructible_­v<T> is true.
Effects: See Table [tab:optional.swap].
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & calls swap(*(*this), *rhs) & initializes the contained value of *this as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs), followed by rhs.val->T​::​~T(); postcondition is that *this contains a value and rhs does not contain a value
rhs does not contain a value& & initializes the contained value of rhs as if direct-non-list-initializing an object of type T with the expression std​::​move(*(*this)), followed by val->T​::​~T(); postcondition is that *this does not contain a value and rhs contains a value & no effect
Throws: Any exceptions thrown by the operations in the relevant part of Table [tab:optional.swap].
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) remain unchanged.
If an exception is thrown during the call to function swap, the state of *val and *rhs.val is determined by the exception safety guarantee of swap for lvalues of T.
If an exception is thrown during the call to T's move constructor, the state of *val and *rhs.val is determined by the exception safety guarantee of T's move constructor.

23.6.3.5 Observers [optional.observe]

constexpr const T* operator->() const; constexpr T* operator->();
Requires: *this contains a value.
Returns: val.
Throws: Nothing.
Remarks: These functions shall be constexpr functions.
constexpr const T& operator*() const&; constexpr T& operator*() &;
Requires: *this contains a value.
Returns: *val.
Throws: Nothing.
Remarks: These functions shall be constexpr functions.
constexpr T&& operator*() &&; constexpr const T&& operator*() const&&;
Requires: *this contains a value.
Effects: Equivalent to: return std​::​move(*val);
constexpr explicit operator bool() const noexcept;
Returns: true if and only if *this contains a value.
Remarks: This function shall be a constexpr function.
constexpr bool has_value() const noexcept;
Returns: true if and only if *this contains a value.
Remarks: This function shall be a constexpr function.
constexpr const T& value() const&; constexpr T& value() &;
Effects: Equivalent to:
return bool(*this) ? *val : throw bad_optional_access();
constexpr T&& value() &&; constexpr const T&& value() const&&;
Effects: Equivalent to:
return bool(*this) ? std::move(*val) : throw bad_optional_access();
template <class U> constexpr T value_or(U&& v) const&;
Effects: Equivalent to:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
Remarks: If is_­copy_­constructible_­v<T> && is_­convertible_­v<U&&, T> is false, the program is ill-formed.
template <class U> constexpr T value_or(U&& v) &&;
Effects: Equivalent to:
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
Remarks: If is_­move_­constructible_­v<T> && is_­convertible_­v<U&&, T> is false, the program is ill-formed.

23.6.3.6 Modifiers [optional.mod]

void reset() noexcept;
Effects: If *this contains a value, calls val->T​::​~T() to destroy the contained value; otherwise no effect.
Postconditions: *this does not contain a value.

23.6.4 No-value state indicator [optional.nullopt]

struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified);
The struct nullopt_­t is an empty structure type used as a unique type to indicate the state of not containing a value for optional objects.
In particular, optional<T> has a constructor with nullopt_­t as a single argument; this indicates that an optional object not containing a value shall be constructed.
Type nullopt_­t shall not have a default constructor or an initializer-list constructor, and shall not be an aggregate.

23.6.5 Class bad_­optional_­access [optional.bad.access]

class bad_optional_access : public exception {
public:
  bad_optional_access();
};
The class bad_­optional_­access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value.
bad_optional_access();
Effects: Constructs an object of class bad_­optional_­access.
Postconditions: what() returns an implementation-defined ntbs.

23.6.6 Relational operators [optional.relops]

template <class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
Requires: The expression *x == *y shall be well-formed and its result shall be convertible to bool.
[Note
:
T need not be EqualityComparable.
end note
]
Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true; otherwise *x == *y.
Remarks: Specializations of this function template for which *x == *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x != *y shall be well-formed and its result shall be convertible to bool.
Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false; otherwise *x != *y.
Remarks: Specializations of this function template for which *x != *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
Requires: *x < *y shall be well-formed and its result shall be convertible to bool.
Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
Remarks: Specializations of this function template for which *x < *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
Requires: The expression *x > *y shall be well-formed and its result shall be convertible to bool.
Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
Remarks: Specializations of this function template for which *x > *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x <= *y shall be well-formed and its result shall be convertible to bool.
Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
Remarks: Specializations of this function template for which *x <= *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x >= *y shall be well-formed and its result shall be convertible to bool.
Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
Remarks: Specializations of this function template for which *x >= *y is a core constant expression shall be constexpr functions.

23.6.7 Comparison with nullopt [optional.nullops]

template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept; template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
Returns: !x.
template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept; template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
Returns: false.
template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
Returns: !x.
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
Returns: true.
template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
Returns: false.
template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
Returns: true.
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
Returns: !x.

23.6.8 Comparison with T [optional.comp_with_t]

template <class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
Requires: The expression *x == v shall be well-formed and its result shall be convertible to bool.
[Note
:
T need not be EqualityComparable.
end note
]
Effects: Equivalent to: return bool(x) ? *x == v : false;
template <class T, class U> constexpr bool operator==(const U& v, const optional<T>& x);
Requires: The expression v == *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v == *x : false;
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
Requires: The expression *x != v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x != v : true;
template <class T, class U> constexpr bool operator!=(const U& v, const optional<T>& x);
Requires: The expression v != *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v != *x : true;
template <class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
Requires: The expression *x < v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x < v : true;
template <class T, class U> constexpr bool operator<(const U& v, const optional<T>& x);
Requires: The expression v < *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v < *x : false;
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
Requires: The expression *x <= v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x <= v : true;
template <class T, class U> constexpr bool operator<=(const U& v, const optional<T>& x);
Requires: The expression v <= *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v <= *x : false;
template <class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
Requires: The expression *x > v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x > v : false;
template <class T, class U> constexpr bool operator>(const U& v, const optional<T>& x);
Requires: The expression v > *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v > *x : true;
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
Requires: The expression *x >= v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x >= v : false;
template <class T, class U> constexpr bool operator>=(const U& v, const optional<T>& x);
Requires: The expression v >= *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v >= *x : true;

23.6.9 Specialized algorithms [optional.specalg]

template <class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
Effects: Calls x.swap(y).
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­swappable_­v<T> is true.
template <class T> constexpr optional<decay_t<T>> make_optional(T&& v);
Returns: optional<decay_­t<T>>(std​::​forward<T>(v)).
template <class T, class...Args> constexpr optional<T> make_optional(Args&&... args);
Effects: Equivalent to: return optional<T>(in_­place, std​::​forward<Args>(args)...);
template <class T, class U, class... Args> constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
Effects: Equivalent to: return optional<T>(in_­place, il, std​::​forward<Args>(args)...);

23.6.10 Hash support [optional.hash]

template <class T> struct hash<optional<T>>;
The specialization hash<optional<T>> is enabled ([unord.hash]) if and only if hash<remove_­const_­t<T>> is enabled.
When enabled, for an object o of type optional<T>, if bool(o) == true, then hash<optional<T>>()(o) shall evaluate to the same value as hash<remove_­const_­t<T>>()(*o); otherwise it evaluates to an unspecified value.
The member functions are not guaranteed to be noexcept.

23.7 Variants [variant]

23.7.1 In general [variant.general]

A variant object holds and manages the lifetime of a value.
If the variant holds a value, that value's type has to be one of the template argument types given to variant.
These template arguments are called alternatives.

23.7.2 Header <variant> synopsis [variant.syn]

namespace std {
  // [variant.variant], class template variant
  template <class... Types>
    class variant;

  // [variant.helper], variant helper classes
  template <class T> struct variant_size;                   // not defined
  template <class T> struct variant_size<const T>;
  template <class T> struct variant_size<volatile T>;
  template <class T> struct variant_size<const volatile T>;
  template <class T>
    inline constexpr size_t variant_size_v = variant_size<T>::value;

  template <class... Types>
    struct variant_size<variant<Types...>>;

  template <size_t I, class T> struct variant_alternative;  // not defined
  template <size_t I, class T> struct variant_alternative<I, const T>;
  template <size_t I, class T> struct variant_alternative<I, volatile T>;
  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
  template <size_t I, class T>
    using variant_alternative_t = typename variant_alternative<I, T>::type;

  template <size_t I, class... Types>
    struct variant_alternative<I, variant<Types...>>;

  inline constexpr size_t variant_npos = -1;

  // [variant.get], value access
  template <class T, class... Types>
    constexpr bool holds_alternative(const variant<Types...>&) noexcept;

  template <size_t I, class... Types>
    constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&);
  template <size_t I, class... Types>
    constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&);
  template <size_t I, class... Types>
    constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&);
  template <size_t I, class... Types>
    constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&);

  template <class T, class... Types>
    constexpr T& get(variant<Types...>&);
  template <class T, class... Types>
    constexpr T&& get(variant<Types...>&&);
  template <class T, class... Types>
    constexpr const T& get(const variant<Types...>&);
  template <class T, class... Types>
    constexpr const T&& get(const variant<Types...>&&);

  template <size_t I, class... Types>
    constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
      get_if(variant<Types...>*) noexcept;
  template <size_t I, class... Types>
    constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
      get_if(const variant<Types...>*) noexcept;

  template <class T, class... Types>
    constexpr add_pointer_t<T>
      get_if(variant<Types...>*) noexcept;
  template <class T, class... Types>
    constexpr add_pointer_t<const T>
      get_if(const variant<Types...>*) noexcept;

  // [variant.relops], relational operators
  template <class... Types>
    constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);

  // [variant.visit], visitation
  template <class Visitor, class... Variants>
    constexpr see below visit(Visitor&&, Variants&&...);

  // [variant.monostate], class monostate
  struct monostate;

  // [variant.monostate.relops], monostate relational operators
  constexpr bool operator<(monostate, monostate) noexcept;
  constexpr bool operator>(monostate, monostate) noexcept;
  constexpr bool operator<=(monostate, monostate) noexcept;
  constexpr bool operator>=(monostate, monostate) noexcept;
  constexpr bool operator==(monostate, monostate) noexcept;
  constexpr bool operator!=(monostate, monostate) noexcept;

  // [variant.specalg], specialized algorithms
  template <class... Types>
    void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);

  // [variant.bad.access], class bad_­variant_­access
  class bad_variant_access;

  // [variant.hash], hash support
  template <class T> struct hash;
  template <class... Types> struct hash<variant<Types...>>;
  template <> struct hash<monostate>;

  // [variant.traits], allocator-related traits
  template <class T, class Alloc> struct uses_allocator;
  template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc>;
}

23.7.3 Class template variant [variant.variant]

namespace std {
  template <class... Types>
    class variant {
    public:
      // [variant.ctor], constructors
      constexpr variant() noexcept(see below);
      variant(const variant&);
      variant(variant&&) noexcept(see below);

      template <class T>
        constexpr variant(T&&) noexcept(see below);

      template <class T, class... Args>
        constexpr explicit variant(in_place_type_t<T>, Args&&...);
      template <class T, class U, class... Args>
        constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...);

      template <size_t I, class... Args>
        constexpr explicit variant(in_place_index_t<I>, Args&&...);
      template <size_t I, class U, class... Args>
        constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);

      // allocator-extended constructors
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&);
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&, const variant&);
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&, variant&&);
      template <class Alloc, class T>
        variant(allocator_arg_t, const Alloc&, T&&);
      template <class Alloc, class T, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...);
      template <class Alloc, class T, class U, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_type_t<T>,
                initializer_list<U>, Args&&...);
      template <class Alloc, size_t I, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...);
      template <class Alloc, size_t I, class U, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_index_t<I>,
                initializer_list<U>, Args&&...);

      // [variant.dtor], destructor
      ~variant();

      // [variant.assign], assignment
      variant& operator=(const variant&);
      variant& operator=(variant&&) noexcept(see below);

      template <class T> variant& operator=(T&&) noexcept(see below);

      // [variant.mod], modifiers
      template <class T, class... Args>
        T& emplace(Args&&...);
      template <class T, class U, class... Args>
        T& emplace(initializer_list<U>, Args&&...);
      template <size_t I, class... Args>
        variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
      template <size_t I, class U, class... Args>
        variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);

      // [variant.status], value status
      constexpr bool valueless_by_exception() const noexcept;
      constexpr size_t index() const noexcept;

      // [variant.swap], swap
      void swap(variant&) noexcept(see below);
    };
}
Any instance of variant at any given time either holds a value of one of its alternative types, or it holds no value.
When an instance of variant holds a value of alternative type T, it means that a value of type T, referred to as the variant object's contained value, is allocated within the storage of the variant object.
Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value.
The contained value shall be allocated in a region of the variant storage suitably aligned for all types in Types....
It is implementation-defined whether over-aligned types are supported.
All types in Types... shall be (possibly cv-qualified) object types that are not arrays.
A program that instantiates the definition of variant with no template arguments is ill-formed.

23.7.3.1 Constructors [variant.ctor]

In the descriptions that follow, let i be in the range [0, sizeof...(Types)), and T be the type in Types....
constexpr variant() noexcept(see below);
Effects: Constructs a variant holding a value-initialized value of type T.
Postconditions: valueless_­by_­exception() is false and index() is 0.
Throws: Any exception thrown by the value-initialization of T.
Remarks: This function shall be constexpr if and only if the value-initialization of the alternative type T would satisfy the requirements for a constexpr function.
The expression inside noexcept is equivalent to is_­nothrow_­default_­constructible_­v<T>.
This function shall not participate in overload resolution unless is_­default_­constructible_­v<T> is true.
[Note
:
See also class monostate.
end note
]
variant(const variant& w);
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with get<j>(w), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by direct-initializing any T for all i.
Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<T> is true for all i.
variant(variant&& w) noexcept(see below);
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with get<j>(std​::​move(w)), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by move-constructing any T for all i.
Remarks: The expression inside noexcept is equivalent to the logical AND of is_­nothrow_­move_­constructible_­v<T> for all i.
This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true for all i.
template <class T> constexpr variant(T&& t) noexcept(see below);
Let T be a type that is determined as follows: build an imaginary function FUN(T) for each alternative type T.
The overload FUN(T) selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative T which is the type of the contained value after construction.
Effects: Initializes *this to hold the alternative type T and direct-initializes the contained value as if direct-non-list-initializing it with std​::​forward<T>(t).
Postconditions: holds_­alternative<T>(*this) is true.
Throws: Any exception thrown by the initialization of the selected alternative T.
Remarks: This function shall not participate in overload resolution unless is_­same_­v<decay_­t<T>, variant> is false, unless decay_­t<T> is neither a specialization of in_­place_­type_­t nor a specialization of in_­place_­index_­t, unless is_­constructible_­v<T, T> is true, and unless the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[Note
:
variant<string, string> v("abc");
is ill-formed, as both alternative types have an equally viable constructor for the argument.
end note
]
The expression inside noexcept is equivalent to is_­nothrow_­constructible_­v<T, T>.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: holds_­alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_­constructible_­v<T, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class U, class... Args> constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: holds_­alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_­constructible_­v<T, initializer_­list<U>&, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: index() is I.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: This function shall not participate in overload resolution unless
  • I is less than sizeof...(Types) and
  • is_­constructible_­v<T, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <size_t I, class U, class... Args> constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: index() is I.
Remarks: This function shall not participate in overload resolution unless
  • I is less than sizeof...(Types) and
  • is_­constructible_­v<T, initializer_­list<U>&, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
// allocator-extended constructors template <class Alloc> variant(allocator_arg_t, const Alloc& a); template <class Alloc> variant(allocator_arg_t, const Alloc& a, const variant& v); template <class Alloc> variant(allocator_arg_t, const Alloc& a, variant&& v); template <class Alloc, class T> variant(allocator_arg_t, const Alloc& a, T&& t); template <class Alloc, class T, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args); template <class Alloc, class T, class U, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, initializer_list<U> il, Args&&... args); template <class Alloc, size_t I, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args); template <class Alloc, size_t I, class U, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Requires: Alloc shall meet the requirements for an Allocator ([allocator.requirements]).
Effects: Equivalent to the preceding constructors except that the contained value is constructed with uses-allocator construction ([allocator.uses.construction]).

23.7.3.2 Destructor [variant.dtor]

~variant();
Effects: If valueless_­by_­exception() is false, destroys the currently contained value.
Remarks: If is_­trivially_­destructible_­v<T> == true for all T then this destructor shall be a trivial destructor.

23.7.3.3 Assignment [variant.assign]

variant& operator=(const variant& rhs);
Let j be rhs.index().
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
    Otherwise,
  • if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
    Otherwise,
  • if index() == j, assigns the value contained in rhs to the value contained in *this.
    Otherwise,
  • if either is_­nothrow_­copy_­constructible_­v<T> or !is_­nothrow_­move_­constructible_­v<T> is true, equivalent to emplace<j>(get<j>(rhs)).
    Otherwise,
  • equivalent to operator=(variant(rhs)).
Returns: *this.
Postconditions: index() == rhs.index().
Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<T> && is_­copy_­assignable_­v<T> is true for all i.
variant& operator=(variant&& rhs) noexcept(see below);
Let j be rhs.index().
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
    Otherwise,
  • if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
    Otherwise,
  • if index() == j, assigns get<j>(std​::​move(rhs)) to the value contained in *this.
    Otherwise,
  • equivalent to emplace<j>(get<j>(std​::​move(rhs))).
Returns: *this.
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> && is_­move_­assignable_­v<T> is true for all i.
The expression inside noexcept is equivalent to: is_­nothrow_­move_­constructible_­v<T> && is_­nothrow_­move_­assignable_­v<T> for all i.
  • If an exception is thrown during the call to T's move construction (with j being rhs.index()), the variant will hold no value.
  • If an exception is thrown during the call to T's move assignment, the state of the contained value is as defined by the exception safety guarantee of T's move assignment; index() will be j.
template <class T> variant& operator=(T&& t) noexcept(see below);
Let T be a type that is determined as follows: build an imaginary function FUN(T) for each alternative type T.
The overload FUN(T) selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative T which is the type of the contained value after assignment.
Effects:
  • If *this holds a T, assigns std​::​forward<T>(t) to the value contained in *this.
    Otherwise,
  • if is_­nothrow_­constructible_­v<T, T> || !is_­nothrow_­move_­constructible_­v<T> is true, equivalent to emplace<j>(std​::​forward<T>(t)).
    Otherwise,
  • equivalent to operator=(variant(std​::​forward<T>(t))).
Postconditions: holds_­alternative<T>(*this) is true, with T selected by the imaginary function overload resolution described above.
Returns: *this.
Remarks: This function shall not participate in overload resolution unless is_­same_­v<decay_­t<T>, variant> is false, unless is_­assignable_­v<T&, T> && is_­constructible_­v<T, T> is true, and unless the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[Note
:
variant<string, string> v;
v = "abc";
is ill-formed, as both alternative types have an equally viable constructor for the argument.
end note
]
The expression inside noexcept is equivalent to:
is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>
  • If an exception is thrown during the assignment of std​::​forward<T>(t) to the value contained in *this, the state of the contained value and t are as defined by the exception safety guarantee of the assignment expression; valueless_­by_­exception() will be false.
  • If an exception is thrown during the initialization of the contained value, the variant object might not hold a value.

23.7.3.4 Modifiers [variant.mod]

template <class T, class... Args> T& emplace(Args&&... args);
Let I be the zero-based index of T in Types....
Effects: Equivalent to: return emplace<I>(std​::​forward<Args>(args)...);
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, Args...> is true, and T occurs exactly once in Types....
template <class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Let I be the zero-based index of T in Types....
Effects: Equivalent to: return emplace<I>(il, std​::​forward<Args>(args)...);
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args...> is true, and T occurs exactly once in Types....
template <size_t I, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
Requires: I < sizeof...(Types).
Effects: Destroys the currently contained value if valueless_­by_­exception() is false.
Then initializes the contained value as if direct-non-list-initializing a value of type T with the arguments std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, Args...> is true.
If an exception is thrown during the initialization of the contained value, the variant might not hold a value.
template <size_t I, class U, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
Requires: I < sizeof...(Types).
Effects: Destroys the currently contained value if valueless_­by_­exception() is false.
Then initializes the contained value as if direct-non-list-initializing a value of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args...> is true.
If an exception is thrown during the initialization of the contained value, the variant might not hold a value.

23.7.3.5 Value status [variant.status]

constexpr bool valueless_by_exception() const noexcept;
Effects: Returns false if and only if the variant holds a value.
[Note
:
A variant might not hold a value if an exception is thrown during a type-changing assignment or emplacement.
The latter means that even a variant<float, int> can become valueless_­by_­exception(), for instance by
struct S { operator int() { throw 42; }};
variant<float, int> v{12.f};
v.emplace<1>(S());
end note
]
constexpr size_t index() const noexcept;
Effects: If valueless_­by_­exception() is true, returns variant_­npos.
Otherwise, returns the zero-based index of the alternative of the contained value.

23.7.3.6 Swap [variant.swap]

void swap(variant& rhs) noexcept(see below);
Requires: Lvalues of type T shall be swappable ([swappable.requirements]) and is_­move_­constructible_­v<T> shall be true for all i.
Effects:
  • if valueless_­by_­exception() && rhs.valueless_­by_­exception() no effect.
    Otherwise,
  • if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs)) where i is index().
    Otherwise,
  • exchanges values of rhs and *this.
Throws: If index() == rhs.index(), any exception thrown by swap(get<i>(*this), get<i>(rhs)) with i being index().
Otherwise, any exception thrown by the move constructor of T or T with i being index() and j being rhs.index().
Remarks: If an exception is thrown during the call to function swap(get<i>(*this), get<i>(rhs)), the states of the contained values of *this and of rhs are determined by the exception safety guarantee of swap for lvalues of T with i being index().
If an exception is thrown during the exchange of the values of *this and rhs, the states of the values of *this and of rhs are determined by the exception safety guarantee of variant's move constructor.
The expression inside noexcept is equivalent to the logical AND of is_­nothrow_­move_­constructible_­v<T> && is_­nothrow_­swappable_­v<T> for all i.

23.7.4 variant helper classes [variant.helper]

template <class T> struct variant_size;
Remarks: All specializations of variant_­size shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, N> for some N.
template <class T> class variant_size<const T>; template <class T> class variant_size<volatile T>; template <class T> class variant_size<const volatile T>;
Let VS denote variant_­size<T> of the cv-unqualified type T.
Then each of the three templates shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, VS​::​value>.
template <class... Types> struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class T> class variant_alternative<I, const T>; template <size_t I, class T> class variant_alternative<I, volatile T>; template <size_t I, class T> class variant_alternative<I, const volatile T>;
Let VA denote variant_­alternative<I, T> of the cv-unqualified type T.
Then each of the three templates shall meet the TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the following type:
  • for the first specialization, add_­const_­t<VA​::​type>,
  • for the second specialization, add_­volatile_­t<VA​::​type>, and
  • for the third specialization, add_­cv_­t<VA​::​type>.
variant_alternative<I, variant<Types...>>::type
Requires: I < sizeof...(Types).
Value: The type T.

23.7.5 Value access [variant.get]

template <class T, class... Types> constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Returns: true if index() is equal to the zero-based index of T in Types....
template <size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v); template <size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>& v); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&& v);
Requires: I < sizeof...(Types).
Otherwise the program is ill-formed.
Effects: If v.index() is I, returns a reference to the object stored in the variant.
Otherwise, throws an exception of type bad_­variant_­access.
template <class T, class... Types> constexpr T& get(variant<Types...>& v); template <class T, class... Types> constexpr T&& get(variant<Types...>&& v); template <class T, class... Types> constexpr const T& get(const variant<Types...>& v); template <class T, class... Types> constexpr const T&& get(const variant<Types...>&& v);
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Effects: If v holds a value of type T, returns a reference to that value.
Otherwise, throws an exception of type bad_­variant_­access.
template <size_t I, class... Types> constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>* v) noexcept; template <size_t I, class... Types> constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>* v) noexcept;
Requires: I < sizeof...(Types).
Otherwise the program is ill-formed.
Returns: A pointer to the value stored in the variant, if v != nullptr and v->index() == I.
Otherwise, returns nullptr.
template <class T, class... Types> constexpr add_pointer_t<T> get_if(variant<Types...>* v) noexcept; template <class T, class... Types> constexpr add_pointer_t<const T> get_if(const variant<Types...>* v) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Effects: Equivalent to: return get_­if<i>(v); with i being the zero-based index of T in Types....

23.7.6 Relational operators [variant.relops]

template <class... Types> constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) == get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.index() != w.index(), false; otherwise if v.valueless_­by_­exception(), true; otherwise get<i>(v) == get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) != get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.index() != w.index(), true; otherwise if v.valueless_­by_­exception(), false; otherwise get<i>(v) != get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) < get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If w.valueless_­by_­exception(), false; otherwise if v.valueless_­by_­exception(), true; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise get<i>(v) < get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) > get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.valueless_­by_­exception(), false; otherwise if w.valueless_­by_­exception(), true; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise get<i>(v) > get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) <= get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.valueless_­by_­exception(), true; otherwise if w.valueless_­by_­exception(), false; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise get<i>(v) <= get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) >= get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If w.valueless_­by_­exception(), true; otherwise if v.valueless_­by_­exception(), false; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise get<i>(v) >= get<i>(w) with i being v.index().

23.7.7 Visitation [variant.visit]

template <class Visitor, class... Variants> constexpr see below visit(Visitor&& vis, Variants&&... vars);
Requires: The expression in the Effects: element shall be a valid expression of the same type and value category, for all combinations of alternative types of all variants.
Otherwise, the program is ill-formed.
Effects: Let is... be vars.index()....
Returns INVOKE(forward<Visitor>(vis), get<is>(forward<Variants>(vars))...);.
Remarks: The return type is the common type of all possible INVOKE expressions of the Effects: element.
Throws: bad_­variant_­access if any variant in vars is valueless_­by_­exception().
Complexity: For sizeof...(Variants) <= 1, the invocation of the callable object is implemented in constant time, i.e. it does not depend on sizeof...(Types). For sizeof...(Variants) > 1, the invocation of the callable object has no complexity requirements.

23.7.8 Class monostate [variant.monostate]

struct monostate{};
The class monostate can serve as a first alternative type for a variant to make the variant type default constructible.

23.7.9 monostate relational operators [variant.monostate.relops]

constexpr bool operator<(monostate, monostate) noexcept { return false; } constexpr bool operator>(monostate, monostate) noexcept { return false; } constexpr bool operator<=(monostate, monostate) noexcept { return true; } constexpr bool operator>=(monostate, monostate) noexcept { return true; } constexpr bool operator==(monostate, monostate) noexcept { return true; } constexpr bool operator!=(monostate, monostate) noexcept { return false; }
[Note
:
monostate objects have only a single state; they thus always compare equal.
end note
]

23.7.10 Specialized algorithms [variant.specalg]

template <class... Types> void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
Effects: Equivalent to v.swap(w).
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> && is_­swappable_­v<T> is true for all i.
The expression inside noexcept is equivalent to noexcept(v.swap(w)).

23.7.11 Class bad_­variant_­access [variant.bad.access]

class bad_variant_access : public exception {
public:
  bad_variant_access() noexcept;
  const char* what() const noexcept override;
};
Objects of type bad_­variant_­access are thrown to report invalid accesses to the value of a variant object.
bad_variant_access() noexcept;
Constructs a bad_­variant_­access object.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

23.7.12 Hash support [variant.hash]

template <class... Types> struct hash<variant<Types...>>;
The specialization hash<variant<Types...>> is enabled ([unord.hash]) if and only if every specialization in hash<remove_­const_­t<Types>>... is enabled.
The member functions are not guaranteed to be noexcept.
template <> struct hash<monostate>;
The specialization is enabled ([unord.hash]).

23.7.13 Allocator-related traits [variant.traits]

template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).
[Note
:
Specialization of this trait informs other library components that variant can be constructed with an allocator, even though it does not have a nested allocator_­type.
end note
]

23.8 Storage for any type [any]

This section describes components that C++ programs may use to perform operations on objects of a discriminated type.
[Note
:
The discriminated type may contain values of different types but does not attempt conversion between them, i.e. 5 is held strictly as an int and is not implicitly convertible either to "5" or to 5.0.
This indifference to interpretation but awareness of type effectively allows safe, generic containers of single values, with no scope for surprises from ambiguous conversions.
end note
]

23.8.1 Header <any> synopsis [any.synop]

namespace std {
  // [any.bad_any_cast], class bad_­any_­cast
  class bad_any_cast;

  // [any.class], class any
  class any;

  // [any.nonmembers], non-member functions
  void swap(any& x, any& y) noexcept;

  template <class T, class... Args>
    any make_any(Args&& ...args);
  template <class T, class U, class... Args>
    any make_any(initializer_list<U> il, Args&& ...args);

  template<class T>
    T any_cast(const any& operand);
  template<class T>
    T any_cast(any& operand);
  template<class T>
    T any_cast(any&& operand);

  template<class T>
    const T* any_cast(const any* operand) noexcept;
  template<class T>
    T* any_cast(any* operand) noexcept;
}

23.8.2 Class bad_­any_­cast [any.bad_any_cast]

class bad_any_cast : public bad_cast {
public:
  const char* what() const noexcept override;
};
Objects of type bad_­any_­cast are thrown by a failed any_­cast ([any.nonmembers]).
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

23.8.3 Class any [any.class]

class any {
public:
  // [any.cons], construction and destruction
  constexpr any() noexcept;

  any(const any& other);
  any(any&& other) noexcept;

  template <class T> any(T&& value);

  template <class T, class... Args>
    explicit any(in_place_type_t<T>, Args&&...);
  template <class T, class U, class... Args>
    explicit any(in_place_type_t<T>, initializer_list<U>, Args&&...);

  ~any();

  // [any.assign], assignments
  any& operator=(const any& rhs);
  any& operator=(any&& rhs) noexcept;

  template <class T> any& operator=(T&& rhs);

  // [any.modifiers], modifiers
  template <class T, class... Args>
    decay_t<T>& emplace(Args&& ...);
  template <class T, class U, class... Args>
    decay_t<T>& emplace(initializer_list<U>, Args&&...);
  void reset() noexcept;
  void swap(any& rhs) noexcept;

  // [any.observers], observers
  bool has_value() const noexcept;
  const type_info& type() const noexcept;
};
An object of class any stores an instance of any type that satisfies the constructor requirements or it has no value, and this is referred to as the state of the class any object.
The stored instance is called the contained value, Two states are equivalent if either they both have no value, or both have a value and the contained values are equivalent.
The non-member any_­cast functions provide type-safe access to the contained value.
Implementations should avoid the use of dynamically allocated memory for a small contained value.
[Example
:
where the object constructed is holding only an int.
end example
]
Such small-object optimization shall only be applied to types T for which is_­nothrow_­move_­constructible_­v<T> is true.

23.8.3.1 Construction and destruction [any.cons]

constexpr any() noexcept;
Postconditions: has_­value() is false.
any(const any& other);
Effects: If other.has_­value() is false, constructs an object that has no value.
Otherwise, equivalent to any(in_­place<T>, any_­cast<const T&>(other)) where T is the type of the contained object.
Throws: Any exceptions arising from calling the selected constructor for the contained value.
any(any&& other) noexcept;
Effects: If other.has_­value() is false, constructs an object that has no value.
Otherwise, constructs an object of type any that contains either the contained object of other, or contains an object of the same type constructed from the contained object of other considering that contained object as an rvalue.
Postconditions: other is left in a valid but otherwise unspecified state.
template<class T> any(T&& value);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Constructs an object of type any that contains an object of type VT direct-initialized with std​::​forward<T>(value).
Remarks: This constructor shall not participate in overload resolution unless VT is not the same type as any, VT is not a specialization of in_­place_­type_­t, and is_­copy_­constructible_­v<VT> is true.
Throws: Any exception thrown by the selected constructor of VT.
template <class T, class... Args> explicit any(in_place_type_t<T>, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value of type VT.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.
template <class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.
~any();
Effects: As if by reset().

23.8.3.2 Assignment [any.assign]

any& operator=(const any& rhs);
Effects: As if by any(rhs).swap(*this).
No effects if an exception is thrown.
Returns: *this.
Throws: Any exceptions arising from the copy constructor for the contained value.
any& operator=(any&& rhs) noexcept;
Effects: As if by any(std​::​move(rhs)).swap(*this).
Returns: *this.
Postconditions: The state of *this is equivalent to the original state of rhs and rhs is left in a valid but otherwise unspecified state.
template<class T> any& operator=(T&& rhs);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Constructs an object tmp of type any that contains an object of type VT direct-initialized with std​::​forward<T>(rhs), and tmp.swap(*this).
No effects if an exception is thrown.
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless VT is not the same type as any and is_­copy_­constructible_­v<VT> is true.
Throws: Any exception thrown by the selected constructor of VT.

23.8.3.3 Modifiers [any.modifiers]

template <class T, class... Args> decay_t<T>& emplace(Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Calls reset().
Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
This function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.
template <class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U> il, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Calls reset().
Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
The function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.
void reset() noexcept;
Effects: If has_­value() is true, destroys the contained value.
Postconditions: has_­value() is false.
void swap(any& rhs) noexcept;
Effects: Exchanges the states of *this and rhs.

23.8.3.4 Observers [any.observers]

bool has_value() const noexcept;
Returns: true if *this contains an object, otherwise false.
const type_info& type() const noexcept;
Returns: typeid(T) if *this has a contained value of type T, otherwise typeid(void).
[Note
:
Useful for querying against types known either at compile time or only at runtime.
end note
]

23.8.4 Non-member functions [any.nonmembers]

void swap(any& x, any& y) noexcept;
Effects: As if by x.swap(y).
template <class T, class... Args> any make_any(Args&& ...args);
Effects: Equivalent to: return any(in_­place_­type<T>, std​::​forward<Args>(args)...);
template <class T, class U, class... Args> any make_any(initializer_list<U> il, Args&& ...args);
Effects: Equivalent to: return any(in_­place_­type<T>, il, std​::​forward<Args>(args)...);
template<class T> T any_cast(const any& operand); template<class T> T any_cast(any& operand); template<class T> T any_cast(any&& operand);
Let U be the type remove_­cv_­t<remove_­reference_­t<ValueType>>.
Requires: For the first overload, is_­constructible_­v<ValueType, const U&> is true.
For the second overload, is_­constructible_­v<ValueType, U&> is true.
For the third overload, is_­constructible_­v<ValueType, U> is true.
Otherwise the program is ill-formed.
Returns: For the first and second overload, static_­cast<ValueType>(*any_­cast<U>(&operand)).
For the third overload, static_­cast<ValueType>(std​::​move(*any_­cast<U>(&operand))).
Throws: bad_­any_­cast if operand.type() != typeid(remove_­reference_­t<T>).
[Example
:
any x(5);                                   // x holds int
assert(any_cast<int>(x) == 5);              // cast to value
any_cast<int&>(x) = 10;                     // cast to reference
assert(any_cast<int>(x) == 10);

x = "Meow";                                 // x holds const char*
assert(strcmp(any_cast<const char*>(x), "Meow") == 0);
any_cast<const char*&>(x) = "Harry";
assert(strcmp(any_cast<const char*>(x), "Harry") == 0);

x = string("Meow");                         // x holds string
string s, s2("Jane");
s = move(any_cast<string&>(x));             // move from any
assert(s == "Meow");
any_cast<string&>(x) = move(s2);            // move to any
assert(any_cast<const string&>(x) == "Jane");

string cat("Meow");
const any y(cat);                           // const y holds string
assert(any_cast<const string&>(y) == cat);

any_cast<string&>(y);                       // error; cannot
                                            // any_­cast away const
end example
]
template<class T> const T* any_cast(const any* operand) noexcept; template<class T> T* any_cast(any* operand) noexcept;
Returns: If operand != nullptr && operand->type() == typeid(T), a pointer to the object contained by operand; otherwise, nullptr.
[Example
:
bool is_string(const any& operand) {
  return any_cast<string>(&operand) != nullptr;
}
end example
]

23.9 Bitsets [bitset]

23.9.1 Header <bitset> synopsis [bitset.syn]

#include <string>
#include <iosfwd>   // for istream ([istream.syn]), ostream ([ostream.syn]), see [iosfwd.syn]

namespace std {
  template <size_t N> class bitset;

  // [bitset.operators], bitset operators
  template <size_t N>
    bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
  template <class charT, class traits, size_t N>
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
  template <class charT, class traits, size_t N>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
}
The header <bitset> defines a class template and several related functions for representing and manipulating fixed-size sequences of bits.

23.9.2 Class template bitset [template.bitset]

namespace std {
  template<size_t N> class bitset {
  public:
    // bit reference:
    class reference {
      friend class bitset;
      reference() noexcept;
    public:
      ~reference() noexcept;
      reference& operator=(bool x) noexcept;             // for b[i] = x;
      reference& operator=(const reference&) noexcept;   // for b[i] = b[j];
      bool operator~() const noexcept;                   // flips the bit
      operator bool() const noexcept;                    // for x = b[i];
      reference& flip() noexcept;                        // for b[i].flip();
    };

    // [bitset.cons], constructors
    constexpr bitset() noexcept;
    constexpr bitset(unsigned long long val) noexcept;
    template<class charT, class traits, class Allocator>
      explicit bitset(
        const basic_string<charT, traits, Allocator>& str,
        typename basic_string<charT, traits, Allocator>::size_type pos = 0,
        typename basic_string<charT, traits, Allocator>::size_type n =
          basic_string<charT, traits, Allocator>::npos,
        charT zero = charT('0'),
        charT one = charT('1'));
    template <class charT>
      explicit bitset(
        const charT* str,
        typename basic_string<charT>::size_type n = basic_string<charT>::npos,
        charT zero = charT('0'),
        charT one = charT('1'));

    // [bitset.members], bitset operations
    bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator<<=(size_t pos) noexcept;
    bitset<N>& operator>>=(size_t pos) noexcept;
    bitset<N>& set() noexcept;
    bitset<N>& set(size_t pos, bool val = true);
    bitset<N>& reset() noexcept;
    bitset<N>& reset(size_t pos);
    bitset<N>  operator~() const noexcept;
    bitset<N>& flip() noexcept;
    bitset<N>& flip(size_t pos);

    // element access:
    constexpr bool operator[](size_t pos) const;       // for b[i];
    reference operator[](size_t pos);                  // for b[i];

    unsigned long to_ulong() const;
    unsigned long long to_ullong() const;
    template <class charT = char,
              class traits = char_traits<charT>,
              class Allocator = allocator<charT>>
      basic_string<charT, traits, Allocator>
        to_string(charT zero = charT('0'), charT one = charT('1')) const;

    size_t count() const noexcept;
    constexpr size_t size() const noexcept;
    bool operator==(const bitset<N>& rhs) const noexcept;
    bool operator!=(const bitset<N>& rhs) const noexcept;
    bool test(size_t pos) const;
    bool all() const noexcept;
    bool any() const noexcept;
    bool none() const noexcept;
    bitset<N> operator<<(size_t pos) const noexcept;
    bitset<N> operator>>(size_t pos) const noexcept;
  };

  // [bitset.hash], hash support
  template <class T> struct hash;
  template <size_t N> struct hash<bitset<N>>;
}
The class template bitset<N>describes an object that can store a sequence consisting of a fixed number of bits, N.
Each bit represents either the value zero (reset) or one (set).
To toggle a bit is to change the value zero to one, or the value one to zero.
Each bit has a non-negative position pos.
When converting between an object of class bitset<N> and a value of some integral type, bit position pos corresponds to the bit value 1 << pos.
The integral value corresponding to two or more bits is the sum of their bit values.
The functions described in this subclause can report three kinds of errors, each associated with a distinct exception:

23.9.2.1 bitset constructors [bitset.cons]

constexpr bitset() noexcept;
Effects: Constructs an object of class bitset<N>, initializing all bits to zero.
constexpr bitset(unsigned long long val) noexcept;
Effects: Constructs an object of class bitset<N>, initializing the first M bit positions to the corresponding bit values in val.
M is the smaller of N and the number of bits in the value representation ([basic.types]) of unsigned long long.
If M < N, the remaining bit positions are initialized to zero.
template <class charT, class traits, class Allocator> explicit bitset(const basic_string<charT, traits, Allocator>& str, typename basic_string<charT, traits, Allocator>::size_type pos = 0, typename basic_string<charT, traits, Allocator>::size_type n = basic_string<charT, traits, Allocator>::npos, charT zero = charT('0'), charT one = charT('1'));
Throws: out_­of_­range if pos > str.size() or invalid_­argument if an invalid character is found (see below).
Effects: Determines the effective length rlen of the initializing string as the smaller of n and str.size() - pos.
The function then throws invalid_­argument if any of the rlen characters in str beginning at position pos is other than zero or one.
The function uses traits​::​eq() to compare the character values.
Otherwise, the function constructs an object of class bitset<N>, initializing the first M bit positions to values determined from the corresponding characters in the string str.
M is the smaller of N and rlen.
An element of the constructed object has value zero if the corresponding character in str, beginning at position pos, is zero.
Otherwise, the element has the value one.
Character position pos + M - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
If M < N, remaining bit positions are initialized to zero.
template <class charT> explicit bitset( const charT* str, typename basic_string<charT>::size_type n = basic_string<charT>::npos, charT zero = charT('0'), charT one = charT('1'));
Effects: Constructs an object of class bitset<N> as if by:
bitset(
  n == basic_string<charT>::npos
    ? basic_string<charT>(str)
    : basic_string<charT>(str, n),
  0, n, zero, one)

23.9.2.2 bitset members [bitset.members]

bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
Effects: Clears each bit in *this for which the corresponding bit in rhs is clear, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
Effects: Sets each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
Effects: Toggles each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator<<=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If I < pos, the new value is zero;
  • If I >= pos, the new value is the previous value of the bit at position I - pos.
Returns: *this.
bitset<N>& operator>>=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If pos >= N - I, the new value is zero;
  • If pos < N - I, the new value is the previous value of the bit at position I + pos.
Returns: *this.
bitset<N>& set() noexcept;
Effects: Sets all bits in *this.
Returns: *this.
bitset<N>& set(size_t pos, bool val = true);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Stores a new value in the bit at position pos in *this.
If val is nonzero, the stored value is one, otherwise it is zero.
Returns: *this.
bitset<N>& reset() noexcept;
Effects: Resets all bits in *this.
Returns: *this.
bitset<N>& reset(size_t pos);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Resets the bit at position pos in *this.
Returns: *this.
bitset<N> operator~() const noexcept;
Effects: Constructs an object x of class bitset<N> and initializes it with *this.
Returns: x.flip().
bitset<N>& flip() noexcept;
Effects: Toggles all bits in *this.
Returns: *this.
bitset<N>& flip(size_t pos);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Toggles the bit at position pos in *this.
Returns: *this.
unsigned long to_ulong() const;
Throws: overflow_­error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long.
Returns: x.
unsigned long long to_ullong() const;
Throws: overflow_­error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long long.
Returns: x.
template <class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
Effects: Constructs a string object of the appropriate type and initializes it to a string of length N characters.
Each character is determined by the value of its corresponding bit position in *this.
Character position N - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
Bit value zero becomes the character zero, bit value one becomes the character one.
Returns: The created object.
size_t count() const noexcept;
Returns: A count of the number of bits set in *this.
constexpr size_t size() const noexcept;
Returns: N.
bool operator==(const bitset<N>& rhs) const noexcept;
Returns: true if the value of each bit in *this equals the value of the corresponding bit in rhs.
bool operator!=(const bitset<N>& rhs) const noexcept;
Returns: true if !(*this == rhs).
bool test(size_t pos) const;
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Returns: true if the bit at position pos in *this has the value one.
bool all() const noexcept;
Returns: count() == size().
bool any() const noexcept;
Returns: count() != 0.
bool none() const noexcept;
Returns: count() == 0.
bitset<N> operator<<(size_t pos) const noexcept;
Returns: bitset<N>(*this) <<= pos.
bitset<N> operator>>(size_t pos) const noexcept;
Returns: bitset<N>(*this) >>= pos.
constexpr bool operator[](size_t pos) const;
Requires: pos shall be valid.
Returns: true if the bit at position pos in *this has the value one, otherwise false.
Throws: Nothing.
bitset<N>::reference operator[](size_t pos);
Requires: pos shall be valid.
Returns: An object of type bitset<N>​::​reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val).
Throws: Nothing.
Remarks: For the purpose of determining the presence of a data race ([intro.multithread]), any access or update through the resulting reference potentially accesses or modifies, respectively, the entire underlying bitset.

23.9.3 bitset hash support [bitset.hash]

template <size_t N> struct hash<bitset<N>>;
The specialization is enabled ([unord.hash]).

23.9.4 bitset operators [bitset.operators]

bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) &= rhs.
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) |= rhs.
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) ^= rhs.
template <class charT, class traits, size_t N> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
A formatted input function ([istream.formatted]).
Effects: Extracts up to N characters from is.
Stores these characters in a temporary object str of type basic_­string<charT, traits>, then evaluates the expression x = bitset<N>(str).
Characters are extracted and stored until any of the following occurs:
  • N characters have been extracted and stored;
  • end-of-file occurs on the input sequence;
  • the next input character is neither is.widen('0') nor is.widen('1') (in which case the input character is not extracted).
If no characters are stored in str, calls is.setstate(ios_­base​::​failbit) (which may throw ios_­base​::​failure ([iostate.flags])).
Returns: is.
template <class charT, class traits, size_t N> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
Returns:
os << x.template to_string<charT, traits, allocator<charT>>(
  use_facet<ctype<charT>>(os.getloc()).widen('0'),
  use_facet<ctype<charT>>(os.getloc()).widen('1'))
(see [ostream.formatted]).

23.10 Memory [memory]

23.10.1 In general [memory.general]

This subclause describes the contents of the header <memory> ([memory.syn]) and some of the contents of the header <cstdlib> ([cstdlib.syn]).

23.10.2 Header <memory> synopsis [memory.syn]

The header <memory> defines several types and function templates that describe properties of pointers and pointer-like types, manage memory for containers and other template types, destroy objects, and construct multiple objects in uninitialized memory buffers ([pointer.traits][specialized.algorithms]).
The header also defines the templates unique_­ptr, shared_­ptr, weak_­ptr, and various function templates that operate on objects of these types ([smartptr]).
namespace std {
  // [pointer.traits], pointer traits
  template <class Ptr> struct pointer_traits;
  template <class T> struct pointer_traits<T*>;

  // [util.dynamic.safety], pointer safety
  enum class pointer_safety { relaxed, preferred, strict };
  void declare_reachable(void* p);
  template <class T> T* undeclare_reachable(T* p);
  void declare_no_pointers(char* p, size_t n);
  void undeclare_no_pointers(char* p, size_t n);
  pointer_safety get_pointer_safety() noexcept;

  // [ptr.align], pointer alignment function
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);

  // [allocator.tag], allocator argument tag
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
  inline constexpr allocator_arg_t allocator_arg{};

  // [allocator.uses], uses_­allocator
  template <class T, class Alloc> struct uses_allocator;

  // [allocator.traits], allocator traits
  template <class Alloc> struct allocator_traits;

  // [default.allocator], the default allocator
  template <class T> class allocator;
  template <class T, class U>
    bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
  template <class T, class U>
    bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;

  // [specialized.algorithms], specialized algorithms
  template <class T> constexpr T* addressof(T& r) noexcept;
  template <class T> const T* addressof(const T&&) = delete;
  template <class ForwardIterator>
    void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                      ForwardIterator first, Size n);
  template <class ForwardIterator>
    void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                    ForwardIterator first, Size n);
  template <class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
                                         ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         InputIterator first, Size n,
                                         ForwardIterator result);
  template <class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class InputIterator, class Size, class ForwardIterator>
    pair<InputIterator, ForwardIterator>
      uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
    pair<InputIterator, ForwardIterator>
      uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           InputIterator first, Size n, ForwardIterator result);
  template <class ForwardIterator, class T>
    void uninitialized_fill(ForwardIterator first, ForwardIterator last,
                            const T& x);
  template <class ExecutionPolicy, class ForwardIterator, class T>
    void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                            ForwardIterator first, ForwardIterator last,
                            const T& x);
  template <class ForwardIterator, class Size, class T>
    ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
  template <class ExecutionPolicy, class ForwardIterator, class Size, class T>
    ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator first, Size n, const T& x);
  template <class T>
    void destroy_at(T* location);
  template <class ForwardIterator>
    void destroy(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator destroy_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              ForwardIterator first, Size n);

  // [unique.ptr], class template unique_­ptr
  template <class T> struct default_delete;
  template <class T> struct default_delete<T[]>;
  template <class T, class D = default_delete<T>> class unique_ptr;
  template <class T, class D> class unique_ptr<T[], D>;

  template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
  template <class T> unique_ptr<T> make_unique(size_t n);
  template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

  template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

  template <class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

  template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

  // [util.smartptr.weak.bad], class bad_­weak_­ptr
  class bad_weak_ptr;

  // [util.smartptr.shared], class template shared_­ptr
  template<class T> class shared_ptr;

  // [util.smartptr.shared.create], shared_­ptr creation
  template<class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
  template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);

  // [util.smartptr.shared.cmp], shared_­ptr comparisons
  template<class T, class U>
    bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;

  template <class T>
    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;

  // [util.smartptr.shared.spec], shared_­ptr specialized algorithms
  template<class T>
    void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.cast], shared_­ptr casts
  template<class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;

  // [util.smartptr.getdeleter], shared_­ptr get_­deleter
  template<class D, class T>
    D* get_deleter(const shared_ptr<T>& p) noexcept;

  // [util.smartptr.shared.io], shared_­ptr I/O
  template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);

  // [util.smartptr.weak], class template weak_­ptr
  template<class T> class weak_ptr;

  // [util.smartptr.weak.spec], weak_­ptr specialized algorithms
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

  // [util.smartptr.ownerless], class template owner_­less
  template<class T = void> struct owner_less;

  // [util.smartptr.enab], class template enable_­shared_­from_­this
  template<class T> class enable_shared_from_this;

  // [util.smartptr.shared.atomic], shared_­ptr atomic access
  template<class T>
    bool atomic_is_lock_free(const shared_ptr<T>* p);

  template<class T>
    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
  template<class T>
    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);

  template<class T>
    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    bool atomic_compare_exchange_weak(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_strong(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_weak_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);
  template<class T>
    bool atomic_compare_exchange_strong_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);

  // [util.smartptr.hash], hash support
  template <class T> struct hash;
  template <class T, class D> struct hash<unique_ptr<T, D>>;
  template <class T> struct hash<shared_ptr<T>>;

  // [allocator.uses.trait], uses_­allocator
  template <class T, class Alloc>
    inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
}

23.10.3 Pointer traits [pointer.traits]

The class template pointer_­traits supplies a uniform interface to certain attributes of pointer-like types.
namespace std {
  template <class Ptr> struct pointer_traits {
    using pointer         = Ptr;
    using element_type    = see below;
    using difference_type = see below;

    template <class U> using rebind = see below;

    static pointer pointer_to(see below r);
  };

  template <class T> struct pointer_traits<T*> {
    using pointer         = T*;
    using element_type    = T;
    using difference_type = ptrdiff_t;

    template <class U> using rebind = U*;

    static pointer pointer_to(see below r) noexcept;
  };
}

23.10.3.1 Pointer traits member types [pointer.traits.types]

using element_type = see below;
Type: Ptr​::​element_­type if the qualified-id Ptr​::​element_­type is valid and denotes a type ([temp.deduct]); otherwise, T if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the specialization is ill-formed.
using difference_type = see below;
Type: Ptr​::​difference_­type if the qualified-id Ptr​::​difference_­type is valid and denotes a type ([temp.deduct]); otherwise, ptrdiff_­t.
template <class U> using rebind = see below;
Alias template: Ptr​::​rebind<U> if the qualified-id Ptr​::​rebind<U> is valid and denotes a type ([temp.deduct]); otherwise, SomePointer<U, Args> if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind is ill-formed.

23.10.3.2 Pointer traits member functions [pointer.traits.functions]

static pointer pointer_traits::pointer_to(see below r); static pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
Remarks: If element_­type is cv void, the type of r is unspecified; otherwise, it is element_­type&.
Returns: The first member function returns a pointer to r obtained by calling Ptr​::​pointer_­to(r) through which indirection is valid; an instantiation of this function is ill-formed if Ptr does not have a matching pointer_­to static member function.
The second member function returns addressof(r).

23.10.4 Pointer safety [util.dynamic.safety]

A complete object is declared reachable while the number of calls to declare_­reachable with an argument referencing the object exceeds the number of calls to undeclare_­reachable with an argument referencing the object.
void declare_reachable(void* p);
Requires: p shall be a safely-derived pointer ([basic.stc.dynamic.safety]) or a null pointer value.
Effects: If p is not null, the complete object referenced by p is subsequently declared reachable ([basic.stc.dynamic.safety]).
Throws: May throw bad_­alloc if the system cannot allocate additional memory that may be required to track objects declared reachable.
template <class T> T* undeclare_reachable(T* p);
Requires: If p is not null, the complete object referenced by p shall have been previously declared reachable, and shall be live ([basic.life]) from the time of the call until the last undeclare_­reachable(p) call on the object.
Returns: A safely derived copy of p which shall compare equal to p.
Throws: Nothing.
[Note
:
It is expected that calls to declare_­reachable(p) will consume a small amount of memory in addition to that occupied by the referenced object until the matching call to undeclare_­reachable(p) is encountered.
Long running programs should arrange that calls are matched.
end note
]
void declare_no_pointers(char* p, size_t n);
Requires: No bytes in the specified range are currently registered with declare_­no_­pointers().
If the specified range is in an allocated object, then it must be entirely within a single allocated object.
The object must be live until the corresponding undeclare_­no_­pointers() call.
[Note
:
In a garbage-collecting implementation, the fact that a region in an object is registered with declare_­no_­pointers() should not prevent the object from being collected.
end note
]
Effects: The n bytes starting at p no longer contain traceable pointer locations, independent of their type.
Hence indirection through a pointer located there is undefined if the object it points to was created by global operator new and not previously declared reachable.
[Note
:
This may be used to inform a garbage collector or leak detector that this region of memory need not be traced.
end note
]
Throws: Nothing.
[Note
:
Under some conditions implementations may need to allocate memory.
However, the request can be ignored if memory allocation fails.
end note
]
void undeclare_no_pointers(char* p, size_t n);
Requires: The same range must previously have been passed to declare_­no_­pointers().
Effects: Unregisters a range registered with declare_­no_­pointers() for destruction.
It must be called before the lifetime of the object ends.
Throws: Nothing.
pointer_safety get_pointer_safety() noexcept;
Returns: pointer_­safety​::​strict if the implementation has strict pointer safety ([basic.stc.dynamic.safety]).
It is implementation-defined whether get_­pointer_­safety returns pointer_­safety​::​relaxed or pointer_­safety​::​preferred if the implementation has relaxed pointer safety.221
pointer_­safety​::​preferred might be returned to indicate that a leak detector is running so that the program can avoid spurious leak reports.

23.10.5 Align [ptr.align]

void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
Effects: If it is possible to fit size bytes of storage aligned by alignment into the buffer pointed to by ptr with length space, the function updates ptr to represent the first possible address of such storage and decreases space by the number of bytes used for alignment.
Otherwise, the function does nothing.
Requires:
  • alignment shall be a power of two
  • ptr shall represent the address of contiguous storage of at least space bytes
Returns: A null pointer if the requested aligned buffer would not fit into the available space, otherwise the adjusted value of ptr.
[Note
:
The function updates its ptr and space arguments so that it can be called repeatedly with possibly different alignment and size arguments for the same buffer.
end note
]

23.10.6 Allocator argument tag [allocator.tag]

namespace std { struct allocator_arg_t { explicit allocator_arg_t() = default; }; inline constexpr allocator_arg_t allocator_arg{}; }
The allocator_­arg_­t struct is an empty structure type used as a unique type to disambiguate constructor and function overloading.
Specifically, several types (see tuple [tuple]) have constructors with allocator_­arg_­t as the first argument, immediately followed by an argument of a type that satisfies the Allocator requirements ([allocator.requirements]).

23.10.7 uses_­allocator [allocator.uses]

23.10.7.1 uses_­allocator trait [allocator.uses.trait]

template <class T, class Alloc> struct uses_allocator;
Remarks: Automatically detects whether T has a nested allocator_­type that is convertible from Alloc.
Meets the BinaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that is derived from true_­type if the qualified-id T​::​allocator_­type is valid and denotes a type ([temp.deduct]) and is_­convertible_­v<Alloc, T​::​allocator_­type> != false, otherwise it shall be derived from false_­type.
A program may specialize this template to derive from true_­type for a user-defined type T that does not have a nested allocator_­type but nonetheless can be constructed with an allocator where either:
  • the first argument of a constructor has type allocator_­arg_­t and the second argument has type Alloc or
  • the last argument of a constructor has type Alloc.

23.10.7.2 Uses-allocator construction [allocator.uses.construction]

Uses-allocator construction with allocator Alloc refers to the construction of an object obj of type T, using constructor arguments v1, v2, ..., vN of types V1, V2, ..., VN, respectively, and an allocator alloc of type Alloc, according to the following rules:
  • if uses_­allocator_­v<T, Alloc> is false and is_­constructible_­v<T, V1, V2, ..., VN> is true, then obj is initialized as obj(v1, v2, ..., vN);
  • otherwise, if uses_­allocator_­v<T, Alloc> is true and is_­constructible_­v<T, allocator_­arg_­t, Alloc, V1, V2, ..., VN> is true, then obj is initialized as obj(allocator_­arg, alloc, v1, v2, ..., vN);
  • otherwise, if uses_­allocator_­v<T, Alloc> is true and is_­constructible_­v<T, V1, V2, ..., VN, Alloc> is true, then obj is initialized as obj(v1, v2, ..., vN, alloc);
  • otherwise, the request for uses-allocator construction is ill-formed.
    [Note
    :
    An error will result if uses_­allocator_­v<T, Alloc> is true but the specific constructor does not take an allocator.
    This definition prevents a silent failure to pass the allocator to an element.
    end note
    ]

23.10.8 Allocator traits [allocator.traits]

The class template allocator_­traits supplies a uniform interface to all allocator types.
An allocator cannot be a non-class type, however, even if allocator_­traits supplies the entire required interface.
[Note
:
Thus, it is always possible to create a derived class from an allocator.
end note
]
namespace std {
  template <class Alloc> struct allocator_traits {
    using allocator_type     = Alloc;

    using value_type         = typename Alloc::value_type;

    using pointer            = see below;
    using const_pointer      = see below;
    using void_pointer       = see below;
    using const_void_pointer = see below;

    using difference_type    = see below;
    using size_type          = see below;

    using propagate_on_container_copy_assignment = see below;
    using propagate_on_container_move_assignment = see below;
    using propagate_on_container_swap            = see below;
    using is_always_equal                        = see below;

    template <class T> using rebind_alloc = see below;
    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;

    static pointer allocate(Alloc& a, size_type n);
    static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);

    static void deallocate(Alloc& a, pointer p, size_type n);

    template <class T, class... Args>
      static void construct(Alloc& a, T* p, Args&&... args);

    template <class T>
      static void destroy(Alloc& a, T* p);

    static size_type max_size(const Alloc& a) noexcept;

    static Alloc select_on_container_copy_construction(const Alloc& rhs);
  };
}

23.10.8.1 Allocator traits member types [allocator.traits.types]

using pointer = see below;
Type: Alloc​::​pointer if the qualified-id Alloc​::​pointer is valid and denotes a type ([temp.deduct]); otherwise, value_­type*.
using const_pointer = see below;
Type: Alloc​::​const_­pointer if the qualified-id Alloc​::​const_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​rebind<​const value_­type>.
using void_pointer = see below;
Type: Alloc​::​void_­pointer if the qualified-id Alloc​::​void_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​rebind<​void>.
using const_void_pointer = see below;
Type: Alloc​::​const_­void_­pointer if the qualified-id Alloc​::​const_­void_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​​rebind<const void>.
using difference_type = see below;
Type: Alloc​::​difference_­type if the qualified-id Alloc​::​difference_­type is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​difference_­type.
using size_type = see below;
Type: Alloc​::​size_­type if the qualified-id Alloc​::​size_­type is valid and denotes a type ([temp.deduct]); otherwise, make_­unsigned_­t<difference_­type>.
using propagate_on_container_copy_assignment = see below;
Type: Alloc​::​propagate_­on_­container_­copy_­assignment if the qualified-id Alloc​::​propagate_­on_­container_­copy_­assignment is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using propagate_on_container_move_assignment = see below;
Type: Alloc​::​propagate_­on_­container_­move_­assignment if the qualified-id Alloc​::​propagate_­on_­container_­move_­assignment is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using propagate_on_container_swap = see below;
Type: Alloc​::​propagate_­on_­container_­swap if the qualified-id Alloc​::​propagate_­on_­container_­swap is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using is_always_equal = see below;
Type: Alloc​::​is_­always_­equal if the qualified-id Alloc​::​is_­always_­equal is valid and denotes a type ([temp.deduct]); otherwise is_­empty<Alloc>​::​type.
template <class T> using rebind_alloc = see below;
Alias template: Alloc​::​rebind<T>​::​other if the qualified-id Alloc​::​rebind<T>​::​other is valid and denotes a type ([temp.deduct]); otherwise, Alloc<T, Args> if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind_­alloc is ill-formed.

23.10.8.2 Allocator traits static member functions [allocator.traits.members]

static pointer allocate(Alloc& a, size_type n);
Returns: a.allocate(n).
static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
Returns: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n).
static void deallocate(Alloc& a, pointer p, size_type n);
Effects: Calls a.deallocate(p, n).
Throws: Nothing.
template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args);
Effects: Calls a.construct(p, std​::​forward<Args>(args)...) if that call is well-formed; otherwise, invokes ​::​new (static_­cast<void*>(p)) T(std​::​forward<Args>(args)...).
template <class T> static void destroy(Alloc& a, T* p);
Effects: Calls a.destroy(p) if that call is well-formed; otherwise, invokes p->~T().
static size_type max_size(const Alloc& a) noexcept;
Returns: a.max_­size() if that expression is well-formed; otherwise, numeric_­limits<size_­type>​::​​max()/sizeof(value_­type).
static Alloc select_on_container_copy_construction(const Alloc& rhs);
Returns: rhs.select_­on_­container_­copy_­construction() if that expression is well-formed; otherwise, rhs.

23.10.9 The default allocator [default.allocator]

All specializations of the default allocator satisfy the allocator completeness requirements ([allocator.requirements.completeness]).
namespace std {
  template <class T> class allocator {
   public:
    using value_type      = T;
    using propagate_on_container_move_assignment = true_type;
    using is_always_equal = true_type;

    allocator() noexcept;
    allocator(const allocator&) noexcept;
    template <class U> allocator(const allocator<U>&) noexcept;
    ~allocator();

    T* allocate(size_t n);
    void deallocate(T* p, size_t n);
  };
}

23.10.9.1 allocator members [allocator.members]

Except for the destructor, member functions of the default allocator shall not introduce data races ([intro.multithread]) as a result of concurrent calls to those member functions from different threads.
Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.
T* allocate(size_t n);
Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T.
Remarks: the storage is obtained by calling ​::​operator new ([new.delete]), but it is unspecified when or how often this function is called.
Throws: bad_­alloc if the storage cannot be obtained.
void deallocate(T* p, size_t n);
Requires: p shall be a pointer value obtained from allocate().
n shall equal the value passed as the first argument to the invocation of allocate which returned p.
Effects: Deallocates the storage referenced by p .
Remarks: Uses ​::​operator delete ([new.delete]), but it is unspecified when this function is called.

23.10.9.2 allocator globals [allocator.globals]

template <class T, class U> bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
Returns: true.
template <class T, class U> bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
Returns: false.

23.10.10 Specialized algorithms [specialized.algorithms]

Throughout this subclause, the names of template parameters are used to express type requirements.
  • If an algorithm's template parameter is named InputIterator, the template argument shall satisfy the requirements of an input iterator ([input.iterators]).
  • If an algorithm's template parameter is named ForwardIterator, the template argument shall satisfy the requirements of a forward iterator ([forward.iterators]), and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.
Unless otherwise specified, if an exception is thrown in the following algorithms there are no effects.

23.10.10.1 addressof [specialized.addressof]

template <class T> constexpr T* addressof(T& r) noexcept;
Returns: The actual address of the object or function referenced by r, even in the presence of an overloaded operator&.
Remarks: An expression addressof(E) is a constant subexpression ([defns.const.subexpr]) if E is an lvalue constant subexpression.

23.10.10.2 uninitialized_­default_­construct [uninitialized.construct.default]

template <class ForwardIterator> void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type;
template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n>0; (void)++first, --n)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type;
return first;

23.10.10.3 uninitialized_­value_­construct [uninitialized.construct.value]

template <class ForwardIterator> void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type();
template <class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n>0; (void)++first, --n)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type();
return first;

23.10.10.4 uninitialized_­copy [uninitialized.copy]

template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
Effects: As if by:
for (; first != last; ++result, (void) ++first)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(*first);
Returns: result.
template <class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
Effects: As if by:
for ( ; n > 0; ++result, (void) ++first, --n) {
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(*first);
}
Returns: result.

23.10.10.5 uninitialized_­move [uninitialized.move]

template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
Effects: Equivalent to:
for (; first != last; (void)++result, ++first)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return result;
Remarks: If an exception is thrown, some objects in the range [first, last) are left in a valid but unspecified state.
template <class InputIterator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
Effects: Equivalent to:
for (; n > 0; ++result, (void) ++first, --n)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return {first,result};
Remarks: If an exception is thrown, some objects in the range [first, std​::​next(first,n)) are left in a valid but unspecified state.

23.10.10.6 uninitialized_­fill [uninitialized.fill]

template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
Effects: As if by:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type(x);
template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
Effects: As if by:
for (; n--; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type(x);
return first;

23.10.10.7 destroy [specialized.destroy]

template <class T> void destroy_at(T* location);
Effects: Equivalent to:
location->~T();
template <class ForwardIterator> void destroy(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first!=last; ++first)
  destroy_at(addressof(*first));
template <class ForwardIterator, class Size> ForwardIterator destroy_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n > 0; (void)++first, --n)
  destroy_at(addressof(*first));
return first;

23.10.11 C library memory allocation [c.malloc]

[Note
:
The header <cstdlib> ([cstdlib.syn]) declares the functions described in this subclause.
end note
]
void* aligned_alloc(size_t alignment, size_t size); void* calloc(size_t nmemb, size_t size); void* malloc(size_t size); void* realloc(void* ptr, size_t size);
Effects: These functions have the semantics specified in the C standard library.
Remarks: These functions do not attempt to allocate storage by calling ​::​operator new() ([support.dynamic]).
Storage allocated directly with these functions is implicitly declared reachable (see [basic.stc.dynamic.safety]) on allocation, ceases to be declared reachable on deallocation, and need not cease to be declared reachable as the result of an undeclare_­reachable() call.
[Note
:
This allows existing C libraries to remain unaffected by restrictions on pointers that are not safely derived, at the expense of providing far fewer garbage collection and leak detection options for malloc()-allocated objects.
It also allows malloc() to be implemented with a separate allocation arena, bypassing the normal declare_­reachable() implementation.
The above functions should never intentionally be used as a replacement for declare_­reachable(), and newly written code is strongly encouraged to treat memory allocated with these functions as though it were allocated with operator new.
end note
]
void free(void* ptr);
Effects: This function has the semantics specified in the C standard library.
Remarks: This function does not attempt to deallocate storage by calling ​::​operator delete().
See also: ISO C 7.22.3.

23.11 Smart pointers [smartptr]

23.11.1 Class template unique_­ptr [unique.ptr]

A unique pointer is an object that owns another object and manages that other object through a pointer.
More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose of p when u is itself destroyed (e.g., when leaving block scope ([stmt.dcl])).
In this context, u is said to own p.
The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct invocation results in p's appropriate disposition (typically its deletion).
Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter.
Upon request, u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned object via the associated deleter before such replacement is considered completed.
Additionally, u can, upon request, transfer ownership to another unique pointer u2.
Upon completion of such a transfer, the following postconditions hold:
  • u2.p is equal to the pre-transfer u.p,
  • u.p is equal to nullptr, and
  • if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete.
[Note
:
A deleter's state need never be copied, only moved or swapped as ownership is transferred.
end note
]
Each object of a type U instantiated from the unique_­ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer.
In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
The template parameter T of unique_­ptr may be an incomplete type.
[Note
:
The uses of unique_­ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.
end note
]
namespace std {
  template<class T> struct default_delete;
  template<class T> struct default_delete<T[]>;

  template<class T, class D = default_delete<T>> class unique_ptr;
  template<class T, class D> class unique_ptr<T[], D>;

  template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
  template<class T> unique_ptr<T> make_unique(size_t n);
  template<class T, class... Args> unspecified make_unique(Args&&...) = delete;

  template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

  template<class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

  template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

}

23.11.1.1 Default deleters [unique.ptr.dltr]

23.11.1.1.1 In general [unique.ptr.dltr.general]

The class template default_­delete serves as the default deleter (destruction policy) for the class template unique_­ptr.
The template parameter T of default_­delete may be an incomplete type.

23.11.1.1.2 default_­delete [unique.ptr.dltr.dflt]

namespace std {
  template <class T> struct default_delete {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U>&) noexcept;
    void operator()(T*) const;
  };
}
template <class U> default_delete(const default_delete<U>& other) noexcept;
Effects: Constructs a default_­delete object from another default_­delete<U> object.
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T*.
void operator()(T* ptr) const;
Effects: Calls delete on ptr.
Remarks: If T is an incomplete type, the program is ill-formed.

23.11.1.1.3 default_­delete<T[]> [unique.ptr.dltr.dflt1]

namespace std {
  template <class T> struct default_delete<T[]> {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U[]>&) noexcept;
    template <class U> void operator()(U* ptr) const;
  };
}
template <class U> default_delete(const default_delete<U[]>& other) noexcept;
Effects: constructs a default_­delete object from another default_­delete<U[]> object.
Remarks: This constructor shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].
template <class U> void operator()(U* ptr) const;
Effects: Calls delete[] on ptr.
Remarks: If U is an incomplete type, the program is ill-formed.
This function shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].

23.11.1.2 unique_­ptr for single objects [unique.ptr.single]

namespace std {
  template <class T, class D = default_delete<T>> class unique_ptr {
  public:
    using pointer      = see below;
    using element_type = T;
    using deleter_type = D;

    // [unique.ptr.single.ctor], constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;
    template <class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;

    // [unique.ptr.single.dtor], destructor
    ~unique_ptr();

    // [unique.ptr.single.asgn], assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.single.observers], observers
    add_lvalue_reference_t<T> operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.single.modifiers], modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;

    // disable copy from lvalue
    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
  };
}
The default type for the template parameter D is default_­delete.
A client-supplied template argument D shall be a function object type ([function.objects]), lvalue reference to function, or lvalue reference to function object type for which, given a value d of type D and a value ptr of type unique_­ptr<T, D>​::​pointer, the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible (Table 27).
If the qualified-id remove_­reference_­t<D>​::​pointer is valid and denotes a type ([temp.deduct]), then unique_­ptr<T, D>​::​pointer shall be a synonym for remove_­reference_­t<D>​::​pointer.
Otherwise unique_­ptr<T, D>​::​pointer shall be a synonym for element_­type*.
The type unique_­ptr<T, D>​::​pointer shall satisfy the requirements of NullablePointer ([nullablepointer.requirements]).
[Example
:
Given an allocator type X ([allocator.requirements]) and letting A be a synonym for allocator_­traits<X>, the types A​::​pointer, A​::​const_­pointer, A​::​void_­pointer, and A​::​const_­void_­pointer may be used as unique_­ptr<T, D>​::​pointer.
end example
]

23.11.1.2.1 unique_­ptr constructors [unique.ptr.single.ctor]

constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table 22), and that construction shall not throw an exception.
Effects: Constructs a unique_­ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.
Postconditions: get() == nullptr.
get_­deleter() returns a reference to the stored deleter.
Remarks: If is_­pointer_­v<deleter_­type> is true or is_­default_­constructible_­v<deleter_­type> is false, this constructor shall not participate in overload resolution.
explicit unique_ptr(pointer p) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table 22), and that construction shall not throw an exception.
Effects: Constructs a unique_­ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter.
Postconditions: get() == p.
get_­deleter() returns a reference to the stored deleter.
Remarks: If is_­pointer_­v<deleter_­type> is true or is_­default_­constructible_­v<deleter_­type> is false, this constructor shall not participate in overload resolution.
If class template argument deduction ([over.match.class.deduct]) would select the function template corresponding to this constructor, then the program is ill-formed.
unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept;
The signature of these constructors depends upon whether D is a reference type.
If D is a non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, A&& d) noexcept;
If D is an lvalue reference type A&, then the signatures are:
unique_ptr(pointer p, A& d) noexcept;
unique_ptr(pointer p, A&& d) = delete;
If D is an lvalue reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, const A&& d) = delete;
Effects: Constructs a unique_­ptr object which owns p, initializing the stored pointer with p and initializing the deleter from std​::​forward<decltype(d)>(d).
Remarks: These constructors shall not participate in overload resolution unless is_­constructible_­v<D, decltype(d)> is true.
Postconditions: get() == p.
get_­deleter() returns a reference to the stored deleter.
If D is a reference type then get_­deleter() returns a reference to the lvalue d.
Remarks: If class template argument deduction ([over.match.class.deduct]) would select a function template corresponding to either of these constructors, then the program is ill-formed.
[Example
:
D d;
unique_ptr<int, D> p1(new int, D());        // D must be MoveConstructible
unique_ptr<int, D> p2(new int, d);          // D must be CopyConstructible
unique_ptr<int, D&> p3(new int, d);         // p3 holds a reference to d
unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined
                                            // with reference deleter type
end example
]
unique_ptr(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible (Table 23).
Construction of the deleter from an rvalue of type D shall not throw an exception.
Effects: Constructs a unique_­ptr by transferring ownership from u to *this.
If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note
:
The deleter constructor can be implemented with std​::​forward<D>.
end note
]
Postconditions: get() yields the value u.get() yielded before the construction.
get_­deleter() returns a reference to the stored deleter that was constructed from u.get_­deleter().
If D is a reference type then get_­deleter() and u.get_­deleter() both reference the same lvalue deleter.
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception.
Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Remarks: This constructor shall not participate in overload resolution unless:
  • unique_­ptr<U, E>​::​pointer is implicitly convertible to pointer,
  • U is not an array type, and
  • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Effects: Constructs a unique_­ptr by transferring ownership from u to *this.
If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note
:
The deleter constructor can be implemented with std​::​forward<E>.
end note
]
Postconditions: get() yields the value u.get() yielded before the construction.
get_­deleter() returns a reference to the stored deleter that was constructed from u.get_­deleter().

23.11.1.2.2 unique_­ptr destructor [unique.ptr.single.dtor]

~unique_ptr();
Requires: The expression get_­deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
[Note
:
The use of default_­delete requires T to be a complete type.
end note
]
Effects: If get() == nullptr there are no effects.
Otherwise get_­deleter()(get()).

23.11.1.2.3 unique_­ptr assignment [unique.ptr.single.asgn]

unique_ptr& operator=(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable (Table 25) and assignment of the deleter from an rvalue of type D shall not throw an exception.
Otherwise, D is a reference type; remove_­reference_­t<D> shall satisfy the CopyAssignable requirements and assignment of the deleter from an lvalue of type D shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_­deleter() = std​::​forward<D>(u.get_­deleter()).
Returns: *this.
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception.
Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
Remarks: This operator shall not participate in overload resolution unless:
  • unique_­ptr<U, E>​::​pointer is implicitly convertible to pointer, and
  • U is not an array type, and
  • is_­assignable_­v<D&, E&&> is true.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_­deleter() = std​::​forward<E>(u.get_­deleter()).
Returns: *this.
unique_ptr& operator=(nullptr_t) noexcept;
Effects: As if by reset().
Postconditions: get() == nullptr.
Returns: *this.

23.11.1.2.4 unique_­ptr observers [unique.ptr.single.observers]

add_lvalue_reference_t<T> operator*() const;
Requires: get() != nullptr.
Returns: *get().
pointer operator->() const noexcept;
Requires: get() != nullptr.
Returns: get().
[Note
:
The use of this function typically requires that T be a complete type.
end note
]
pointer get() const noexcept;
Returns: The stored pointer.
deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept;
Returns: A reference to the stored deleter.
explicit operator bool() const noexcept;
Returns: get() != nullptr.

23.11.1.2.5 unique_­ptr modifiers [unique.ptr.single.modifiers]

pointer release() noexcept;
Postconditions: get() == nullptr.
Returns: The value get() had at the start of the call to release.
void reset(pointer p = pointer()) noexcept;
Requires: The expression get_­deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: Assigns p to the stored pointer, and then if and only if the old value of the stored pointer, old_­p, was not equal to nullptr, calls get_­deleter()(old_­p).
[Note
:
The order of these operations is significant because the call to get_­deleter() may destroy *this.
end note
]
Postconditions: get() == p.
[Note
:
The postcondition does not hold if the call to get_­deleter() destroys *this since this->get() is no longer a valid expression.
end note
]
void swap(unique_ptr& u) noexcept;
Requires: get_­deleter() shall be swappable ([swappable.requirements]) and shall not throw an exception under swap.
Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.

23.11.1.3 unique_­ptr for array objects with a runtime length [unique.ptr.runtime]

namespace std {
  template <class T, class D> class unique_ptr<T[], D> {
  public:
    using pointer      = see below;
    using element_type = T;
    using deleter_type = D;

    // [unique.ptr.runtime.ctor], constructors
    constexpr unique_ptr() noexcept;
    template <class U> explicit unique_ptr(U p) noexcept;
    template <class U> unique_ptr(U p, see below d) noexcept;
    template <class U> unique_ptr(U p, see below d) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    template <class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E>
      unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.runtime.observers], observers
    T& operator[](size_t i) const;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.runtime.modifiers], modifiers
    pointer release() noexcept;
    template <class U> void reset(U p) noexcept;
    void reset(nullptr_t = nullptr) noexcept;
    void swap(unique_ptr& u) noexcept;

    // disable copy from lvalue
    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
  };
}
A specialization for array types is provided with a slightly altered interface.
  • Conversions between different types of unique_­ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms of unique_­ptr, produce an ill-formed program.
  • Pointers to types derived from T are rejected by the constructors, and by reset.
  • The observers operator* and operator-> are not provided.
  • The indexing observer operator[] is provided.
  • The default deleter will call delete[].
Descriptions are provided below only for members that differ from the primary template.
The template argument T shall be a complete type.

23.11.1.3.1 unique_­ptr constructors [unique.ptr.runtime.ctor]

template <class U> explicit unique_ptr(U p) noexcept;
This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer except that it additionally shall not participate in overload resolution unless
  • U is the same type as pointer, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].
template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept;
These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter except that they shall not participate in overload resolution unless either
  • U is the same type as pointer,
  • U is nullptr_­t, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
This constructor behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_­ptr<U, E>:
  • U is an array type, and
  • pointer is the same type as element_­type*, and
  • UP​::​pointer is the same type as UP​::​element_­type*, and
  • UP​::​element_­type(*)[] is convertible to element_­type(*)[], and
  • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
[Note
:
This replaces the overload-resolution specification of the primary template
end note
]

23.11.1.3.2 unique_­ptr assignment [unique.ptr.runtime.asgn]

template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u)noexcept;
This operator behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_­ptr<U, E>:
  • U is an array type, and
  • pointer is the same type as element_­type*, and
  • UP​::​pointer is the same type as UP​::​element_­type*, and
  • UP​::​element_­type(*)[] is convertible to element_­type(*)[], and
  • is_­assignable_­v<D&, E&&> is true.
[Note
:
This replaces the overload-resolution specification of the primary template
end note
]

23.11.1.3.3 unique_­ptr observers [unique.ptr.runtime.observers]

T& operator[](size_t i) const;
Requires: i < the number of elements in the array to which the stored pointer points.
Returns: get()[i].

23.11.1.3.4 unique_­ptr modifiers [unique.ptr.runtime.modifiers]

void reset(nullptr_t p = nullptr) noexcept;
Effects: Equivalent to reset(pointer()).
template <class U> void reset(U p) noexcept;
This function behaves the same as the reset member of the primary template, except that it shall not participate in overload resolution unless either
  • U is the same type as pointer, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].

23.11.1.4 unique_­ptr creation [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Remarks: This function shall not participate in overload resolution unless T is not an array.
Returns: unique_­ptr<T>(new T(std​::​forward<Args>(args)...)).
template <class T> unique_ptr<T> make_unique(size_t n);
Remarks: This function shall not participate in overload resolution unless T is an array of unknown bound.
Returns: unique_­ptr<T>(new remove_­extent_­t<T>[n]()).
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
Remarks: This function shall not participate in overload resolution unless T is an array of known bound.

23.11.1.5 unique_­ptr specialized algorithms [unique.ptr.special]

template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<D> is true.
Effects: Calls x.swap(y).
template <class T1, class D1, class T2, class D2> bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: x.get() == y.get().
template <class T1, class D1, class T2, class D2> bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: x.get() != y.get().
template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Requires: Let CT denote
common_type_t<typename unique_ptr<T1, D1>::pointer,
              typename unique_ptr<T2, D2>::pointer>
Then the specialization less<CT> shall be a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.
Returns: less<CT>()(x.get(), y.get()).
Remarks: If unique_­ptr<T1, D1>​::​pointer is not implicitly convertible to CT or unique_­ptr<T2, D2>​::​pointer is not implicitly convertible to CT, the program is ill-formed.
template <class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: !(y < x).
template <class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: y < x.
template <class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: !(x < y).
template <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: !x.
template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: (bool)x.
template <class T, class D> bool operator<(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<(nullptr_t, const unique_ptr<T, D>& x);
Requires: The specialization less<unique_­ptr<T, D>​::​pointer> shall be a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.
Returns: The first function template returns less<unique_­ptr<T, D>​::​pointer>()(x.get(),
nullptr)
.
The second function template returns less<unique_­ptr<T, D>​::​pointer>()(nullptr, x.get()).
template <class T, class D> bool operator>(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns nullptr < x.
The second function template returns x < nullptr.
template <class T, class D> bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(nullptr < x).
The second function template returns !(x < nullptr).
template <class T, class D> bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(x < nullptr).
The second function template returns !(nullptr < x).

23.11.2 Shared-ownership pointers [util.smartptr]

23.11.2.1 Class bad_­weak_­ptr [util.smartptr.weak.bad]

namespace std {
  class bad_weak_ptr : public exception {
  public:
    bad_weak_ptr() noexcept;
  };
}
An exception of type bad_­weak_­ptr is thrown by the shared_­ptr constructor taking a weak_­ptr.
bad_weak_ptr() noexcept;
Postconditions: what() returns an implementation-defined ntbs.

23.11.2.2 Class template shared_­ptr [util.smartptr.shared]

The shared_­ptr class template stores a pointer, usually obtained via new.
shared_­ptr implements semantics of shared ownership; the last remaining owner of the pointer is responsible for destroying the object, or otherwise releasing the resources associated with the stored pointer.
A shared_­ptr is said to be empty if it does not own a pointer.
namespace std {
  template<class T> class shared_ptr {
  public:
    using element_type = remove_extent_t<T>;
    using weak_type    = weak_ptr<T>;

    // [util.smartptr.shared.const], constructors
    constexpr shared_ptr() noexcept;
    template<class Y> explicit shared_ptr(Y* p);
    template<class Y, class D> shared_ptr(Y* p, D d);
    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
    template <class D> shared_ptr(nullptr_t p, D d);
    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
    template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
    shared_ptr(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
    shared_ptr(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
    constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }

    // [util.smartptr.shared.dest], destructor
    ~shared_ptr();

    // [util.smartptr.shared.assign], assignment
    shared_ptr& operator=(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    shared_ptr& operator=(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);

    // [util.smartptr.shared.mod], modifiers
    void swap(shared_ptr& r) noexcept;
    void reset() noexcept;
    template<class Y> void reset(Y* p);
    template<class Y, class D> void reset(Y* p, D d);
    template<class Y, class D, class A> void reset(Y* p, D d, A a);

    // [util.smartptr.shared.obs], observers
    element_type* get() const noexcept;
    T& operator*() const noexcept;
    T* operator->() const noexcept;
    element_type& operator[](ptrdiff_t i) const;
    long use_count() const noexcept;
    explicit operator bool() const noexcept;
    template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
    template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
  };

  template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
  template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;

  // [util.smartptr.shared.create], shared_­ptr creation
  template<class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
  template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);

  // [util.smartptr.shared.cmp], shared_­ptr comparisons
  template<class T, class U>
    bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;

  template <class T>
    bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator==(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator!=(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator<(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator<=(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator>(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.spec], shared_­ptr specialized algorithms
  template<class T>
    void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.cast], shared_­ptr casts
  template<class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;

  // [util.smartptr.getdeleter], shared_­ptr get_­deleter
  template<class D, class T>
    D* get_deleter(const shared_ptr<T>& p) noexcept;

  // [util.smartptr.shared.io], shared_­ptr I/O
  template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
}
Specializations of shared_­ptr shall be CopyConstructible, CopyAssignable, and LessThanComparable, allowing their use in standard containers.
Specializations of shared_­ptr shall be contextually convertible to bool, allowing their use in boolean expressions and declarations in conditions.
The template parameter T of shared_­ptr may be an incomplete type.
[Example
:
if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
  // do something with px
}
end example
]
For purposes of determining the presence of a data race, member functions shall access and modify only the shared_­ptr and weak_­ptr objects themselves and not objects they refer to.
Changes in use_­count() do not reflect modifications that can introduce data races.
For the purposes of subclause [util.smartptr], a pointer type Y* is said to be compatible with a pointer type T* when either Y* is convertible to T* or Y is U[N] and T is cv U[].

23.11.2.2.1 shared_­ptr constructors [util.smartptr.shared.const]

In the constructor definitions below, enables shared_­from_­this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_­shared_­from_­this ([util.smartptr.enab]), then remove_­cv_­t<Y>* shall be implicitly convertible to T* and the constructor evaluates the statement:
if (p != nullptr && p->weak_this.expired())
  p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
The assignment to the weak_­this member is not atomic and conflicts with any potentially concurrent access to the same object ([intro.multithread]).
constexpr shared_ptr() noexcept;
Effects: Constructs an empty shared_­ptr object.
Postconditions: use_­count() == 0 && get() == nullptr.
template<class Y> explicit shared_ptr(Y* p);
Requires: Y shall be a complete type.
The expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall have well-defined behavior, and shall not throw exceptions.
Effects: When T is not an array type, constructs a shared_­ptr object that owns the pointer p.
Otherwise, constructs a shared_­ptr that owns p and a deleter of an unspecified type that calls delete[] p.
When T is not an array type, enables shared_­from_­this with p.
If an exception is thrown, delete p is called when T is not an array type, delete[] p otherwise.
Postconditions: use_­count() == 1 && get() == p.
Throws: bad_­alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
Remarks: When T is an array type, this constructor shall not participate in overload resolution unless the expression delete[] p is well-formed and either T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
When T is not an array type, this constructor shall not participate in overload resolution unless the expression delete p is well-formed and Y* is convertible to T*.
template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template <class D> shared_ptr(nullptr_t p, D d); template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
Requires: Construction of d and a deleter of type D initialized with std​::​move(d) shall not throw exceptions.
The expression d(p) shall have well-defined behavior and shall not throw exceptions.
A shall be an allocator ([allocator.requirements]).
Effects: Constructs a shared_­ptr object that owns the object p and the deleter d.
When T is not an array type, the first and second constructors enable shared_­from_­this with p.
The second and fourth constructors shall use a copy of a to allocate memory for internal use.
If an exception is thrown, d(p) is called.
Postconditions: use_­count() == 1 && get() == p.
Throws: bad_­alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
Remarks: When T is an array type, this constructor shall not participate in overload resolution unless is_­move_­constructible_­v<D> is true, the expression d(p) is well-formed, and either T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
When T is not an array type, this constructor shall not participate in overload resolution unless is_­move_­constructible_­v<D> is true, the expression d(p) is well-formed, and Y* is convertible to T*.
template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
Effects: Constructs a shared_­ptr instance that stores p and shares ownership with r.
Postconditions: get() == p && use_­count() == r.use_­count().
[Note
:
To avoid the possibility of a dangling pointer, the user of this constructor must ensure that p remains valid at least until the ownership group of r is destroyed.
end note
]
[Note
:
This constructor allows creation of an empty shared_­ptr instance with a non-null stored pointer.
end note
]
shared_ptr(const shared_ptr& r) noexcept; template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: If r is empty, constructs an empty shared_­ptr object; otherwise, constructs a shared_­ptr object that shares ownership with r.
Postconditions: get() == r.get() && use_­count() == r.use_­count().
shared_ptr(shared_ptr&& r) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: Move constructs a shared_­ptr instance from r.
Postconditions: *this shall contain the old value of r.
r shall be empty.
r.get() == nullptr.
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
Effects: Constructs a shared_­ptr object that shares ownership with r and stores a copy of the pointer stored in r.
If an exception is thrown, the constructor has no effect.
Postconditions: use_­count() == r.use_­count().
Throws: bad_­weak_­ptr when r.expired().
Remarks: This constructor shall not participate in overload resolution unless Y* is compatible with T*.
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
Remarks: This constructor shall not participate in overload resolution unless Y* is compatible with T* and unique_­ptr<Y, D>​::​pointer is convertible to element_­type*.
Effects: If r.get() == nullptr, equivalent to shared_­ptr().
Otherwise, if D is not a reference type, equivalent to shared_­ptr(r.release(), r.get_­deleter()).
Otherwise, equivalent to shared_­ptr(r.release(), ref(r.get_­deleter())).
If an exception is thrown, the constructor has no effect.

23.11.2.2.2 shared_­ptr destructor [util.smartptr.shared.dest]

~shared_ptr();
Effects:
  • If *this is empty or shares ownership with another shared_­ptr instance (use_­count() > 1), there are no side effects.
  • Otherwise, if *this owns an object p and a deleter d, d(p) is called.
  • Otherwise, *this owns a pointer p, and delete p is called.
[Note
:
Since the destruction of *this decreases the number of instances that share ownership with *this by one, after *this has been destroyed all shared_­ptr instances that shared ownership with *this will report a use_­count() that is one less than its previous value.
end note
]

23.11.2.2.3 shared_­ptr assignment [util.smartptr.shared.assign]

shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Effects: Equivalent to shared_­ptr(r).swap(*this).
Returns: *this.
[Note
:
The use count updates caused by the temporary object construction and destruction are not observable side effects, so the implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary.
In particular, in the example:
shared_ptr<int> p(new int);
shared_ptr<void> q(p);
p = p;
q = p;
both assignments may be no-ops.
end note
]
shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
Effects: Equivalent to shared_­ptr(std​::​move(r)).swap(*this).
Returns: *this.
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
Effects: Equivalent to shared_­ptr(std​::​move(r)).swap(*this).
Returns: *this.

23.11.2.2.4 shared_­ptr modifiers [util.smartptr.shared.mod]

void swap(shared_ptr& r) noexcept;
Effects: Exchanges the contents of *this and r.
void reset() noexcept;
Effects: Equivalent to shared_­ptr().swap(*this).
template<class Y> void reset(Y* p);
Effects: Equivalent to shared_­ptr(p).swap(*this).
template<class Y, class D> void reset(Y* p, D d);
Effects: Equivalent to shared_­ptr(p, d).swap(*this).
template<class Y, class D, class A> void reset(Y* p, D d, A a);
Effects: Equivalent to shared_­ptr(p, d, a).swap(*this).

23.11.2.2.5 shared_­ptr observers [util.smartptr.shared.obs]

element_type* get() const noexcept;
Returns: The stored pointer.
T& operator*() const noexcept;
Requires: get() != 0.
Returns: *get().
Remarks: When T is an array type or cv void, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
T* operator->() const noexcept;
Requires: get() != 0.
Returns: get().
Remarks: When T is an array type, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
element_type& operator[](ptrdiff_t i) const;
Requires: get() != 0 && i >= 0.
If T is U[N], i < N.
Returns: get()[i].
Remarks: When T is not an array type, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
Throws: Nothing.
long use_count() const noexcept;
Returns: The number of shared_­ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.
Synchronization: None.
[Note
:
get() == nullptr does not imply a specific return value of use_­count().
end note
]
[Note
:
weak_­ptr<T>​::​lock() can affect the return value of use_­count().
end note
]
[Note
:
When multiple threads can affect the return value of use_­count(), the result should be treated as approximate.
In particular, use_­count() == 1 does not imply that accesses through a previously destroyed shared_­ptr have in any sense completed.
end note
]
explicit operator bool() const noexcept;
Returns: get() != 0.
template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
Returns: An unspecified value such that
  • x.owner_­before(y) defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by owner_­before, !a.owner_­before(b) && !b.owner_­before(a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.

23.11.2.2.6 shared_­ptr creation [util.smartptr.shared.create]

template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args); template<class T, class A, class... Args> shared_ptr<T> allocate_shared(const A& a, Args&&... args);
Requires: The expression ​::​new (pv) T(std​::​forward<Args>(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed.
A shall be an allocator ([allocator.requirements]).
The copy constructor and destructor of A shall not throw exceptions.
Effects: Allocates memory suitable for an object of type T and constructs an object in that memory via the placement new-expression ​::​new (pv) T(std​::​forward<Args>(args)...).
The template allocate_­shared uses a copy of a to allocate memory.
If an exception is thrown, the functions have no effect.
Returns: A shared_­ptr instance that stores and owns the address of the newly constructed object of type T.
Postconditions: get() != 0 && use_­count() == 1.
Throws: bad_­alloc, or an exception thrown from A​::​allocate or from the constructor of T.
Remarks: The shared_­ptr constructor called by this function enables shared_­from_­this with the address of the newly constructed object of type T.
Implementations should perform no more than one memory allocation.
[Note
:
This provides efficiency equivalent to an intrusive smart pointer.
end note
]
[Note
:
These functions will typically allocate more memory than sizeof(T) to allow for internal bookkeeping structures such as the reference counts.
end note
]

23.11.2.2.7 shared_­ptr comparison [util.smartptr.shared.cmp]

template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
Returns: a.get() == b.get().
template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
Returns: less<>()(a.get(), b.get()).
[Note
:
Defining a comparison function allows shared_­ptr objects to be used as keys in associative containers.
end note
]
template <class T> bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator==(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: !a.
template <class T> bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator!=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: (bool)a.
template <class T> bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns less<shared_­ptr<T>​::​element_­type*>()(a.get(), nullptr).
The second function template returns less<shared_­ptr<T>​::​element_­type*>()(nullptr, a.get()).
template <class T> bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator>(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns nullptr < a.
The second function template returns a < nullptr.
template <class T> bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator<=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns !(nullptr < a).
The second function template returns !(a < nullptr).
template <class T> bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator>=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns !(a < nullptr).
The second function template returns !(nullptr < a).

23.11.2.2.8 shared_­ptr specialized algorithms [util.smartptr.shared.spec]

template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
Effects: Equivalent to a.swap(b).

23.11.2.2.9 shared_­ptr casts [util.smartptr.shared.cast]

template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression static_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(static_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression dynamic_­cast<T*>((U*)0) shall be well formed and shall have well defined behavior.
Returns:
  • When dynamic_­cast<typename shared_­ptr<T>​::​element_­type*>(r.get()) returns a nonzero value p, shared_­ptr<T>(r, p).
  • Otherwise, shared_­ptr<T>().
[Note
:
The seemingly equivalent expression shared_­ptr<T>(dynamic_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression const_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(const_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression reinterpret_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(reinterpret_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]

23.11.2.2.10 get_­deleter [util.smartptr.getdeleter]

template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
Returns: If p owns a deleter d of type cv-unqualified D, returns addressof(d); otherwise returns nullptr.
The returned pointer remains valid as long as there exists a shared_­ptr instance that owns d.
[Note
:
It is unspecified whether the pointer remains valid longer than that.
This can happen if the implementation doesn't destroy the deleter until all weak_­ptr instances that share ownership with p have been destroyed.
end note
]

23.11.2.2.11 shared_­ptr I/O [util.smartptr.shared.io]

template<class E, class T, class Y> basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
Effects: As if by: os << p.get();
Returns: os.

23.11.2.3 Class template weak_­ptr [util.smartptr.weak]

The weak_­ptr class template stores a weak reference to an object that is already managed by a shared_­ptr.
To access the object, a weak_­ptr can be converted to a shared_­ptr using the member function lock.
namespace std {
  template<class T> class weak_ptr {
  public:
    using element_type = T;

    // [util.smartptr.weak.const], constructors
    constexpr weak_ptr() noexcept;
    template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
    weak_ptr(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
    weak_ptr(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.dest], destructor
    ~weak_ptr();

    // [util.smartptr.weak.assign], assignment
    weak_ptr& operator=(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
    template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    weak_ptr& operator=(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.mod], modifiers
    void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

    // [util.smartptr.weak.obs], observers
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr<T> lock() const noexcept;
    template<class U> bool owner_before(const shared_ptr<U>& b) const;
    template<class U> bool owner_before(const weak_ptr<U>& b) const;
  };

  template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;


  // [util.smartptr.weak.spec], specialized algorithms
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
}
Specializations of weak_­ptr shall be CopyConstructible and CopyAssignable, allowing their use in standard containers.
The template parameter T of weak_­ptr may be an incomplete type.

23.11.2.3.1 weak_­ptr constructors [util.smartptr.weak.const]

constexpr weak_ptr() noexcept;
Effects: Constructs an empty weak_­ptr object.
Postconditions: use_­count() == 0.
weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
Effects: If r is empty, constructs an empty weak_­ptr object; otherwise, constructs a weak_­ptr object that shares ownership with r and stores a copy of the pointer stored in r.
Postconditions: use_­count() == r.use_­count().
weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: Move constructs a weak_­ptr instance from r.
Postconditions: *this shall contain the old value of r.
r shall be empty.
r.use_­count() == 0.

23.11.2.3.2 weak_­ptr destructor [util.smartptr.weak.dest]

~weak_ptr();
Effects: Destroys this weak_­ptr object but has no effect on the object its stored pointer points to.

23.11.2.3.3 weak_­ptr assignment [util.smartptr.weak.assign]

weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Effects: Equivalent to weak_­ptr(r).swap(*this).
Remarks: The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary.
Returns: *this.
weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
Effects: Equivalent to weak_­ptr(std​::​move(r)).swap(*this).
Returns: *this.

23.11.2.3.4 weak_­ptr modifiers [util.smartptr.weak.mod]

void swap(weak_ptr& r) noexcept;
Effects: Exchanges the contents of *this and r.
void reset() noexcept;
Effects: Equivalent to weak_­ptr().swap(*this).

23.11.2.3.5 weak_­ptr observers [util.smartptr.weak.obs]

long use_count() const noexcept;
Returns: 0 if *this is empty; otherwise, the number of shared_­ptr instances that share ownership with *this.
bool expired() const noexcept;
Returns: use_­count() == 0.
shared_ptr<T> lock() const noexcept;
Returns: expired() ? shared_­ptr<T>() : shared_­ptr<T>(*this), executed atomically.
template<class U> bool owner_before(const shared_ptr<U>& b) const; template<class U> bool owner_before(const weak_ptr<U>& b) const;
Returns: An unspecified value such that
  • x.owner_­before(y) defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by owner_­before, !a.owner_­before(b) && !b.owner_­before(a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.

23.11.2.3.6 weak_­ptr specialized algorithms [util.smartptr.weak.spec]

template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Effects: Equivalent to a.swap(b).

23.11.2.4 Class template owner_­less [util.smartptr.ownerless]

The class template owner_­less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std {
  template<class T = void> struct owner_less;

  template<class T> struct owner_less<shared_ptr<T>> {
    bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
    bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
  };

  template<class T> struct owner_less<weak_ptr<T>> {
    bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
  };

  template<> struct owner_less<void> {
    template<class T, class U>
      bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;

    using is_transparent = unspecified;
  };
}
operator()(x, y) shall return x.owner_­before(y).
[Note
:
Note that
  • operator() defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by operator(), !operator()(a, b) && !operator()(b, a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.
end note
]

23.11.2.5 Class template enable_­shared_­from_­this [util.smartptr.enab]

A class T can inherit from enable_­shared_­from_­this<T> to inherit the shared_­from_­this member functions that obtain a shared_­ptr instance pointing to *this.
[Example
:
struct X: public enable_shared_from_this<X> { };

int main() {
  shared_ptr<X> p(new X);
  shared_ptr<X> q = p->shared_from_this();
  assert(p == q);
  assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
}
end example
]
namespace std {
  template<class T> class enable_shared_from_this {
  protected:
    constexpr enable_shared_from_this() noexcept;
    enable_shared_from_this(const enable_shared_from_this&) noexcept;
    enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
    ~enable_shared_from_this();
  public:
    shared_ptr<T> shared_from_this();
    shared_ptr<T const> shared_from_this() const;
    weak_ptr<T> weak_from_this() noexcept;
    weak_ptr<T const> weak_from_this() const noexcept;
  private:
    mutable weak_ptr<T> weak_this; // exposition only
  };
}
The template parameter T of enable_­shared_­from_­this may be an incomplete type.
constexpr enable_shared_from_this() noexcept; enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
Effects: Value-initializes weak_­this.
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
Returns: *this.
[Note
:
weak_­this is not changed.
end note
]
shared_ptr<T> shared_from_this(); shared_ptr<T const> shared_from_this() const;
Returns: shared_­ptr<T>(weak_­this).
weak_ptr<T> weak_from_this() noexcept; weak_ptr<T const> weak_from_this() const noexcept;
Returns: weak_­this.

23.11.2.6 shared_­ptr atomic access [util.smartptr.shared.atomic]

Concurrent access to a shared_­ptr object from multiple threads does not introduce a data race if the access is done exclusively via the functions in this section and the instance is passed as their first argument.
The meaning of the arguments of type memory_­order is explained in [atomics.order].
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: true if atomic access to *p is lock-free, false otherwise.
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: atomic_­load_­explicit(p, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order_­release or memory_­order_­acq_­rel.
Returns: *p.
Throws: Nothing.
template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Effects: As if by atomic_­store_­explicit(p, r, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order_­acquire or memory_­order_­acq_­rel.
Effects: As if by p->swap(r).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Returns: atomic_­exchange_­explicit(p, r, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Effects: As if by p->swap(r).
Returns: The previous value of *p.
Throws: Nothing.
template<class T> bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Requires: p shall not be null and v shall not be null.
Returns:
atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
Throws: Nothing.
template<class T> bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Returns:
atomic_compare_exchange_strong_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
template<class T> bool atomic_compare_exchange_weak_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); template<class T> bool atomic_compare_exchange_strong_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure);
Requires: p shall not be null and v shall not be null.
The failure argument shall not be memory_­order_­release nor memory_­order_­acq_­rel.
Effects: If *p is equivalent to *v, assigns w to *p and has synchronization semantics corresponding to the value of success, otherwise assigns *p to *v and has synchronization semantics corresponding to the value of failure.
Returns: true if *p was equivalent to *v, false otherwise.
Throws: Nothing.
Remarks: Two shared_­ptr objects are equivalent if they store the same pointer value and share ownership.
The weak form may fail spuriously.

23.11.2.7 Smart pointer hash support [util.smartptr.hash]

template <class T, class D> struct hash<unique_ptr<T, D>>;
Letting UP be unique_­ptr<T,D>, the specialization hash<UP> is enabled ([unord.hash]) if and only if hash<typename UP​::​pointer> is enabled.
When enabled, for an object p of type UP, hash<UP>()(p) shall evaluate to the same value as hash<typename UP​::​pointer>()(p.get()).
The member functions are not guaranteed to be noexcept.
template <class T> struct hash<shared_ptr<T>>;
For an object p of type shared_­ptr<T>, hash<shared_­ptr<T>>()(p) shall evaluate to the same value as hash<typename shared_­ptr<T>​::​element_­type*>()(p.get()).

23.12 Memory resources [mem.res]

23.12.1 Header <memory_­resource> synopsis [mem.res.syn]

namespace std::pmr {
  // [mem.res.class], class memory_­resource
  class memory_resource;

  bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
  bool operator!=(const memory_resource& a, const memory_resource& b) noexcept;

  // [mem.poly.allocator.class], class template polymorphic_­allocator
  template <class Tp> class polymorphic_allocator;

  template <class T1, class T2>
    bool operator==(const polymorphic_allocator<T1>& a,
                    const polymorphic_allocator<T2>& b) noexcept;
  template <class T1, class T2>
    bool operator!=(const polymorphic_allocator<T1>& a,
                    const polymorphic_allocator<T2>& b) noexcept;

  // [mem.res.global], global memory resources
  memory_resource* new_delete_resource() noexcept;
  memory_resource* null_memory_resource() noexcept;
  memory_resource* set_default_resource(memory_resource* r) noexcept;
  memory_resource* get_default_resource() noexcept;

  // [mem.res.pool], pool resource classes
  struct pool_options;
  class synchronized_pool_resource;
  class unsynchronized_pool_resource;
  class monotonic_buffer_resource;
}

23.12.2 Class memory_­resource [mem.res.class]

The memory_­resource class is an abstract interface to an unbounded set of classes encapsulating memory resources.
class memory_resource {
  static constexpr size_t max_align = alignof(max_align_t); // exposition only

public:
  virtual ~memory_resource();

  void* allocate(size_t bytes, size_t alignment = max_align);
  void deallocate(void* p, size_t bytes, size_t alignment = max_align);

  bool is_equal(const memory_resource& other) const noexcept;

private:
  virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
  virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;

  virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
};

23.12.2.1 memory_­resource public member functions [mem.res.public]

~memory_resource();
Effects: Destroys this memory_­resource.
void* allocate(size_t bytes, size_t alignment = max_align);
Effects: Equivalent to: return do_­allocate(bytes, alignment);
void deallocate(void* p, size_t bytes, size_t alignment = max_align);
Effects: Equivalent to: do_­deallocate(p, bytes, alignment);
bool is_equal(const memory_resource& other) const noexcept;
Effects: Equivalent to: return do_­is_­equal(other);

23.12.2.2 memory_­resource private virtual member functions [mem.res.private]

virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
Requires: alignment shall be a power of two.
Returns: A derived class shall implement this function to return a pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The returned storage is aligned to the specified alignment, if such alignment is supported ([basic.align]); otherwise it is aligned to max_­align.
Throws: A derived class implementation shall throw an appropriate exception if it is unable to allocate memory with the requested size and alignment.
virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
Requires: p shall have been returned from a prior call to allocate(bytes, alignment) on a memory resource equal to *this, and the storage at p shall not yet have been deallocated.
Effects: A derived class shall implement this function to dispose of allocated storage.
Throws: Nothing.
virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
Returns: A derived class shall implement this function to return true if memory allocated from this can be deallocated from other and vice-versa, otherwise false.
[Note
:
The most-derived type of other might not match the type of this.
For a derived class D, a typical implementation of this function will immediately return false if dynamic_­cast<const D*>(&other) == nullptr.
end note
]

23.12.2.3 memory_­resource equality [mem.res.eq]

bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
Returns: &a == &b || a.is_­equal(b).
bool operator!=(const memory_resource& a, const memory_resource& b) noexcept;
Returns: !(a == b).

23.12.3 Class template polymorphic_­allocator [mem.poly.allocator.class]

A specialization of class template pmr​::​polymorphic_­allocator conforms to the Allocator requirements ([allocator.requirements]).
Constructed with different memory resources, different instances of the same specialization of pmr​::​polymorphic_­allocator can exhibit entirely different allocation behavior.
This runtime polymorphism allows objects that use polymorphic_­allocator to behave as if they used different allocator types at run time even though they use the same static allocator type.
template <class Tp>
class polymorphic_allocator {
  memory_resource* memory_rsrc; // exposition only

public:
  using value_type = Tp;

  // [mem.poly.allocator.ctor], constructors
  polymorphic_allocator() noexcept;
  polymorphic_allocator(memory_resource* r);

  polymorphic_allocator(const polymorphic_allocator& other) = default;

  template <class U>
    polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;

  polymorphic_allocator&
    operator=(const polymorphic_allocator& rhs) = delete;

  // [mem.poly.allocator.mem], member functions
  Tp* allocate(size_t n);
  void deallocate(Tp* p, size_t n);

  template <class T, class... Args>
  void construct(T* p, Args&&... args);

  template <class T1, class T2, class... Args1, class... Args2>
    void construct(pair<T1,T2>* p, piecewise_construct_t,
                   tuple<Args1...> x, tuple<Args2...> y);
  template <class T1, class T2>
    void construct(pair<T1,T2>* p);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, U&& x, V&& y);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, const pair<U, V>& pr);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, pair<U, V>&& pr);

  template <class T>
    void destroy(T* p);

  polymorphic_allocator select_on_container_copy_construction() const;

  memory_resource* resource() const;
};

23.12.3.1 polymorphic_­allocator constructors [mem.poly.allocator.ctor]

polymorphic_allocator() noexcept;
Effects: Sets memory_­rsrc to get_­default_­resource().
polymorphic_allocator(memory_resource* r);
Requires: r is non-null.
Effects: Sets memory_­rsrc to r.
Throws: Nothing.
[Note
:
This constructor provides an implicit conversion from memory_­resource*.
end note
]
template <class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
Effects: Sets memory_­rsrc to other.resource().

23.12.3.2 polymorphic_­allocator member functions [mem.poly.allocator.mem]

Tp* allocate(size_t n);
Returns: Equivalent to
return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
void deallocate(Tp* p, size_t n);
Requires: p was allocated from a memory resource x, equal to *memory_­rsrc, using x.allocate(n * sizeof(Tp), alignof(Tp)).
Effects: Equivalent to memory_­rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp)).
Throws: Nothing.
template <class T, class... Args> void construct(T* p, Args&&... args);
Requires: Uses-allocator construction of T with allocator resource() (see [allocator.uses.construction]) and constructor arguments std​::​forward<Args>(args)... is well-formed.
[Note
:
Uses-allocator construction is always well formed for types that do not use allocators.
end note
]
Effects: Construct a T object in the storage whose address is represented by p by uses-allocator construction with allocator resource() and constructor arguments std​::​forward<Args>(args)....
Throws: Nothing unless the constructor for T throws.
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1,T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
[Note
:
This method and the construct methods that follow are overloads for piecewise construction of pairs ([pairs.pair]).
end note
]
Effects: Let xprime be a tuple constructed from x according to the appropriate rule from the following list.
[Note
:
The following description can be summarized as constructing a pair<T1, T2> object in the storage whose address is represented by p, as if by separate uses-allocator construction with allocator resource() ([allocator.uses.construction]) of p->first using the elements of x and p->second using the elements of y.
end note
]
  • If uses_­allocator_­v<T1,memory_­resource*> is false
    and is_­constructible_­v<T1,Args1...> is true,
    then xprime is x.
  • Otherwise, if uses_­allocator_­v<T1,memory_­resource*> is true
    and is_­constructible_­v<T1,allocator_­arg_­t,memory_­resource*,Args1...> is true,
    then xprime is tuple_­cat(make_­tuple(allocator_­arg, resource()), std​::​move(x)).
  • Otherwise, if uses_­allocator_­v<T1,memory_­resource*> is true
    and is_­constructible_­v<T1,Args1...,memory_­resource*> is true,
    then xprime is tuple_­cat(std​::​move(x), make_­tuple(resource())).
  • Otherwise the program is ill formed.
Let yprime be a tuple constructed from y according to the appropriate rule from the following list:
  • If uses_­allocator_­v<T2,memory_­resource*> is false
    and is_­constructible_­v<T2,Args2...> is true,
    then yprime is y.
  • Otherwise, if uses_­allocator_­v<T2,memory_­resource*> is true
    and is_­constructible_­v<T2,allocator_­arg_­t,memory_­resource*,Args2...> is true,
    then yprime is tuple_­cat(make_­tuple(allocator_­arg, resource()), std​::​move(y)).
  • Otherwise, if uses_­allocator_­v<T2,memory_­resource*> is true
    and is_­constructible_­v<T2,Args2...,memory_­resource*> is true,
    then yprime is tuple_­cat(std​::​move(y), make_­tuple(resource())).
  • Otherwise the program is ill formed.
Then, using piecewise_­construct, xprime, and yprime as the constructor arguments, this function constructs a pair<T1, T2> object in the storage whose address is represented by p.
template <class T1, class T2> void construct(pair<T1,T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x)),
          forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, const pair<U, V>& pr);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(pr.first),
          forward_as_tuple(pr.second));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, pair<U, V>&& pr);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(pr.first)),
          forward_as_tuple(std::forward<V>(pr.second)));
template <class T> void destroy(T* p);
Effects: As if by p->~T().
polymorphic_allocator select_on_container_copy_construction() const;
Returns: polymorphic_­allocator().
[Note
:
The memory resource is not propagated.
end note
]
memory_resource* resource() const;
Returns: memory_­rsrc.

23.12.3.3 polymorphic_­allocator equality [mem.poly.allocator.eq]

template <class T1, class T2> bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept;
Returns: *a.resource() == *b.resource().
template <class T1, class T2> bool operator!=(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept;
Returns: !(a == b).

23.12.4 Access to program-wide memory_­resource objects [mem.res.global]

memory_resource* new_delete_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_­resource that can serve as a resource for allocating memory using ​::​operator new and ​::​operator delete.
The same value is returned every time this function is called.
For a return value p and a memory resource r, p->is_­equal(r) returns &r == p.
memory_resource* null_memory_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_­resource for which allocate() always throws bad_­alloc and for which deallocate() has no effect.
The same value is returned every time this function is called.
For a return value p and a memory resource r, p->is_­equal(r) returns &r == p.
The default memory resource pointer is a pointer to a memory resource that is used by certain facilities when an explicit memory resource is not supplied through the interface.
Its initial value is the return value of new_­delete_­resource().
memory_resource* set_default_resource(memory_resource* r) noexcept;
Effects: If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_­delete_­resource().
Postconditions: get_­default_­resource() == r.
Returns: The previous value of the default memory resource pointer.
Remarks: Calling the set_­default_­resource and get_­default_­resource functions shall not incur a data race.
A call to the set_­default_­resource function shall synchronize with subsequent calls to the set_­default_­resource and get_­default_­resource functions.
memory_resource* get_default_resource() noexcept;
Returns: The current value of the default memory resource pointer.

23.12.5 Pool resource classes [mem.res.pool]

23.12.5.1 Classes synchronized_­pool_­resource and unsynchronized_­pool_­resource [mem.res.pool.overview]

The synchronized_­pool_­resource and unsynchronized_­pool_­resource classes (collectively called pool resource classes) are general-purpose memory resources having the following qualities:
  • Each resource frees its allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
  • A pool resource consists of a collection of pools, serving requests for different block sizes.
    Each individual pool manages a collection of chunks that are in turn divided into blocks of uniform size, returned via calls to do_­allocate.
    Each call to do_­allocate(size, alignment) is dispatched to the pool serving the smallest blocks accommodating at least size bytes.
  • When a particular pool is exhausted, allocating a block from that pool results in the allocation of an additional chunk of memory from the upstream allocator (supplied at construction), thus replenishing the pool.
    With each successive replenishment, the chunk size obtained increases geometrically.
    [Note
    :
    By allocating memory in chunks, the pooling strategy increases the chance that consecutive allocations will be close together in memory.
    end note
    ]
  • Allocation requests that exceed the largest block size of any pool are fulfilled directly from the upstream allocator.
  • A pool_­options struct may be passed to the pool resource constructors to tune the largest block size and the maximum chunk size.
A synchronized_­pool_­resource may be accessed from multiple threads without external synchronization and may have thread-specific pools to reduce synchronization costs.
An unsynchronized_­pool_­resource class may not be accessed from multiple threads simultaneously and thus avoids the cost of synchronization entirely in single-threaded applications.
struct pool_options {
  size_t max_blocks_per_chunk = 0;
  size_t largest_required_pool_block = 0;
};

class synchronized_pool_resource : public memory_resource {
public:
  synchronized_pool_resource(const pool_options& opts,
                             memory_resource* upstream);

  synchronized_pool_resource()
      : synchronized_pool_resource(pool_options(), get_default_resource()) {}
  explicit synchronized_pool_resource(memory_resource* upstream)
      : synchronized_pool_resource(pool_options(), upstream) {}
  explicit synchronized_pool_resource(const pool_options& opts)
      : synchronized_pool_resource(opts, get_default_resource()) {}

  synchronized_pool_resource(const synchronized_pool_resource&) = delete;
  virtual ~synchronized_pool_resource();

  synchronized_pool_resource&
    operator=(const synchronized_pool_resource&) = delete;

  void release();
  memory_resource* upstream_resource() const;
  pool_options options() const;

protected:
  void *do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void *p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

class unsynchronized_pool_resource : public memory_resource {
public:
  unsynchronized_pool_resource(const pool_options& opts,
                               memory_resource* upstream);

  unsynchronized_pool_resource()
      : unsynchronized_pool_resource(pool_options(), get_default_resource()) {}
  explicit unsynchronized_pool_resource(memory_resource* upstream)
      : unsynchronized_pool_resource(pool_options(), upstream) {}
  explicit unsynchronized_pool_resource(const pool_options& opts)
      : unsynchronized_pool_resource(opts, get_default_resource()) {}

  unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
  virtual ~unsynchronized_pool_resource();

  unsynchronized_pool_resource&
    operator=(const unsynchronized_pool_resource&) = delete;

  void release();
  memory_resource *upstream_resource() const;
  pool_options options() const;

protected:
  void* do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void* p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

23.12.5.2 pool_­options data members [mem.res.pool.options]

The members of pool_­options comprise a set of constructor options for pool resources.
The effect of each option on the pool resource behavior is described below:
size_t max_blocks_per_chunk;
The maximum number of blocks that will be allocated at once from the upstream memory resource ([mem.res.monotonic.buffer]) to replenish a pool.
If the value of max_­blocks_­per_­chunk is zero or is greater than an implementation-defined limit, that limit is used instead.
The implementation may choose to use a smaller value than is specified in this field and may use different values for different pools.
size_t largest_required_pool_block;
The largest allocation size that is required to be fulfilled using the pooling mechanism.
Attempts to allocate a single block larger than this threshold will be allocated directly from the upstream memory resource.
If largest_­required_­pool_­block is zero or is greater than an implementation-defined limit, that limit is used instead.
The implementation may choose a pass-through threshold larger than specified in this field.

23.12.5.3 Pool resource constructors and destructors [mem.res.pool.ctor]

synchronized_pool_resource(const pool_options& opts, memory_resource* upstream); unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
Requires: upstream is the address of a valid memory resource.
Effects: Constructs a pool resource object that will obtain memory from upstream whenever the pool resource is unable to satisfy a memory request from its own internal data structures.
The resulting object will hold a copy of upstream, but will not own the resource to which upstream points.
[Note
:
The intention is that calls to upstream->allocate() will be substantially fewer than calls to this->allocate() in most cases.
end note
]
The behavior of the pooling mechanism is tuned according to the value of the opts argument.
Throws: Nothing unless upstream->allocate() throws.
It is unspecified if, or under what conditions, this constructor calls upstream->allocate().
virtual ~synchronized_pool_resource(); virtual ~unsynchronized_pool_resource();
Effects: Calls release().

23.12.5.4 Pool resource members [mem.res.pool.mem]

void release();
Effects: Calls upstream_­resource()->deallocate() as necessary to release all allocated memory.
[Note
:
The memory is released back to upstream_­resource() even if deallocate has not been called for some of the allocated blocks.
end note
]
memory_resource* upstream_resource() const;
Returns: The value of the upstream argument provided to the constructor of this object.
pool_options options() const;
Returns: The options that control the pooling behavior of this resource.
The values in the returned struct may differ from those supplied to the pool resource constructor in that values of zero will be replaced with implementation-defined defaults, and sizes may be rounded to unspecified granularity.
void* do_allocate(size_t bytes, size_t alignment) override;
Returns: A pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The size and alignment of the allocated memory shall meet the requirements for a class derived from memory_­resource ([mem.res]).
Effects: If the pool selected for a block of size bytes is unable to satisfy the memory request from its own internal data structures, it will call upstream_­resource()->allocate() to obtain more memory.
If bytes is larger than that which the largest pool can handle, then memory will be allocated using upstream_­resource()->allocate().
Throws: Nothing unless upstream_­resource()->allocate() throws.
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
Effects: Returns the memory at p to the pool.
It is unspecified if, or under what circumstances, this operation will result in a call to upstream_­resource()->deallocate().
Throws: Nothing.
bool synchronized_pool_resource::do_is_equal( const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const synchronized_­pool_­resource*>(&other).
bool unsynchronized_pool_resource::do_is_equal( const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const unsynchronized_­pool_­resource*>(&other).

23.12.6 Class monotonic_­buffer_­resource [mem.res.monotonic.buffer]

A monotonic_­buffer_­resource is a special-purpose memory resource intended for very fast memory allocations in situations where memory is used to build up a few objects and then is released all at once when the memory resource object is destroyed.
It has the following qualities:
  • A call to deallocate has no effect, thus the amount of memory consumed increases monotonically until the resource is destroyed.
  • The program can supply an initial buffer, which the allocator uses to satisfy memory requests.
  • When the initial buffer (if any) is exhausted, it obtains additional buffers from an upstream memory resource supplied at construction.
    Each additional buffer is larger than the previous one, following a geometric progression.
  • It is intended for access from one thread of control at a time.
    Specifically, calls to allocate and deallocate do not synchronize with one another.
  • It frees the allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
class monotonic_buffer_resource : public memory_resource {
  memory_resource *upstream_rsrc; // exposition only
  void *current_buffer;           // exposition only
  size_t next_buffer_size;        // exposition only

public:
  explicit monotonic_buffer_resource(memory_resource *upstream);
  monotonic_buffer_resource(size_t initial_size, memory_resource *upstream);
  monotonic_buffer_resource(void *buffer, size_t buffer_size,
                            memory_resource *upstream);

  monotonic_buffer_resource()
      : monotonic_buffer_resource(get_default_resource()) {}
  explicit monotonic_buffer_resource(size_t initial_size)
      : monotonic_buffer_resource(initial_size, get_default_resource()) {}
  monotonic_buffer_resource(void *buffer, size_t buffer_size)
      : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {}

  monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;

  virtual ~monotonic_buffer_resource();

  monotonic_buffer_resource
    operator=(const monotonic_buffer_resource&) = delete;

  void release();
  memory_resource* upstream_resource() const;

protected:
  void* do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void* p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

23.12.6.1 monotonic_­buffer_­resource constructor and destructor [mem.res.monotonic.buffer.ctor]

explicit monotonic_buffer_resource(memory_resource* upstream); monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
Requires: upstream shall be the address of a valid memory resource.
initial_­size, if specified, shall be greater than zero.
Effects: Sets upstream_­rsrc to upstream and current_­buffer to nullptr.
If initial_­size is specified, sets next_­buffer_­size to at least initial_­size; otherwise sets next_­buffer_­size to an implementation-defined size.
monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
Requires: upstream shall be the address of a valid memory resource.
buffer_­size shall be no larger than the number of bytes in buffer.
Effects: Sets upstream_­rsrc to upstream, current_­buffer to buffer, and next_­buffer_­size to buffer_­size (but not less than 1), then increases next_­buffer_­size by an implementation-defined growth factor (which need not be integral).
~monotonic_buffer_resource();
Effects: Calls release().

23.12.6.2 monotonic_­buffer_­resource members [mem.res.monotonic.buffer.mem]

void release();
Effects: Calls upstream_­rsrc->deallocate() as necessary to release all allocated memory.
[Note
:
The memory is released back to upstream_­rsrc even if some blocks that were allocated from this have not been deallocated from this.
end note
]
memory_resource* upstream_resource() const;
Returns: The value of upstream_­rsrc.
void* do_allocate(size_t bytes, size_t alignment) override;
Returns: A pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The size and alignment of the allocated memory shall meet the requirements for a class derived from memory_­resource ([mem.res]).
Effects: If the unused space in current_­buffer can fit a block with the specified bytes and alignment, then allocate the return block from current_­buffer; otherwise set current_­buffer to upstream_­rsrc->allocate(n, m), where n is not less than max(bytes, next_­buffer_­size) and m is not less than alignment, and increase next_­buffer_­size by an implementation-defined growth factor (which need not be integral), then allocate the return block from the newly-allocated current_­buffer.
Throws: Nothing unless upstream_­rsrc->allocate() throws.
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
Effects: None.
Throws: Nothing.
Remarks: Memory used by this resource increases monotonically until its destruction.
bool do_is_equal(const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const monotonic_­buffer_­resource*>(&other).

23.13 Class template scoped_­allocator_­adaptor [allocator.adaptor]

23.13.1 Header <scoped_­allocator> synopsis [allocator.adaptor.syn]

  // scoped allocator adaptor
  template <class OuterAlloc, class... InnerAlloc>
    class scoped_allocator_adaptor;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
The class template scoped_­allocator_­adaptor is an allocator template that specifies the memory resource (the outer allocator) to be used by a container (as any other allocator does) and also specifies an inner allocator resource to be passed to the constructor of every element within the container.
This adaptor is instantiated with one outer and zero or more inner allocator types.
If instantiated with only one allocator type, the inner allocator becomes the scoped_­allocator_­adaptor itself, thus using the same allocator resource for the container and every element within the container and, if the elements themselves are containers, each of their elements recursively.
If instantiated with more than one allocator, the first allocator is the outer allocator for use by the container, the second allocator is passed to the constructors of the container's elements, and, if the elements themselves are containers, the third allocator is passed to the elements' elements, and so on.
If containers are nested to a depth greater than the number of allocators, the last allocator is used repeatedly, as in the single-allocator case, for any remaining recursions.
[Note
:
The scoped_­allocator_­adaptor is derived from the outer allocator type so it can be substituted for the outer allocator type in most expressions.
end note
]
namespace std {
  template <class OuterAlloc, class... InnerAllocs>
    class scoped_allocator_adaptor : public OuterAlloc {
  private:
    using OuterTraits = allocator_traits<OuterAlloc>; // exposition only
    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
  public:
    using outer_allocator_type = OuterAlloc;
    using inner_allocator_type = see below;

    using value_type           = typename OuterTraits::value_type;
    using size_type            = typename OuterTraits::size_type;
    using difference_type      = typename OuterTraits::difference_type;
    using pointer              = typename OuterTraits::pointer;
    using const_pointer        = typename OuterTraits::const_pointer;
    using void_pointer         = typename OuterTraits::void_pointer;
    using const_void_pointer   = typename OuterTraits::const_void_pointer;

    using propagate_on_container_copy_assignment = see below;
    using propagate_on_container_move_assignment = see below;
    using propagate_on_container_swap            = see below;
    using is_always_equal                        = see below;

    template <class Tp>
      struct rebind {
        using other = scoped_allocator_adaptor<
          OuterTraits::template rebind_alloc<Tp>, InnerAllocs...>;
      };

    scoped_allocator_adaptor();
    template <class OuterA2>
      scoped_allocator_adaptor(OuterA2&& outerAlloc,
                               const InnerAllocs&... innerAllocs) noexcept;

    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;

    template <class OuterA2>
      scoped_allocator_adaptor(
        const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
    template <class OuterA2>
      scoped_allocator_adaptor(
        scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;

    scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
    scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;

    ~scoped_allocator_adaptor();

    inner_allocator_type& inner_allocator() noexcept;
    const inner_allocator_type& inner_allocator() const noexcept;
    outer_allocator_type& outer_allocator() noexcept;
    const outer_allocator_type& outer_allocator() const noexcept;

    pointer allocate(size_type n);
    pointer allocate(size_type n, const_void_pointer hint);
    void deallocate(pointer p, size_type n);
    size_type max_size() const;

    template <class T, class... Args>
      void construct(T* p, Args&&... args);
    template <class T1, class T2, class... Args1, class... Args2>
      void construct(pair<T1, T2>* p, piecewise_construct_t,
                     tuple<Args1...> x, tuple<Args2...> y);
    template <class T1, class T2>
      void construct(pair<T1, T2>* p);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, U&& x, V&& y);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, const pair<U, V>& x);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, pair<U, V>&& x);

    template <class T>
      void destroy(T* p);

    scoped_allocator_adaptor select_on_container_copy_construction() const;
  };

  template<class OuterAlloc, class... InnerAllocs>
    scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
      -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;

  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
}

23.13.2 Scoped allocator adaptor member types [allocator.adaptor.types]

using inner_allocator_type = see below;
Type: scoped_­allocator_­adaptor<OuterAlloc> if sizeof...(InnerAllocs) is zero; otherwise,
scoped_­allocator_­adaptor<InnerAllocs...>.
using propagate_on_container_copy_assignment = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­copy_­assignment​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using propagate_on_container_move_assignment = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­move_­assignment​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using propagate_on_container_swap = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­swap​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using is_always_equal = see below;
Type: true_­type if allocator_­traits<A>​::​is_­always_­equal​::​value is true for every A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.

23.13.3 Scoped allocator adaptor constructors [allocator.adaptor.cnstr]

scoped_allocator_adaptor();
Effects: Value-initializes the OuterAlloc base class and the inner allocator object.
template <class OuterA2> scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;
Effects: Initializes the OuterAlloc base class with std​::​forward<OuterA2>(outerAlloc) and inner with innerAllocs... (hence recursively initializing each allocator within the adaptor with the corresponding allocator from the argument list).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, OuterA2> is true.
scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator from other.
scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
Effects: Move constructs each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2> scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator from other.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, const OuterA2&> is true.
template <class OuterA2> scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator rvalue from other.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, OuterA2> is true.

23.13.4 Scoped allocator adaptor members [allocator.adaptor.members]

In the construct member functions, OUTERMOST(x) is x if x does not have an outer_­allocator() member function and OUTERMOST(x.outer_­allocator()) otherwise; OUTERMOST_­ALLOC_­TRAITS(x) is allocator_­traits<decltype(OUTERMOST(x))>.
[Note
:
OUTERMOST(x) and OUTERMOST_­ALLOC_­TRAITS(x) are recursive operations.
It is incumbent upon the definition of outer_­allocator() to ensure that the recursion terminates.
It will terminate for all instantiations of scoped_­allocator_­adaptor.
end note
]
inner_allocator_type& inner_allocator() noexcept; const inner_allocator_type& inner_allocator() const noexcept;
Returns: *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
outer_allocator_type& outer_allocator() noexcept;
Returns: static_­cast<OuterAlloc&>(*this).
const outer_allocator_type& outer_allocator() const noexcept;
Returns: static_­cast<const OuterAlloc&>(*this).
pointer allocate(size_type n);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n).
pointer allocate(size_type n, const_void_pointer hint);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n, hint).
void deallocate(pointer p, size_type n) noexcept;
Effects: As if by: allocator_­traits<OuterAlloc>​::​deallocate(outer_­allocator(), p, n);
size_type max_size() const;
Returns: allocator_­traits<OuterAlloc>​::​max_­size(outer_­allocator()).
template <class T, class... Args> void construct(T* p, Args&&... args);
Effects:
  • If uses_­allocator_­v<T, inner_­allocator_­type> is false and is_­constructible_­v<T,
    Args...>
    is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, allocator_­arg_­t, inner_­allocator_­type&, Args...> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, allocator_arg, inner_allocator(), std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, Args..., inner_­allocator_­type&> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)..., inner_allocator())
  • Otherwise, the program is ill-formed.
    [Note
    :
    An error will result if uses_­allocator evaluates to true but the specific constructor does not take an allocator.
    This definition prevents a silent failure to pass an inner allocator to a contained element.
    end note
    ]
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
Requires: all of the types in Args1 and Args2 shall be CopyConstructible (Table 24).
Effects: Constructs a tuple object xprime from x by the following rules:
  • If uses_­allocator_­v<T1, inner_­allocator_­type> is false and is_­constructible_­v<T1,
    Args1...>
    is true, then xprime is x.
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, allocator_­arg_­t, inner_­allocator_­type&, Args1...> is true, then xprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(x))
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, Args1..., inner_­allocator_­type&> is true, then xprime is:
    tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
and constructs a tuple object yprime from y by the following rules:
  • If uses_­allocator_­v<T2, inner_­allocator_­type> is false and is_­constructible_­v<T2,
    Args2...>
    is true, then yprime is y.
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, allocator_­arg_­t, inner_­allocator_­type&, Args2...> is true, then yprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(y))
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, Args2..., inner_­allocator_­type&> is true, then yprime is:
    tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
then calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct(
    OUTERMOST(*this), p, piecewise_construct, std::move(xprime), std::move(yprime))
template <class T1, class T2> void construct(pair<T1, T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x)),
          forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, const pair<U, V>& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(x.first),
          forward_as_tuple(x.second));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x.first)),
          forward_as_tuple(std::forward<V>(x.second)));
template <class T> void destroy(T* p);
Effects: Calls OUTERMOST_­ALLOC_­TRAITS(*this)​::​destroy(OUTERMOST(*this), p).
scoped_allocator_adaptor select_on_container_copy_construction() const;
Returns: A new scoped_­allocator_­adaptor object where each allocator A in the adaptor is initialized from the result of calling allocator_­traits<A>​::​select_­on_­container_­copy_­construction() on the corresponding allocator in *this.

23.13.5 Scoped allocator operators [scoped.adaptor.operators]

template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: If sizeof...(InnerAllocs) is zero,
a.outer_allocator() == b.outer_allocator()
otherwise
a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: !(a == b).

23.14 Function objects [function.objects]

A function object type is an object type ([basic.types]) that can be the type of the postfix-expression in a function call ([expr.call], [over.match.call]).222
A function object is an object of a function object type.
In the places where one would expect to pass a pointer to a function to an algorithmic template (Clause [algorithms]), the interface is specified to accept a function object.
This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects.
Such a type is a function pointer or a class type which has a member operator() or a class type which has a conversion to a pointer to function.

23.14.1 Header <functional> synopsis [functional.syn]

namespace std {
  // [func.invoke], invoke
  template <class F, class... Args>
    invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
      noexcept(is_nothrow_invocable_v<F, Args...>);

  // [refwrap], reference_­wrapper
  template <class T> class reference_wrapper;

  template <class T> reference_wrapper<T> ref(T&) noexcept;
  template <class T> reference_wrapper<const T> cref(const T&) noexcept;
  template <class T> void ref(const T&&) = delete;
  template <class T> void cref(const T&&) = delete;

  template <class T> reference_wrapper<T> ref(reference_wrapper<T>) noexcept;
  template <class T> reference_wrapper<const T> cref(reference_wrapper<T>) noexcept;

  // [arithmetic.operations], arithmetic operations
  template <class T = void> struct plus;
  template <class T = void> struct minus;
  template <class T = void> struct multiplies;
  template <class T = void> struct divides;
  template <class T = void> struct modulus;
  template <class T = void> struct negate;
  template <> struct plus<void>;
  template <> struct minus<void>;
  template <> struct multiplies<void>;
  template <> struct divides<void>;
  template <> struct modulus<void>;
  template <> struct negate<void>;

  // [comparisons], comparisons
  template <class T = void> struct equal_to;
  template <class T = void> struct not_equal_to;
  template <class T = void> struct greater;
  template <class T = void> struct less;
  template <class T = void> struct greater_equal;
  template <class T = void> struct less_equal;
  template <> struct equal_to<void>;
  template <> struct not_equal_to<void>;
  template <> struct greater<void>;
  template <> struct less<void>;
  template <> struct greater_equal<void>;
  template <> struct less_equal<void>;

  // [logical.operations], logical operations
  template <class T = void> struct logical_and;
  template <class T = void> struct logical_or;
  template <class T = void> struct logical_not;
  template <> struct logical_and<void>;
  template <> struct logical_or<void>;
  template <> struct logical_not<void>;

  // [bitwise.operations], bitwise operations
  template <class T = void> struct bit_and;
  template <class T = void> struct bit_or;
  template <class T = void> struct bit_xor;
  template <class T = void> struct bit_not;
  template <> struct bit_and<void>;
  template <> struct bit_or<void>;
  template <> struct bit_xor<void>;
  template <> struct bit_not<void>;

  // [func.not_fn], function template not_­fn
  template <class F>
    unspecified not_fn(F&& f);

  // [func.bind], bind
  template<class T> struct is_bind_expression;
  template<class T> struct is_placeholder;

  template<class F, class... BoundArgs>
    unspecified bind(F&&, BoundArgs&&...);
  template<class R, class F, class... BoundArgs>
    unspecified bind(F&&, BoundArgs&&...);

  namespace placeholders {
    // M is the implementation-defined number of placeholders
    see below _1;
    see below _2;
               .
               .
               .
    see below _M;
  }

  // [func.memfn], member function adaptors
  template<class R, class T>
    unspecified mem_fn(R T::*) noexcept;

  // [func.wrap], polymorphic function wrappers
  class bad_function_call;

  template<class> class function; // not defined
  template<class R, class... ArgTypes> class function<R(ArgTypes...)>;

  template<class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;

  template<class R, class... ArgTypes>
    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
  template<class R, class... ArgTypes>
    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
  template<class R, class... ArgTypes>
    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
  template<class R, class... ArgTypes>
    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  // [func.search], searchers
  template<class ForwardIterator, class BinaryPredicate = equal_to<>>
    class default_searcher;

  template<class RandomAccessIterator,
           class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
           class BinaryPredicate = equal_to<>>
    class boyer_moore_searcher;

  template<class RandomAccessIterator,
           class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
           class BinaryPredicate = equal_to<>>
    class boyer_moore_horspool_searcher;

  // [unord.hash], hash function primary template
  template <class T>
    struct hash;

  // [func.bind], function object binders
  template <class T>
    inline constexpr bool is_bind_expression_v = is_bind_expression<T>::value;
  template <class T>
    inline constexpr int is_placeholder_v = is_placeholder<T>::value;
}
[Example
:
If a C++ program wants to have a by-element addition of two vectors a and b containing double and put the result into a, it can do:
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
end example
]
[Example
:
To negate every element of a:
transform(a.begin(), a.end(), a.begin(), negate<double>());
end example
]

23.14.2 Definitions [func.def]

The following definitions apply to this Clause:
A call signature is the name of a return type followed by a parenthesized comma-separated list of zero or more argument types.
A callable type is a function object type ([function.objects]) or a pointer to member.
A callable object is an object of a callable type.
A call wrapper type is a type that holds a callable object and supports a call operation that forwards to that object.
A call wrapper is an object of a call wrapper type.
A target object is the callable object held by a call wrapper.

23.14.3 Requirements [func.require]

Define INVOKE(f, t1, t2, ..., tN) as follows:
  • (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and is_­base_­of_­v<T, decay_­t<decltype(t1)>> is true;
  • (t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of a class T and decay_­t<decltype(t1)> is a specialization of reference_­wrapper;
  • ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;
  • t1.*f when N == 1 and f is a pointer to data member of a class T and is_­base_­of_­v<T, decay_­t<decltype(t1)>> is true;
  • t1.get().*f when N == 1 and f is a pointer to data member of a class T and decay_­t<decltype(t1)> is a specialization of reference_­wrapper;
  • (*t1).*f when N == 1 and f is a pointer to data member of a class T and t1 does not satisfy the previous two items;
  • f(t1, t2, ..., tN) in all other cases.
Define INVOKE<R>(f, t1, t2, ..., tN) as static_­cast<void>(INVOKE(f, t1, t2, ..., tN)) if R is cv void, otherwise INVOKE(f, t1, t2, ..., tN) implicitly converted to R.
Every call wrapper ([func.def]) shall be MoveConstructible.
A forwarding call wrapper is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the wrapped callable object as references.
This forwarding step shall ensure that rvalue arguments are delivered as rvalue references and lvalue arguments are delivered as lvalue references.
A simple call wrapper is a forwarding call wrapper that is CopyConstructible and CopyAssignable and whose copy constructor, move constructor, and assignment operator do not throw exceptions.
[Note
:
In a typical implementation forwarding call wrappers have an overloaded function call operator of the form
template<class... UnBoundArgs>
R operator()(UnBoundArgs&&... unbound_args) cv-qual;
end note
]

23.14.4 Function template invoke [func.invoke]

template <class F, class... Args> invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v<F, Args...>);
Returns: INVOKE(std​::​forward<F>(f), std​::​forward<Args>(args)...) ([func.require]).

23.14.5 Class template reference_­wrapper [refwrap]

namespace std {
  template <class T> class reference_wrapper {
  public :
    // types
    using type = T;

    // construct/copy/destroy
    reference_wrapper(T&) noexcept;
    reference_wrapper(T&&) = delete;     // do not bind to temporary objects
    reference_wrapper(const reference_wrapper& x) noexcept;

    // assignment
    reference_wrapper& operator=(const reference_wrapper& x) noexcept;

    // access
    operator T& () const noexcept;
    T& get() const noexcept;

    // invocation
    template <class... ArgTypes>
      invoke_result_t<T&, ArgTypes...>
      operator() (ArgTypes&&...) const;
  };

  template<class T>
    reference_wrapper(reference_wrapper<T>) -> reference_wrapper<T>;
}
reference_­wrapper<T> is a CopyConstructible and CopyAssignable wrapper around a reference to an object or function of type T.
reference_­wrapper<T> shall be a trivially copyable type ([basic.types]).

23.14.5.1 reference_­wrapper construct/copy/destroy [refwrap.const]

reference_wrapper(T& t) noexcept;
Effects: Constructs a reference_­wrapper object that stores a reference to t.
reference_wrapper(const reference_wrapper& x) noexcept;
Effects: Constructs a reference_­wrapper object that stores a reference to x.get().

23.14.5.2 reference_­wrapper assignment [refwrap.assign]

reference_wrapper& operator=(const reference_wrapper& x) noexcept;
Postconditions: *this stores a reference to x.get().

23.14.5.3 reference_­wrapper access [refwrap.access]

operator T& () const noexcept;
Returns: The stored reference.
T& get() const noexcept;
Returns: The stored reference.

23.14.5.4 reference_­wrapper invocation [refwrap.invoke]

template <class... ArgTypes> invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&... args) const;
Returns: INVOKE(get(), std​::​forward<ArgTypes>(args)...).

23.14.5.5 reference_­wrapper helper functions [refwrap.helpers]

template <class T> reference_wrapper<T> ref(T& t) noexcept;
Returns: reference_­wrapper<T>(t).
template <class T> reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
Returns: ref(t.get()).
template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
Returns: reference_­wrapper <const T>(t).
template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
Returns: cref(t.get()).

23.14.6 Arithmetic operations [arithmetic.operations]

The library provides basic function object classes for all of the arithmetic operators in the language ([expr.mul], [expr.add]).

23.14.6.1 Class template plus [arithmetic.operations.plus]

template <class T = void> struct plus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x + y.
template <> struct plus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u));
Returns: std​::​forward<T>(t) + std​::​forward<U>(u).

23.14.6.2 Class template minus [arithmetic.operations.minus]

template <class T = void> struct minus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x - y.
template <> struct minus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u));
Returns: std​::​forward<T>(t) - std​::​forward<U>(u).

23.14.6.3 Class template multiplies [arithmetic.operations.multiplies]

template <class T = void> struct multiplies { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x * y.
template <> struct multiplies<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u));
Returns: std​::​forward<T>(t) * std​::​forward<U>(u).

23.14.6.4 Class template divides [arithmetic.operations.divides]

template <class T = void> struct divides { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x / y.
template <> struct divides<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u));
Returns: std​::​forward<T>(t) / std​::​forward<U>(u).

23.14.6.5 Class template modulus [arithmetic.operations.modulus]

template <class T = void> struct modulus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x % y.
template <> struct modulus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u));
Returns: std​::​forward<T>(t) % std​::​forward<U>(u).

23.14.6.6 Class template negate [arithmetic.operations.negate]

template <class T = void> struct negate { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: -x.
template <> struct negate<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t));
Returns: -std​::​forward<T>(t).

23.14.7 Comparisons [comparisons]

The library provides basic function object classes for all of the comparison operators in the language ([expr.rel], [expr.eq]).
For templates less, greater, less_­equal, and greater_­equal, the specializations for any pointer type yield a strict total order that is consistent among those specializations and is also consistent with the partial order imposed by the built-in operators <, >, <=, >=.
[Note
:
When a < b is well-defined for pointers a and b of type P, this implies (a < b) == less<P>(a, b), (a > b) == greater<P>(a, b), and so forth.
end note
]
For template specializations less<void>, greater<void>, less_­equal<void>, and greater_­equal<void>, if the call operator calls a built-in operator comparing pointers, the call operator yields a strict total order that is consistent among those specializations and is also consistent with the partial order imposed by those built-in operators.

23.14.7.1 Class template equal_­to [comparisons.equal_to]

template <class T = void> struct equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x == y.
template <> struct equal_to<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u));
Returns: std​::​forward<T>(t) == std​::​forward<U>(u).

23.14.7.2 Class template not_­equal_­to [comparisons.not_equal_to]

template <class T = void> struct not_equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x != y.
template <> struct not_equal_to<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u));
Returns: std​::​forward<T>(t) != std​::​forward<U>(u).

23.14.7.3 Class template greater [comparisons.greater]

template <class T = void> struct greater { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x > y.
template <> struct greater<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u));
Returns: std​::​forward<T>(t) > std​::​forward<U>(u).

23.14.7.4 Class template less [comparisons.less]

template <class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x < y.
template <> struct less<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u));
Returns: std​::​forward<T>(t) < std​::​forward<U>(u).

23.14.7.5 Class template greater_­equal [comparisons.greater_equal]

template <class T = void> struct greater_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x >= y.
template <> struct greater_equal<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u));
Returns: std​::​forward<T>(t) >= std​::​forward<U>(u).

23.14.7.6 Class template less_­equal [comparisons.less_equal]

template <class T = void> struct less_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x <= y.
template <> struct less_equal<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u));
Returns: std​::​forward<T>(t) <= std​::​forward<U>(u).

23.14.8 Logical operations [logical.operations]

The library provides basic function object classes for all of the logical operators in the language ([expr.log.and], [expr.log.or], [expr.unary.op]).

23.14.8.1 Class template logical_­and [logical.operations.and]

template <class T = void> struct logical_and { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x && y.
template <> struct logical_and<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u));
Returns: std​::​forward<T>(t) && std​::​forward<U>(u).

23.14.8.2 Class template logical_­or [logical.operations.or]

template <class T = void> struct logical_or { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x || y.
template <> struct logical_or<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u));
Returns: std​::​forward<T>(t) || std​::​forward<U>(u).

23.14.8.3 Class template logical_­not [logical.operations.not]

template <class T = void> struct logical_not { constexpr bool operator()(const T& x) const; };
constexpr bool operator()(const T& x) const;
Returns: !x.
template <> struct logical_not<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t));
Returns: !std​::​forward<T>(t).

23.14.9 Bitwise operations [bitwise.operations]

The library provides basic function object classes for all of the bitwise operators in the language ([expr.bit.and], [expr.or], [expr.xor], [expr.unary.op]).

23.14.9.1 Class template bit_­and [bitwise.operations.and]

template <class T = void> struct bit_and { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x & y.
template <> struct bit_and<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u));
Returns: std​::​forward<T>(t) & std​::​forward<U>(u).

23.14.9.2 Class template bit_­or [bitwise.operations.or]

template <class T = void> struct bit_or { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x | y.
template <> struct bit_or<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u));
Returns: std​::​forward<T>(t) | std​::​forward<U>(u).

23.14.9.3 Class template bit_­xor [bitwise.operations.xor]

template <class T = void> struct bit_xor { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x ^ y.
template <> struct bit_xor<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u));
Returns: std​::​forward<T>(t) ^ std​::​forward<U>(u).

23.14.9.4 Class template bit_­not [bitwise.operations.not]

template <class T = void> struct bit_not { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: ~x.
template <> struct bit_not<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(~std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&&) const -> decltype(~std::forward<T>(t));
Returns: ~std​::​forward<T>(t).

23.14.10 Function template not_­fn [func.not_fn]

template <class F> unspecified not_fn(F&& f);
Effects: Equivalent to return call_­wrapper(std​::​forward<F>(f)); where call_­wrapper is an exposition only class defined as follows:
class call_wrapper {
  using FD = decay_t<F>;
  FD fd;

  explicit call_wrapper(F&& f);

public:
  call_wrapper(call_wrapper&&) = default;
  call_wrapper(const call_wrapper&) = default;

  template<class... Args>
    auto operator()(Args&&...) &
      -> decltype(!declval<invoke_result_t<FD&, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) const&
      -> decltype(!declval<invoke_result_t<const FD&, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) &&
      -> decltype(!declval<invoke_result_t<FD, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) const&&
      -> decltype(!declval<invoke_result_t<const FD, Args...>>());
};
explicit call_wrapper(F&& f);
Requires: FD shall satisfy the requirements of MoveConstructible.
is_­constructible_­v<FD, F> shall be true.
fd shall be a callable object ([func.def]).
Effects: Initializes fd from std​::​forward<F>(f).
Throws: Any exception thrown by construction of fd.
template<class... Args> auto operator()(Args&&... args) & -> decltype(!declval<invoke_result_t<FD&, Args...>>()); template<class... Args> auto operator()(Args&&... args) const& -> decltype(!declval<invoke_result_t<const FD&, Args...>>());
Effects: Equivalent to:
return !INVOKE(fd, std::forward<Args>(args)...);              // see [func.require]
template<class... Args> auto operator()(Args&&... args) && -> decltype(!declval<invoke_result_t<FD, Args...>>()); template<class... Args> auto operator()(Args&&... args) const&& -> decltype(!declval<invoke_result_t<const FD, Args...>>());
Effects: Equivalent to:
return !INVOKE(std::move(fd), std::forward<Args>(args)...);   // see [func.require]

23.14.11 Function object binders [func.bind]

This subclause describes a uniform mechanism for binding arguments of callable objects.

23.14.11.1 Class template is_­bind_­expression [func.bind.isbind]

namespace std {
  template<class T> struct is_bind_expression;  // see below
}
The class template is_­bind_­expression can be used to detect function objects generated by bind.
The function template bind uses is_­bind_­expression to detect subexpressions.
Instantiations of the is_­bind_­expression template shall meet the UnaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that has a base characteristic of true_­type if T is a type returned from bind, otherwise it shall have a base characteristic of false_­type.
A program may specialize this template for a user-defined type T to have a base characteristic of true_­type to indicate that T should be treated as a subexpression in a bind call.

23.14.11.2 Class template is_­placeholder [func.bind.isplace]

namespace std {
  template<class T> struct is_placeholder;      // see below
}
The class template is_­placeholder can be used to detect the standard placeholders _­1, _­2, and so on.
The function template bind uses is_­placeholder to detect placeholders.
Instantiations of the is_­placeholder template shall meet the UnaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that has the base characteristic of integral_­constant<int, J> if T is the type of std​::​placeholders​::​_­J, otherwise it shall have a base characteristic of integral_­constant<int, 0>.
A program may specialize this template for a user-defined type T to have a base characteristic of integral_­constant<int, N> with N > 0 to indicate that T should be treated as a placeholder type.

23.14.11.3 Function template bind [func.bind.bind]

In the text that follows:
  • FD is the type decay_­t<F>,
  • fd is an lvalue of type FD constructed from std​::​forward<F>(f),
  • T is the type in the template parameter pack BoundArgs,
  • TD is the type decay_­t<T>,
  • t is the argument in the function parameter pack bound_­args,
  • td is an lvalue of type TD constructed from std​::​forward<T>(t),
  • U is the deduced type of the UnBoundArgs&&... parameter of the forwarding call wrapper, and
  • u is the argument associated with U.
template<class F, class... BoundArgs> unspecified bind(F&& f, BoundArgs&&... bound_args);
Requires: is_­constructible_­v<FD, F> shall be true.
For each T in BoundArgs, is_­constructible_­v<TD, T> shall be true.
INVOKE(fd, w, w, …, w) ([func.require]) shall be a valid expression for some values w, w, …, w, where N has the value sizeof...(bound_­args).
The cv-qualifiers cv of the call wrapper g, as specified below, shall be neither volatile nor const volatile.
Returns: A forwarding call wrapper g ([func.require]).
The effect of g(u, u, …, u) shall be
INVOKE(fd, std::forward<V>(v), std::forward<V>(v), …, std::forward<V>(v))
where the values and types of the bound arguments v, v, …, v are determined as specified below.
The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types TD throws an exception.
Throws: Nothing unless the construction of fd or of one of the values td throws an exception.
Remarks: The return type shall satisfy the requirements of MoveConstructible.
If all of FD and TD satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible.
[Note
:
This implies that all of FD and TD are MoveConstructible.
end note
]
template<class R, class F, class... BoundArgs> unspecified bind(F&& f, BoundArgs&&... bound_args);
Requires: is_­constructible_­v<FD, F> shall be true.
For each T in BoundArgs, is_­constructible_­v<TD, T> shall be true.
INVOKE(fd, w, w, …, w) shall be a valid expression for some values w, w, …, w, where N has the value sizeof...(bound_­args).
The cv-qualifiers cv of the call wrapper g, as specified below, shall be neither volatile nor const volatile.
Returns: A forwarding call wrapper g ([func.require]).
The effect of g(u, u, …, u) shall be
INVOKE<R>(fd, std::forward<V>(v), std::forward<V>(v), …, std::forward<V>(v))
where the values and types of the bound arguments v, v, …, v are determined as specified below.
The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types TD throws an exception.
Throws: Nothing unless the construction of fd or of one of the values td throws an exception.
Remarks: The return type shall satisfy the requirements of MoveConstructible.
If all of FD and TD satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible.
[Note
:
This implies that all of FD and TD are MoveConstructible.
end note
]
The values of the bound arguments v, v, …, v and their corresponding types V, V, …, V depend on the types TD derived from the call to bind and the cv-qualifiers cv of the call wrapper g as follows:
  • if TD is reference_­wrapper<T>, the argument is td.get() and its type V is T&;
  • if the value of is_­bind_­expression_­v<TD> is true, the argument is td(std​::​forward<U>(u)...) and its type V is invoke_­result_­t<TD cv &, U...>&&;
  • if the value j of is_­placeholder_­v<TD> is not zero, the argument is std​::​forward<U>(u) and its type V is U&&;
  • otherwise, the value is td and its type V is TD cv &.

23.14.11.4 Placeholders [func.bind.place]

namespace std::placeholders {
  // M is the implementation-defined number of placeholders
  see below _1;
  see below _2;
              .
              .
              .
  see below _M;
}
All placeholder types shall be DefaultConstructible and CopyConstructible, and their default constructors and copy/move constructors shall not throw exceptions.
It is implementation-defined whether placeholder types are CopyAssignable.
CopyAssignable placeholders' copy assignment operators shall not throw exceptions.
Placeholders should be defined as:
inline constexpr unspecified _1{};
If they are not, they shall be declared as:
extern unspecified _1;

23.14.12 Function template mem_­fn [func.memfn]

template<class R, class T> unspecified mem_fn(R T::* pm) noexcept;
Returns: A simple call wrapper ([func.def]) fn such that the expression fn(t, a2, ..., aN) is equivalent to INVOKE(pm, t, a2, ..., aN) ([func.require]).

23.14.13 Polymorphic function wrappers [func.wrap]

This subclause describes a polymorphic wrapper class that encapsulates arbitrary callable objects.

23.14.13.1 Class bad_­function_­call [func.wrap.badcall]

An exception of type bad_­function_­call is thrown by function​::​operator() ([func.wrap.func.inv]) when the function wrapper object has no target.
namespace std {
  class bad_function_call : public exception {
  public:
    // [func.wrap.badcall.const], constructor
    bad_function_call() noexcept;
  };
}

23.14.13.1.1 bad_­function_­call constructor [func.wrap.badcall.const]

bad_function_call() noexcept;
Effects: Constructs a bad_­function_­call object.
Postconditions: what() returns an implementation-defined ntbs.

23.14.13.2 Class template function [func.wrap.func]

namespace std {
  template<class> class function; // not defined

  template<class R, class... ArgTypes>
  class function<R(ArgTypes...)> {
  public:
    using result_type = R;

    // [func.wrap.func.con], construct/copy/destroy
    function() noexcept;
    function(nullptr_t) noexcept;
    function(const function&);
    function(function&&);
    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], function modifiers
    void swap(function&) noexcept;

    // [func.wrap.func.cap], function capacity
    explicit operator bool() const noexcept;

    // [func.wrap.func.inv], function invocation
    R operator()(ArgTypes...) const;

    // [func.wrap.func.targ], function target access
    const 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>;

  // [func.wrap.func.nullptr], Null pointer comparisons
  template <class R, class... ArgTypes>
    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;

  template <class R, class... ArgTypes>
    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  template <class R, class... ArgTypes>
    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;

  template <class R, class... ArgTypes>
    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  // [func.wrap.func.alg], specialized algorithms
  template <class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
}
The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects ([func.def]), given a call signature ([func.def]), allowing functions to be first-class objects.
A callable type ([func.def]) F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand (Clause [expr]), is well formed ([func.require]).
The function class template is a call wrapper ([func.def]) whose call signature ([func.def]) is R(ArgTypes...).
[Note
:
The types deduced by the deduction guides for function may change in future versions of this International Standard.
end note
]

23.14.13.2.1 function construct/copy/destroy [func.wrap.func.con]

function() noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
Postconditions: !*this if !f; otherwise, *this targets a copy of f.target().
Throws: shall not throw exceptions if f's target is a specialization of reference_­wrapper or a function pointer.
Otherwise, may throw bad_­alloc or any exception thrown by the copy constructor of the stored callable object.
[Note
:
Implementations are encouraged to 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.
end note
]
function(function&& f);
Postconditions: If !f, *this has no target; otherwise, the target of *this is equivalent to the target of f before the construction, and f is in a valid state with an unspecified value.
Throws: shall not throw exceptions if f's target is a specialization of reference_­wrapper or a function pointer.
Otherwise, may throw bad_­alloc or any exception thrown by the copy or move constructor of the stored callable object.
[Note
:
Implementations are encouraged to 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.
end note
]
template<class F> function(F f);
Requires: F shall be CopyConstructible.
Remarks: This constructor template shall not participate in overload resolution unless F is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Postconditions: !*this if any of the following hold:
  • f is a null function pointer value.
  • f is a null member pointer value.
  • F is an instance of the function class template, and !f.
Otherwise, *this targets a copy of f initialized with std​::​move(f).
[Note
:
Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f is an object holding only a pointer or reference to an object and a member function pointer.
end note
]
Throws: shall not throw exceptions when f is a function pointer or a reference_­wrapper<T> for some T.
Otherwise, may throw bad_­alloc or any exception thrown by F's copy or move constructor.
template<class F> function(F) -> function<see below>;
Remarks: This deduction guide participates in overload resolution only if &F​::​operator() is well-formed when treated as an unevaluated operand.
In that case, if decltype(&F​::​operator()) is of the form R(G​::​*)(A...) cv & noexcept for a class type G, then the deduced type is function<R(A...)>.
[Example
:
void f() {
  int i{5};
  function g = [&](double) { return i; }; // deduces function<int(double)>
}
end example
]
function& operator=(const function& f);
Effects: As if by function(f).swap(*this);
Returns: *this.
function& operator=(function&& f);
Effects: Replaces the target of *this with the target of f.
Returns: *this.
function& operator=(nullptr_t) noexcept;
Effects: If *this != nullptr, destroys the target of this.
Postconditions: !(*this).
Returns: *this.
template<class F> function& operator=(F&& f);
Effects: As if by: function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
Remarks: This assignment operator shall not participate in overload resolution unless decay_­t<F> is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
Effects: As if by: function(f).swap(*this);
Returns: *this.
~function();
Effects: If *this != nullptr, destroys the target of this.

23.14.13.2.2 function modifiers [func.wrap.func.mod]

void swap(function& other) noexcept;
Effects: interchanges the targets of *this and other.

23.14.13.2.3 function capacity [func.wrap.func.cap]

explicit operator bool() const noexcept;
Returns: true if *this has a target, otherwise false.

23.14.13.2.4 function invocation [func.wrap.func.inv]

R operator()(ArgTypes... args) const;
Returns: INVOKE<R>(f, std​::​forward<ArgTypes>(args)...) ([func.require]), where f is the target object ([func.def]) of *this.
Throws: bad_­function_­call if !*this; otherwise, any exception thrown by the wrapped callable object.

23.14.13.2.5 function target access [func.wrap.func.targ]

const type_info& target_type() const noexcept;
Returns: If *this has a target of type T, typeid(T); otherwise, typeid(void).
template<class T> T* target() noexcept; template<class T> const T* target() const noexcept;
Returns: If target_­type() == typeid(T) a pointer to the stored function target; otherwise a null pointer.

23.14.13.2.6 null pointer comparison functions [func.wrap.func.nullptr]

template <class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept; template <class R, class... ArgTypes> bool operator==(nullptr_t, const function<R(ArgTypes...)>& f) noexcept;
Returns: !f.
template <class R, class... ArgTypes> bool operator!=(const function<R(ArgTypes...)>& f, nullptr_t) noexcept; template <class R, class... ArgTypes> bool operator!=(nullptr_t, const function<R(ArgTypes...)>& f) noexcept;
Returns: (bool)f.

23.14.13.2.7 specialized algorithms [func.wrap.func.alg]

template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
Effects: As if by: f1.swap(f2);

23.14.14 Searchers [func.search]

This subclause provides function object types ([function.objects]) for operations that search for a sequence [pat_first, pat_­last) in another sequence [first, last) that is provided to the object's function call operator.
The first sequence (the pattern to be searched for) is provided to the object's constructor, and the second (the sequence to be searched) is provided to the function call operator.
Each specialization of a class template specified in this subclause [func.search] shall meet the CopyConstructible and CopyAssignable requirements.
Template parameters named of templates specified in this subclause [func.search] shall meet the same requirements and semantics as specified in [algorithms.general].
Template parameters named Hash shall meet the requirements as specified in [hash.requirements].
The Boyer-Moore searcher implements the Boyer-Moore search algorithm.
The Boyer-Moore-Horspool searcher implements the Boyer-Moore-Horspool search algorithm.
In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool.

23.14.14.1 Class template default_­searcher [func.search.default]

template <class ForwardIterator1, class BinaryPredicate = equal_to<>>
  class default_searcher {
  public:
    default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last,
                     BinaryPredicate pred = BinaryPredicate());

    template <class ForwardIterator2>
      pair<ForwardIterator2, ForwardIterator2>
        operator()(ForwardIterator2 first, ForwardIterator2 last) const;

  private:
    ForwardIterator1 pat_first_;        // exposition only
    ForwardIterator1 pat_last_;         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, BinaryPredicate pred = BinaryPredicate());
Effects: Constructs a default_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of BinaryPredicate or ForwardIterator1.
template<class ForwardIterator2> pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const;
Effects: Returns a pair of iterators i and j such that
  • i == search(first, last, pat_­first_­, pat_­last_­, pred_­), and
  • if i == last, then j == last, otherwise j == next(i, distance(pat_­first_­, pat_­last_­)).

23.14.14.2 Class template boyer_­moore_­searcher [func.search.bm]

template <class RandomAccessIterator1,
          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
          class BinaryPredicate = equal_to<>>
  class boyer_moore_searcher {
  public:
    boyer_moore_searcher(RandomAccessIterator1 pat_first,
                         RandomAccessIterator1 pat_last,
                         Hash hf = Hash(),
                         BinaryPredicate pred = BinaryPredicate());

    template <class RandomAccessIterator2>
      pair<RandomAccessIterator2, RandomAccessIterator2>
        operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;

  private:
    RandomAccessIterator1 pat_first_;   // exposition only
    RandomAccessIterator1 pat_last_;    // exposition only
    Hash hash_;                         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Requires: The value type of RandomAccessIterator1 shall meet the DefaultConstructible requirements, the CopyConstructible requirements, and the CopyAssignable requirements.
Requires: For any two values A and B of the type iterator_­traits<RandomAccessIterator1>​::​value_­type, if pred(A, B) == true, then hf(A) == hf(B) shall be true.
Effects: Constructs a boyer_­moore_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, hash_­ with hf, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1, or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_­alloc if additional memory needed for internal data structures cannot be allocated.
template <class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Requires: RandomAccessIterator1 and RandomAccessIterator2 shall have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator in the range [first, last - (pat_­last_­ - pat_­first_­)) such that for every non-negative integer n less than pat_­last_­ - pat_­first_­ the following condition holds: pred(*(i + n), *(pat_­first_­ + n)) != false, and
  • j == next(i, distance(pat_­first_­, pat_­last_­)).
Returns make_­pair(first, first) if [pat_­first_­, pat_­last_­) is empty, otherwise returns make_­pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_­last_­ - pat_­first_­) applications of the predicate.

23.14.14.3 Class template boyer_­moore_­horspool_­searcher [func.search.bmh]

template <class RandomAccessIterator1,
          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
          class BinaryPredicate = equal_to<>>
  class boyer_moore_horspool_searcher {
  public:
    boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first,
                                  RandomAccessIterator1 pat_last,
                                  Hash hf = Hash(),
                                  BinaryPredicate pred = BinaryPredicate());

    template <class RandomAccessIterator2>
      pair<RandomAccessIterator2, RandomAccessIterator2>
        operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;

  private:
    RandomAccessIterator1 pat_first_;   // exposition only
    RandomAccessIterator1 pat_last_;    // exposition only
    Hash hash_;                         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Requires: The value type of RandomAccessIterator1 shall meet the DefaultConstructible, CopyConstructible, and CopyAssignable requirements.
Requires: For any two values A and B of the type iterator_­traits<RandomAccessIterator1>​::​value_­type, if pred(A, B) == true, then hf(A) == hf(B) shall be true.
Effects: Constructs a boyer_­moore_­horspool_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, hash_­ with hf, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1 or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_­alloc if additional memory needed for internal data structures cannot be allocated.
template <class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Requires: RandomAccessIterator1 and RandomAccessIterator2 shall have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator i in the range [first, last - (pat_­last_­ - pat_­first_­)) such that for every non-negative integer n less than pat_­last_­ - pat_­first_­ the following condition holds: pred(*(i + n), *(pat_­first_­ + n)) != false, and
  • j == next(i, distance(pat_­first_­, pat_­last_­)).
Returns make_­pair(first, first) if [pat_­first_­, pat_­last_­) is empty, otherwise returns make_­pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_­last_­ - pat_­first_­) applications of the predicate.

23.14.15 Class template hash [unord.hash]

The unordered associative containers defined in [unord] use specializations of the class template hash ([functional.syn]) as the default hash function.
Each specialization of hash is either enabled or disabled, as described below.
[Note
:
Enabled specializations meet the requirements of Hash, and disabled specializations do not.
end note
]
Each header that declares the template hash provides enabled specializations of hash for nullptr_­t and all cv-unqualified arithmetic, enumeration, and pointer types.
For any type Key for which neither the library nor the user provides an explicit or partial specialization of the class template hash, hash<Key> is disabled.
If the library provides an explicit or partial specialization of hash<Key>, that specialization is enabled except as noted otherwise, and its member functions are noexcept except as noted otherwise.
If H is a disabled specialization of hash, these values are false: is_­default_­constructible_­v<H>, is_­copy_­constructible_­v<H>, is_­move_­constructible_­v<H>, is_­copy_­assignable_­v<H>, and is_­move_­assignable_­v<H>.
Disabled specializations of hash are not function object types ([function.objects]).
[Note
:
This means that the specialization of hash exists, but any attempts to use it as a Hash will be ill-formed.
end note
]
An enabled specialization hash<Key> will:
  • satisfy the Hash requirements ([hash.requirements]), with Key as the function call argument type, the DefaultConstructible requirements (Table 22), the CopyAssignable requirements (Table 26),
  • be swappable ([swappable.requirements]) for lvalues,
  • satisfy the requirement that if k1 == k2 is true, h(k1) == h(k2) is also true, where h is an object of type hash<Key> and k1 and k2 are objects of type Key;
  • satisfy the requirement that the expression h(k), where h is an object of type hash<Key> and k is an object of type Key, shall not throw an exception unless hash<Key> is a user-defined specialization that depends on at least one user-defined type.

23.15 Metaprogramming and type traits [meta]

This subclause describes components used by C++ programs, particularly in templates, to support the widest possible range of types, optimise template code usage, detect type related user errors, and perform type inference and transformation at compile time.
It includes type classification traits, type property inspection traits, and type transformations.
The type classification traits describe a complete taxonomy of all possible C++ types, and state where in that taxonomy a given type belongs.
The type property inspection traits allow important characteristics of types or of combinations of types to be inspected.
The type transformations allow certain properties of types to be manipulated.
All functions specified in this subclause are signal-safe ([csignal.syn]).

23.15.1 Requirements [meta.rqmts]

A UnaryTypeTrait describes a property of a type.
It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described.
It shall be DefaultConstructible, CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its base characteristic, which is a specialization of the template integral_­constant ([meta.help]), with the arguments to the template integral_­constant determined by the requirements for the particular property being described.
The member names of the base characteristic shall not be hidden and shall be unambiguously available in the UnaryTypeTrait.
A BinaryTypeTrait describes a relationship between two types.
It shall be a class template that takes two template type arguments and, optionally, additional arguments that help define the relationship being described.
It shall be DefaultConstructible, CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its base characteristic, which is a specialization of the template integral_­constant ([meta.help]), with the arguments to the template integral_­constant determined by the requirements for the particular relationship being described.
The member names of the base characteristic shall not be hidden and shall be unambiguously available in the BinaryTypeTrait.
A TransformationTrait modifies a property of a type.
It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the modification.
It shall define a publicly accessible nested type named type, which shall be a synonym for the modified type.

23.15.2 Header <type_­traits> synopsis [meta.type.synop]

namespace std {
  // [meta.help], helper class
  template <class T, T v> struct integral_constant;

  template <bool B>
    using bool_constant = integral_constant<bool, B>;
  using true_type  = bool_constant<true>;
  using false_type = bool_constant<false>;

  // [meta.unary.cat], primary type categories
  template <class T> struct is_void;
  template <class T> struct is_null_pointer;
  template <class T> struct is_integral;
  template <class T> struct is_floating_point;
  template <class T> struct is_array;
  template <class T> struct is_pointer;
  template <class T> struct is_lvalue_reference;
  template <class T> struct is_rvalue_reference;
  template <class T> struct is_member_object_pointer;
  template <class T> struct is_member_function_pointer;
  template <class T> struct is_enum;
  template <class T> struct is_union;
  template <class T> struct is_class;
  template <class T> struct is_function;

  // [meta.unary.comp], composite type categories
  template <class T> struct is_reference;
  template <class T> struct is_arithmetic;
  template <class T> struct is_fundamental;
  template <class T> struct is_object;
  template <class T> struct is_scalar;
  template <class T> struct is_compound;
  template <class T> struct is_member_pointer;

  // [meta.unary.prop], type properties
  template <class T> struct is_const;
  template <class T> struct is_volatile;
  template <class T> struct is_trivial;
  template <class T> struct is_trivially_copyable;
  template <class T> struct is_standard_layout;
  template <class T> struct is_pod;
  template <class T> struct is_empty;
  template <class T> struct is_polymorphic;
  template <class T> struct is_abstract;
  template <class T> struct is_final;
  template <class T> struct is_aggregate;

  template <class T> struct is_signed;
  template <class T> struct is_unsigned;

  template <class T, class... Args> struct is_constructible;
  template <class T> struct is_default_constructible;
  template <class T> struct is_copy_constructible;
  template <class T> struct is_move_constructible;

  template <class T, class U> struct is_assignable;
  template <class T> struct is_copy_assignable;
  template <class T> struct is_move_assignable;

  template <class T, class U> struct is_swappable_with;
  template <class T> struct is_swappable;

  template <class T> struct is_destructible;

  template <class T, class... Args> struct is_trivially_constructible;
  template <class T> struct is_trivially_default_constructible;
  template <class T> struct is_trivially_copy_constructible;
  template <class T> struct is_trivially_move_constructible;

  template <class T, class U> struct is_trivially_assignable;
  template <class T> struct is_trivially_copy_assignable;
  template <class T> struct is_trivially_move_assignable;
  template <class T> struct is_trivially_destructible;

  template <class T, class... Args> struct is_nothrow_constructible;
  template <class T> struct is_nothrow_default_constructible;
  template <class T> struct is_nothrow_copy_constructible;
  template <class T> struct is_nothrow_move_constructible;

  template <class T, class U> struct is_nothrow_assignable;
  template <class T> struct is_nothrow_copy_assignable;
  template <class T> struct is_nothrow_move_assignable;

  template <class T, class U> struct is_nothrow_swappable_with;
  template <class T> struct is_nothrow_swappable;

  template <class T> struct is_nothrow_destructible;

  template <class T> struct has_virtual_destructor;

  template <class T> struct has_unique_object_representations;

  // [meta.unary.prop.query], type property queries
  template <class T> struct alignment_of;
  template <class T> struct rank;
  template <class T, unsigned I = 0> struct extent;

  // [meta.rel], type relations
  template <class T, class U> struct is_same;
  template <class Base, class Derived> struct is_base_of;
  template <class From, class To> struct is_convertible;

  template <class Fn, class... ArgTypes> struct is_invocable;
  template <class R, class Fn, class... ArgTypes> struct is_invocable_r;

  template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
  template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;

  // [meta.trans.cv], const-volatile modifications
  template <class T> struct remove_const;
  template <class T> struct remove_volatile;
  template <class T> struct remove_cv;
  template <class T> struct add_const;
  template <class T> struct add_volatile;
  template <class T> struct add_cv;

  template <class T>
    using remove_const_t    = typename remove_const<T>::type;
  template <class T>
    using remove_volatile_t = typename remove_volatile<T>::type;
  template <class T>
    using remove_cv_t       = typename remove_cv<T>::type;
  template <class T>
    using add_const_t       = typename add_const<T>::type;
  template <class T>
    using add_volatile_t    = typename add_volatile<T>::type;
  template <class T>
    using add_cv_t          = typename add_cv<T>::type;

  // [meta.trans.ref], reference modifications
  template <class T> struct remove_reference;
  template <class T> struct add_lvalue_reference;
  template <class T> struct add_rvalue_reference;

  template <class T>
    using remove_reference_t     = typename remove_reference<T>::type;
  template <class T>
    using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
  template <class T>
    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;

  // [meta.trans.sign], sign modifications
  template <class T> struct make_signed;
  template <class T> struct make_unsigned;

  template <class T>
    using make_signed_t   = typename make_signed<T>::type;
  template <class T>
    using make_unsigned_t = typename make_unsigned<T>::type;

  // [meta.trans.arr], array modifications
  template <class T> struct remove_extent;
  template <class T> struct remove_all_extents;

  template <class T>
    using remove_extent_t      = typename remove_extent<T>::type;
  template <class T>
    using remove_all_extents_t = typename remove_all_extents<T>::type;

  // [meta.trans.ptr], pointer modifications
  template <class T> struct remove_pointer;
  template <class T> struct add_pointer;

  template <class T>
    using remove_pointer_t = typename remove_pointer<T>::type;
  template <class T>
    using add_pointer_t    = typename add_pointer<T>::type;

  // [meta.trans.other], other transformations
  template <size_t Len,
            size_t Align = default-alignment> // see [meta.trans.other]
    struct aligned_storage;
  template <size_t Len, class... Types> struct aligned_union;
  template <class T> struct decay;
  template <bool, class T = void> struct enable_if;
  template <bool, class T, class F> struct conditional;
  template <class... T> struct common_type;
  template <class T> struct underlying_type;
  template <class Fn, class... ArgTypes> struct invoke_result;

  template <size_t Len,
            size_t Align = default-alignment> // see [meta.trans.other]
    using aligned_storage_t = typename aligned_storage<Len, Align>::type;
  template <size_t Len, class... Types>
    using aligned_union_t   = typename aligned_union<Len, Types...>::type;
  template <class T>
    using decay_t           = typename decay<T>::type;
  template <bool b, class T = void>
    using enable_if_t       = typename enable_if<b, T>::type;
  template <bool b, class T, class F>
    using conditional_t     = typename conditional<b, T, F>::type;
  template <class... T>
    using common_type_t     = typename common_type<T...>::type;
  template <class T>
    using underlying_type_t = typename underlying_type<T>::type;
  template <class Fn, class... ArgTypes>
    using invoke_result_t   = typename invoke_result<Fn, ArgTypes...>::type;
  template <class...>
    using void_t            = void;

  // [meta.logical], logical operator traits
  template<class... B> struct conjunction;
  template<class... B> struct disjunction;
  template<class B> struct negation;

  // [meta.unary.cat], primary type categories
  template <class T> inline constexpr bool is_void_v
    = is_void<T>::value;
  template <class T> inline constexpr bool is_null_pointer_v
    = is_null_pointer<T>::value;
  template <class T> inline constexpr bool is_integral_v
    = is_integral<T>::value;
  template <class T> inline constexpr bool is_floating_point_v
    = is_floating_point<T>::value;
  template <class T> inline constexpr bool is_array_v
    = is_array<T>::value;
  template <class T> inline constexpr bool is_pointer_v
    = is_pointer<T>::value;
  template <class T> inline constexpr bool is_lvalue_reference_v
    = is_lvalue_reference<T>::value;
  template <class T> inline constexpr bool is_rvalue_reference_v
    = is_rvalue_reference<T>::value;
  template <class T> inline constexpr bool is_member_object_pointer_v
    = is_member_object_pointer<T>::value;
  template <class T> inline constexpr bool is_member_function_pointer_v
    = is_member_function_pointer<T>::value;
  template <class T> inline constexpr bool is_enum_v
    = is_enum<T>::value;
  template <class T> inline constexpr bool is_union_v
    = is_union<T>::value;
  template <class T> inline constexpr bool is_class_v
    = is_class<T>::value;
  template <class T> inline constexpr bool is_function_v
    = is_function<T>::value;

  // [meta.unary.comp], composite type categories
  template <class T> inline constexpr bool is_reference_v
    = is_reference<T>::value;
  template <class T> inline constexpr bool is_arithmetic_v
    = is_arithmetic<T>::value;
  template <class T> inline constexpr bool is_fundamental_v
    = is_fundamental<T>::value;
  template <class T> inline constexpr bool is_object_v
    = is_object<T>::value;
  template <class T> inline constexpr bool is_scalar_v
    = is_scalar<T>::value;
  template <class T> inline constexpr bool is_compound_v
    = is_compound<T>::value;
  template <class T> inline constexpr bool is_member_pointer_v
    = is_member_pointer<T>::value;

  // [meta.unary.prop], type properties
  template <class T> inline constexpr bool is_const_v
    = is_const<T>::value;
  template <class T> inline constexpr bool is_volatile_v
    = is_volatile<T>::value;
  template <class T> inline constexpr bool is_trivial_v
    = is_trivial<T>::value;
  template <class T> inline constexpr bool is_trivially_copyable_v
    = is_trivially_copyable<T>::value;
  template <class T> inline constexpr bool is_standard_layout_v
    = is_standard_layout<T>::value;
  template <class T> inline constexpr bool is_pod_v
    = is_pod<T>::value;
  template <class T> inline constexpr bool is_empty_v
    = is_empty<T>::value;
  template <class T> inline constexpr bool is_polymorphic_v
    = is_polymorphic<T>::value;
  template <class T> inline constexpr bool is_abstract_v
    = is_abstract<T>::value;
  template <class T> inline constexpr bool is_final_v
    = is_final<T>::value;
  template <class T> inline constexpr bool is_aggregate_v
    = is_aggregate<T>::value;
  template <class T> inline constexpr bool is_signed_v
    = is_signed<T>::value;
  template <class T> inline constexpr bool is_unsigned_v
    = is_unsigned<T>::value;
  template <class T, class... Args> inline constexpr bool is_constructible_v
    = is_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_default_constructible_v
    = is_default_constructible<T>::value;
  template <class T> inline constexpr bool is_copy_constructible_v
    = is_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_move_constructible_v
    = is_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_assignable_v
    = is_assignable<T, U>::value;
  template <class T> inline constexpr bool is_copy_assignable_v
    = is_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_move_assignable_v
    = is_move_assignable<T>::value;
  template <class T, class U> inline constexpr bool is_swappable_with_v
    = is_swappable_with<T, U>::value;
  template <class T> inline constexpr bool is_swappable_v
    = is_swappable<T>::value;
  template <class T> inline constexpr bool is_destructible_v
    = is_destructible<T>::value;
  template <class T, class... Args> inline constexpr bool is_trivially_constructible_v
    = is_trivially_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_trivially_default_constructible_v
    = is_trivially_default_constructible<T>::value;
  template <class T> inline constexpr bool is_trivially_copy_constructible_v
    = is_trivially_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_trivially_move_constructible_v
    = is_trivially_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_trivially_assignable_v
    = is_trivially_assignable<T, U>::value;
  template <class T> inline constexpr bool is_trivially_copy_assignable_v
    = is_trivially_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_trivially_move_assignable_v
    = is_trivially_move_assignable<T>::value;
  template <class T> inline constexpr bool is_trivially_destructible_v
    = is_trivially_destructible<T>::value;
  template <class T, class... Args> inline constexpr bool is_nothrow_constructible_v
    = is_nothrow_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_nothrow_default_constructible_v
    = is_nothrow_default_constructible<T>::value;
  template <class T> inline constexpr bool is_nothrow_copy_constructible_v
    = is_nothrow_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_nothrow_move_constructible_v
    = is_nothrow_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_nothrow_assignable_v
    = is_nothrow_assignable<T, U>::value;
  template <class T> inline constexpr bool is_nothrow_copy_assignable_v
    = is_nothrow_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_nothrow_move_assignable_v
    = is_nothrow_move_assignable<T>::value;
  template <class T, class U> inline constexpr bool is_nothrow_swappable_with_v
    = is_nothrow_swappable_with<T, U>::value;
  template <class T> inline constexpr bool is_nothrow_swappable_v
    = is_nothrow_swappable<T>::value;
  template <class T> inline constexpr bool is_nothrow_destructible_v
    = is_nothrow_destructible<T>::value;
  template <class T> inline constexpr bool has_virtual_destructor_v
    = has_virtual_destructor<T>::value;
  template <class T> inline constexpr bool has_unique_object_representations_v
    = has_unique_object_representations<T>::value;

  // [meta.unary.prop.query], type property queries
  template <class T> inline constexpr size_t alignment_of_v
    = alignment_of<T>::value;
  template <class T> inline constexpr size_t rank_v
    = rank<T>::value;
  template <class T, unsigned I = 0> inline constexpr size_t extent_v
    = extent<T, I>::value;

  // [meta.rel], type relations
  template <class T, class U> inline constexpr bool is_same_v
    = is_same<T, U>::value;
  template <class Base, class Derived> inline constexpr bool is_base_of_v
    = is_base_of<Base, Derived>::value;
  template <class From, class To> inline constexpr bool is_convertible_v
    = is_convertible<From, To>::value;
  template <class Fn, class... ArgTypes> inline constexpr bool is_invocable_v
    = is_invocable<Fn, ArgTypes...>::value;
  template <class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v
    = is_invocable_r<R, Fn, ArgTypes...>::value;
  template <class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v
    = is_nothrow_invocable<Fn, ArgTypes...>::value;
  template <class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v
    = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;

  // [meta.logical], logical operator traits
  template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value;
  template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value;
  template<class B> inline constexpr bool negation_v = negation<B>::value;
}
The behavior of a program that adds specializations for any of the templates defined in this subclause is undefined unless otherwise specified.
Unless otherwise specified, an incomplete type may be used to instantiate a template in this subclause.

23.15.3 Helper classes [meta.help]

namespace std {
  template <class T, T v>
  struct integral_constant {
    static constexpr T value = v;
    using value_type = T;
    using type       = integral_constant<T, v>;
    constexpr operator value_type() const noexcept { return value; }
    constexpr value_type operator()() const noexcept { return value; }
  };
}
The class template integral_­constant, alias template bool_­constant, and its associated typedef-names true_­type and false_­type are used as base classes to define the interface for various type traits.

23.15.4 Unary type traits [meta.unary]

This subclause contains templates that may be used to query the properties of a type at compile time.
Each of these templates shall be a UnaryTypeTrait ([meta.rqmts]) with a base characteristic of true_­type if the corresponding condition is true, otherwise false_­type.

23.15.4.1 Primary type categories [meta.unary.cat]

The primary type categories correspond to the descriptions given in section [basic.types] of the C++ standard.
For any given type T, the result of applying one of these templates to T and to cv T shall yield the same result.
[Note
:
For any given type T, exactly one of the primary type categories has a value member that evaluates to true.
end note
]
Table 35 — Primary type category predicates
Template
Condition
Comments
template <class T>
struct is_­void;
T is void
template <class T>
struct is_­null_­pointer;
T is nullptr_­t ([basic.fundamental])
template <class T>
struct is_­integral;
T is an integral type ([basic.fundamental])
template <class T>
struct is_­floating_­point;
T is a floating-point type ([basic.fundamental])
template <class T>
struct is_­array;
T is an array type ([basic.compound]) of known or unknown extent
Class template array ([array]) is not an array type.
template <class T>
struct is_­pointer;
T is a pointer type ([basic.compound])
Includes pointers to functions but not pointers to non-static members.
template <class T>
struct is_­lvalue_­reference;
T is an lvalue reference type ([dcl.ref])
template <class T>
struct is_­rvalue_­reference;
T is an rvalue reference type ([dcl.ref])
template <class T>
struct is_­member_­object_­pointer;
T is a pointer to non-static data member
template <class T>
struct is_­member_­function_­pointer;
T is a pointer to non-static member function
template <class T>
struct is_­enum;
T is an enumeration type ([basic.compound])
template <class T>
struct is_­union;
T is a union type ([basic.compound])
template <class T>
struct is_­class;
T is a non-union class type ([basic.compound])
template <class T>
struct is_­function;
T is a function type ([basic.compound])

23.15.4.2 Composite type traits [meta.unary.comp]

These templates provide convenient compositions of the primary type categories, corresponding to the descriptions given in section [basic.types].
For any given type T, the result of applying one of these templates to T and to cv T shall yield the same result.
Table 36 — Composite type category predicates
Template
Condition
Comments
template <class T>
struct is_­reference;
T is an lvalue reference or an rvalue reference
template <class T>
struct is_­arithmetic;
T is an arithmetic type ([basic.fundamental])
template <class T>
struct is_­fundamental;
T is a fundamental type ([basic.fundamental])
template <class T>
struct is_­object;
T is an object type ([basic.types])
template <class T>
struct is_­scalar;
T is a scalar type ([basic.types])
template <class T>
struct is_­compound;
T is a compound type ([basic.compound])
template <class T>
struct is_­member_­pointer;
T is a pointer to non-static data member or non-static member function

23.15.4.3 Type properties [meta.unary.prop]

These templates provide access to some of the more important properties of types.
It is unspecified whether the library defines any full or partial specializations of any of these templates.
For all of the class templates X declared in this subclause, instantiating that template with a template-argument that is a class template specialization may result in the implicit instantiation of the template argument if and only if the semantics of X require that the argument must be a complete type.
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any type T is considered to be a trivial ([basic.types], [special]) function call that is not an odr-use ([basic.def.odr]) of declval in the context of the corresponding definition notwithstanding the restrictions of [declval].
Table 37 — Type property predicates
Template
Condition
Preconditions
template <class T>
struct is_­const;
T is const-qualified ([basic.type.qualifier])
template <class T>
struct is_­volatile;
T is volatile-qualified ([basic.type.qualifier])
template <class T>
struct is_­trivial;
T is a trivial type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­trivially_­copyable;
T is a trivially copyable type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­standard_­layout;
T is a standard-layout type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­pod;
T is a POD type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­empty;
T is a class type, but not a union type, with no non-static data members other than bit-fields of length 0, no virtual member functions, no virtual base classes, and no base class B for which is_­empty_­v<B> is false.
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­polymorphic;
T is a polymorphic class ([class.virtual])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­abstract;
T is an abstract class ([class.abstract])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­final;
T is a class type marked with the class-virt-specifier final (Clause [class]).
[Note
:
A union is a class type that can be marked with final.
end note
]
If T is a class type, T shall be a complete type.
template <class T>
struct is_­aggregate;
T is an aggregate type ([dcl.init.aggr])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­signed;
If is_­arithmetic_­v<T> is true, the same result as T(-1) < T(0); otherwise, false
template <class T>
struct is_­unsigned;
If is_­arithmetic_­v<T> is true, the same result as T(0) < T(-1); otherwise, false
template <class T, class... Args>
struct is_­constructible;
For a function type T or for a cv void type T, is_­constructible_­v<T, Args...> is false, otherwise see below
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­default_­constructible;
is_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­copy_­constructible;
For a referenceable type T ([defns.referenceable]), the same result as is_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­move_­constructible;
For a referenceable type T, the same result as is_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­assignable;
The expression declval<T>() = declval<U>() is well-formed when treated as an unevaluated operand (Clause [expr]).
Access checking is performed as if in a context unrelated to T and U.
Only the validity of the immediate context of the assignment expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­copy_­assignable;
For a referenceable type T, the same result as is_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­move_­assignable;
For a referenceable type T, the same result as is_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­swappable_­with;
The expressions swap(declval<T>(), declval<U>()) and swap(declval<U>(), declval<T>()) are each well-formed when treated as an unevaluated operand (Clause [expr]) in an overload-resolution context for swappable values ([swappable.requirements]).
Access checking is performed as if in a context unrelated to T and U.
Only the validity of the immediate context of the swap expressions is considered.
[Note
:
The compilation of the expressions can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­swappable;
For a referenceable type T, the same result as is_­swappable_­with_­v<T&, T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­destructible;
Either T is a reference type, or T is a complete object type for which the expression declval<U&>().~U() is well-formed when treated as an unevaluated operand (Clause [expr]), where U is remove_­all_­extents<T>.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class... Args>
struct
is_­trivially_­constructible;
is_­constructible_­v<T,
Args...> is true and the variable definition for is_­constructible, as defined below, is known to call no operation that is not trivial ([basic.types], [special]).
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­trivially_­default_­constructible;
is_­trivially_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­copy_­constructible;
For a referenceable type T, the same result as is_­trivially_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­move_­constructible;
For a referenceable type T, the same result as is_­trivially_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­trivially_­assignable;
is_­assignable_­v<T, U> is true and the assignment, as defined by is_­assignable, is known to call no operation that is not trivial ([basic.types], [special]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­trivially_­copy_­assignable;
For a referenceable type T, the same result as is_­trivially_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­move_­assignable;
For a referenceable type T, the same result as is_­trivially_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­destructible;
is_­destructible_­v<T> is true and the indicated destructor is known to be trivial.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class... Args>
struct is_­nothrow_­constructible;
is_­constructible_­v<T, Args...> is true and the variable definition for is_­constructible, as defined below, is known not to throw any exceptions ([expr.unary.noexcept]).
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­default_­constructible;
is_­nothrow_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­copy_­constructible;
For a referenceable type T, the same result as is_­nothrow_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­move_­constructible;
For a referenceable type T, the same result as is_­nothrow_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­nothrow_­assignable;
is_­assignable_­v<T, U> is true and the assignment is known not to throw any exceptions ([expr.unary.noexcept]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­copy_­assignable;
For a referenceable type T, the same result as is_­nothrow_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­move_­assignable;
For a referenceable type T, the same result as is_­nothrow_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­nothrow_­swappable_­with;
is_­swappable_­with_­v<T, U> is true and each swap expression of the definition of is_­swappable_­with<T, U> is known not to throw any exceptions ([expr.unary.noexcept]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­swappable;
For a referenceable type T, the same result as is_­nothrow_­swappable_­with_­v<T&, T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­destructible;
is_­destructible_­v<T> is true and the indicated destructor is known not to throw any exceptions ([expr.unary.noexcept]).
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct has_­virtual_­destructor;
T has a virtual destructor ([class.dtor])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct has_­unique_­object_­representations;
For an array type T, the same result as has_­unique_­object_­representations_­v<remove_­all_­extents_­t<T>>, otherwise see below.
T shall be a complete type, cv void, or an array of unknown bound.
[Example
:
is_const_v<const volatile int>     // true
is_const_v<const int*>             // false
is_const_v<const int&>             // false
is_const_v<int[3]>                 // false
is_const_v<const int[3]>           // true
end example
]
[Example
:
remove_const_t<const volatile int>  // volatile int
remove_const_t<const int* const>    // const int*
remove_const_t<const int&>          // const int&
remove_const_t<const int[3]>        // int[3]
end example
]
[Example
:
// Given:
struct P final { };
union U1 { };
union U2 final { };

// the following assertions hold:
static_assert(!is_final_v<int>);
static_assert(is_final_v<P>);
static_assert(!is_final_v<U1>);
static_assert(is_final_v<U2>);
end example
]
The predicate condition for a template specialization is_­constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(declval<Args>()...);
[Note
:
These tokens are never interpreted as a function declaration.
end note
]
Access checking is performed as if in a context unrelated to T and any of the Args.
Only the validity of the immediate context of the variable initialization is considered.
[Note
:
The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
The predicate condition for a template specialization has_­unique_­object_­representations<T> shall be satisfied if and only if:
  • T is trivially copyable, and
  • any two objects of type T with the same value have the same object representation, where two objects of array or non-union class type are considered to have the same value if their respective sequences of direct subobjects have the same values, and two objects of union type are considered to have the same value if they have the same active member and the corresponding members have the same value.
The set of scalar types for which this condition holds is implementation-defined.
[Note
:
If a type has padding bits, the condition does not hold; otherwise, the condition holds true for unsigned integral types.
end note
]

23.15.5 Type property queries [meta.unary.prop.query]

This subclause contains templates that may be used to query properties of types at compile time.
Table 38 — Type property queries
Template
Value
template <class T>
struct alignment_­of;
alignof(T).

Requires: alignof(T) shall be a valid expression ([expr.alignof])
template <class T>
struct rank;
If T names an array type, an integer value representing the number of dimensions of T; otherwise, 0.
template <class T,
unsigned I = 0>
struct extent;
If T is not an array type, or if it has rank less than or equal to I, or if I is 0 and T has type “array of unknown bound of U”, then 0; otherwise, the bound ([dcl.array]) of the I'th dimension of T, where indexing of I is zero-based
Each of these templates shall be a UnaryTypeTrait ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, Value>.
[Example
:
// the following assertions hold:
assert(rank_v<int> == 0);
assert(rank_v<int[2]> == 1);
assert(rank_v<int[][4]> == 2);
end example
]
[Example
:
// the following assertions hold:
assert(extent_v<int> == 0);
assert(extent_v<int[2]> == 2);
assert(extent_v<int[2][4]> == 2);
assert(extent_v<int[][4]> == 0);
assert((extent_v<int, 1>) == 0);
assert((extent_v<int[2], 1>) == 0);
assert((extent_v<int[2][4], 1>) == 4);
assert((extent_v<int[][4], 1>) == 4);
end example
]

23.15.6 Relationships between types [meta.rel]

This subclause contains templates that may be used to query relationships between types at compile time.
Each of these templates shall be a BinaryTypeTrait ([meta.rqmts]) with a base characteristic of true_­type if the corresponding condition is true, otherwise false_­type.
Table 39 — Type relationship predicates
Template
Condition
Comments
template <class T, class U>
struct is_­same;
T and U name the same type with the same cv-qualifications
template <class Base, class Derived>
struct is_­base_­of;
Base is a base class of Derived (Clause [class.derived]) without regard to cv-qualifiers or Base and Derived are not unions and name the same class type without regard to cv-qualifiers
If Base and Derived are non-union class types and are not possibly cv-qualified versions of the same type, Derived shall be a complete type.
[Note
:
Base classes that are private, protected, or ambiguous are, nonetheless, base classes.
end note
]
template <class From, class To>
struct is_­convertible;
see below
From and To shall be complete types, arrays of unknown bound, or cv void types.
template <class Fn, class... ArgTypes>
struct is_­invocable;
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand
Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­invocable_­r;
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand
Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class Fn, class... ArgTypes>
struct is_­nothrow_­invocable;
is_­invocable_­v<
Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­nothrow_­invocable_­r;
is_­invocable_­r_­v<
R, Fn, ArgTypes...> is true and the expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any type T is considered to be a trivial ([basic.types], [special]) function call that is not an odr-use ([basic.def.odr]) of declval in the context of the corresponding definition notwithstanding the restrictions of [declval].
[Example
:
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : private B1, private B2 {};

is_base_of_v<B, D>         // true
is_base_of_v<const B, D>   // true
is_base_of_v<B, const D>   // true
is_base_of_v<B, const B>   // true
is_base_of_v<D, B>         // false
is_base_of_v<B&, D&>       // false
is_base_of_v<B[3], D[3]>   // false
is_base_of_v<int, int>     // false
end example
]
The predicate condition for a template specialization is_­convertible<From, To> shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:
To test() {
  return declval<From>();
}
[Note
:
This requirement gives well defined results for reference types, void types, array types, and function types.
end note
]
Access checking is performed in a context unrelated to To and From.
Only the validity of the immediate context of the expression of the return statement (including initialization of the returned object or reference) is considered.
[Note
:
The initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]

23.15.7 Transformations between types [meta.trans]

This subclause contains templates that may be used to transform one type to another following some predefined rule.
Each of the templates in this subclause shall be a TransformationTrait ([meta.rqmts]).

23.15.7.1 Const-volatile modifications [meta.trans.cv]

Table 40 — Const-volatile modifications
Template
Comments
template <class T>
struct remove_­const;
The member typedef type names the same type as T except that any top-level const-qualifier has been removed.
[Example
:
remove_­const_­t<const volatile int> evaluates to volatile int, whereas remove_­const_­t<const int*> evaluates to const int*.
end example
]
template <class T>
struct remove_­volatile;
The member typedef type names the same type as T except that any top-level volatile-qualifier has been removed.
[Example
:
remove_­volatile_­t<const volatile int> evaluates to const int, whereas remove_­volatile_­t<volatile int*> evaluates to volatile int*.
end example
]
template <class T>
struct remove_­cv;
The member typedef type shall be the same as T except that any top-level cv-qualifier has been removed.
[Example
:
remove_­cv_­t<const volatile int> evaluates to int, whereas remove_­cv_­t<const volatile int*> evaluates to const volatile int*.
end example
]
template <class T>
struct add_­const;
If T is a reference, function, or top-level const-qualified type, then type names the same type as T, otherwise T const.
template <class T>
struct add_­volatile;
If T is a reference, function, or top-level volatile-qualified type, then type names the same type as T, otherwise T volatile.
template <class T>
struct add_­cv;
The member typedef type names the same type as add_­const_­t<add_­volatile_­t<T>>.

23.15.7.2 Reference modifications [meta.trans.ref]

Table 41 — Reference modifications
Template
Comments
template <class T>
struct remove_­reference;
If T has type “reference to T1” then the member typedef type names T1; otherwise, type names T.
template <class T>
struct add_­lvalue_­reference;
If T names a referenceable type ([defns.referenceable]) then the member typedef type names T&; otherwise, type names T.
[Note
:
This rule reflects the semantics of reference collapsing ([dcl.ref]).
end note
]
template <class T>
struct add_­rvalue_­reference;
If T names a referenceable type then the member typedef type names T&&; otherwise, type names T.
[Note
:
This rule reflects the semantics of reference collapsing ([dcl.ref]).
For example, when a type T names a type T1&, the type add_­rvalue_­reference_­t<T> is not an rvalue reference.
end note
]

23.15.7.3 Sign modifications [meta.trans.sign]

Table 42 — Sign modifications
Template
Comments
template <class T>
struct make_­signed;
If T names a (possibly cv-qualified) signed integer type ([basic.fundamental]) then the member typedef type names the type T; otherwise, if T names a (possibly cv-qualified) unsigned integer type then type names the corresponding signed integer type, with the same cv-qualifiers as T; otherwise, type names the signed integer type with smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T.

Requires: T shall be a (possibly cv-qualified) integral type or enumeration but not a bool type.
template <class T>
struct make_­unsigned;
If T names a (possibly cv-qualified) unsigned integer type ([basic.fundamental]) then the member typedef type names the type T; otherwise, if T names a (possibly cv-qualified) signed integer type then type names the corresponding unsigned integer type, with the same cv-qualifiers as T; otherwise, type names the unsigned integer type with smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T.

Requires: T shall be a (possibly cv-qualified) integral type or enumeration but not a bool type.

23.15.7.4 Array modifications [meta.trans.arr]

Table 43 — Array modifications
Template
Comments
template <class T>
struct remove_­extent;
If T names a type “array of U”, the member typedef type shall be U, otherwise T.
[Note
:
For multidimensional arrays, only the first array dimension is removed.
For a type “array of const U”, the resulting type is const U.
end note
]
template <class T>
struct remove_­all_­extents;
If T is “multi-dimensional array of U”, the resulting member typedef type is U, otherwise T.
[Example
:
// the following assertions hold:
assert((is_same_v<remove_extent_t<int>, int>));
assert((is_same_v<remove_extent_t<int[2]>, int>));
assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
end example
]
[Example
:
// the following assertions hold:
assert((is_same_v<remove_all_extents_t<int>, int>));
assert((is_same_v<remove_all_extents_t<int[2]>, int>));
assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
end example
]

23.15.7.5 Pointer modifications [meta.trans.ptr]

Table 44 — Pointer modifications
Template
Comments
template <class T>
struct remove_­pointer;
If T has type “(possibly cv-qualified) pointer to T1” then the member typedef type names T1; otherwise, it names T.
template <class T>
struct add_­pointer;
If T names a referenceable type ([defns.referenceable]) or a cv void type then the member typedef type names the same type as remove_­reference_­t<T>*; otherwise, type names T.

23.15.7.6 Other transformations [meta.trans.other]

Table 45 — Other transformations
Template
Comments
template <size_­t Len,
size_­t Align
= default-alignment>
struct aligned_­storage;
The value of default-alignment shall be the most stringent alignment requirement for any C++ object type whose size is no greater than Len ([basic.types]).
The member typedef type shall be a POD type suitable for use as uninitialized storage for any object whose size is at most Len and whose alignment is a divisor of Align.

Requires: Len shall not be zero.
Align shall be equal to alignof(T) for some type T or to default-alignment.
template <size_­t Len,
class... Types>
struct aligned_­union;
The member typedef type shall be a POD type suitable for use as uninitialized storage for any object whose type is listed in Types; its size shall be at least Len.
The static member alignment_­value shall be an integral constant of type size_­t whose value is the strictest alignment of all types listed in Types.

Requires: At least one type is provided.
template <class T>
struct decay;
Let U be remove_­reference_­t<T>.
If is_­array_­v<U> is true, the member typedef type shall equal remove_­extent_­t<U>*.
If is_­function_­v<U> is true, the member typedef type shall equal add_­pointer_­t<U>.
Otherwise the member typedef type equals remove_­cv_­t<U>.
[Note
:
This behavior is similar to the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) conversions applied when an lvalue expression is used as an rvalue, but also strips cv-qualifiers from class types in order to more closely model by-value argument passing.
end note
]
template <bool B, class T = void> struct enable_­if;
If B is true, the member typedef type shall equal T; otherwise, there shall be no member type.
template <bool B, class T, class F>
struct conditional;
If B is true, the member typedef type shall equal T.
If B is false, the member typedef type shall equal F.
template <class... T> struct common_­type;
Unless this trait is specialized (as specified in Note B, below), the member type shall be defined or omitted as specified in Note A, below.
If it is omitted, there shall be no member type.
Each type in the parameter pack T shall be complete, cv void, or an array of unknown bound.
template <class T>
struct underlying_­type;
The member typedef type names the underlying type of T.

Requires: T shall be a complete enumeration type ([dcl.enum])
template <class Fn,
class... ArgTypes>
struct invoke_­result;
If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand (Clause [expr]), the member typedef type names the type decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type.
Access checking is performed as if in a context unrelated to Fn and ArgTypes.
Only the validity of the immediate context of the expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]

Requires: Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
[Note
:
A typical implementation would define aligned_­storage as:
template <size_t Len, size_t Alignment>
struct aligned_storage {
  typedef struct {
    alignas(Alignment) unsigned char __data[Len];
  } type;
};
end note
]
It is implementation-defined whether any extended alignment is supported ([basic.align]).
Note A: For the common_­type trait applied to a parameter pack T of types, the member type shall be either defined or not present as follows:
  • If sizeof...(T) is zero, there shall be no member type.
  • If sizeof...(T) is one, let T0 denote the sole type constituting the pack T.
    The member typedef-name type shall denote the same type, if any, as common_­type_­t<T0, T0>; otherwise there shall be no member type.
  • If sizeof...(T) is two, let the first and second types constituting T be denoted by T1 and T2, respectively, and let D1 and D2 denote the same types as decay_­t<T1> and decay_­t<T2>, respectively.
    • If is_­same_­v<T1, D1> is false or is_­same_­v<T2, D2> is false, let C denote the same type, if any, as common_­type_­t<D1, D2>.
    • Otherwise, let C denote the same type, if any, as
      decay_t<decltype(false ? declval<D1>() : declval<D2>())>
      [Note
      :
      This will not apply if there is a specialization common_­type<D1, D2>.
      end note
      ]
    In either case, the member typedef-name type shall denote the same type, if any, as C.
    Otherwise, there shall be no member type.
  • If sizeof...(T) is greater than two, let T1, T2, and R, respectively, denote the first, second, and (pack of) remaining types constituting T.
    Let C denote the same type, if any, as common_­type_­t<T1, T2>.
    If there is such a type C, the member typedef-name type shall denote the same type, if any, as common_­type_­t<C, R...>.
    Otherwise, there shall be no member type.
Note B: Notwithstanding the provisions of [meta.type.synop], and pursuant to [namespace.std], a program may specialize common_­type<T1, T2> for types T1 and T2 such that is_­same_­v<T1, decay_­t<T1>> and is_­same_­v<T2, decay_­t<T2>> are each true.
[Note
:
Such specializations are needed when only explicit conversions are desired between the template arguments.
end note
]
Such a specialization need not have a member named type, but if it does, that member shall be a typedef-name for an accessible and unambiguous cv-unqualified non-reference type C to which each of the types T1 and T2 is explicitly convertible.
Moreover, common_­type_­t<T1, T2> shall denote the same type, if any, as does common_­type_­t<T2, T1>.
No diagnostic is required for a violation of this Note's rules.
[Example
:
Given these definitions:
using PF1 = bool  (&)();
using PF2 = short (*)(long);

struct S {
  operator PF2() const;
  double operator()(char, int&);
  void fn(long) const;
  char data;
};

using PMF = void (S::*)(long) const;
using PMD = char  S::*;
the following assertions will hold:
static_assert(is_same_v<invoke_result_t<S, int>, short>);
static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
static_assert(is_same_v<invoke_result_t<PF1>, bool>);
static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
end example
]

23.15.8 Logical operator traits [meta.logical]

This subclause describes type traits for applying logical operators to other type traits.
template<class... B> struct conjunction : see below { };
The class template conjunction forms the logical conjunction of its template type arguments.
For a specialization conjunction<B1, ..., BN>, if there is a template type argument Bi for which bool(Bi​::​value) is false, then instantiating conjunction<B1, ..., BN>​::​value does not require the instantiation of Bj​::​value for j > i.
[Note
:
This is analogous to the short-circuiting behavior of the built-in operator &&.
end note
]
Every template type argument for which Bi​::​value is instantiated shall be usable as a base class and shall have a member value which is convertible to bool, is not hidden, and is unambiguously available in the type.
The specialization conjunction<B1, ..., BN> has a public and unambiguous base that is either
  • the first type Bi in the list true_­type, B1, ..., BN for which bool(Bi​::​value) is false, or
  • if there is no such Bi, the last type in the list.
[Note
:
This means a specialization of conjunction does not necessarily inherit from either true_­type or false_­type.
end note
]
The member names of the base class, other than conjunction and operator=, shall not be hidden and shall be unambiguously available in conjunction.
template<class... B> struct disjunction : see below { };
The class template disjunction forms the logical disjunction of its template type arguments.
For a specialization disjunction<B1, ..., BN>, if there is a template type argument Bi for which bool(Bi​::​value) is true, then instantiating disjunction<B1, ..., BN>​::​value does not require the instantiation of Bj​::​value for j > i.
[Note
:
This is analogous to the short-circuiting behavior of the built-in operator ||.
end note
]
Every template type argument for which Bi​::​value is instantiated shall be usable as a base class and shall have a member value which is convertible to bool, is not hidden, and is unambiguously available in the type.
The specialization disjunction<B1, ..., BN> has a public and unambiguous base that is either
  • the first type Bi in the list false_­type, B1, ..., BN for which bool(Bi​::​value) is true, or
  • if there is no such Bi, the last type in the list.
[Note
:
This means a specialization of disjunction does not necessarily inherit from either true_­type or false_­type.
end note
]
The member names of the base class, other than disjunction and operator=, shall not be hidden and shall be unambiguously available in disjunction.
template<class B> struct negation : see below { };
The class template negation forms the logical negation of its template type argument.
The type negation<B> is a UnaryTypeTrait with a base characteristic of bool_­constant<!bool(B​::​value)>.

23.16 Compile-time rational arithmetic [ratio]

23.16.1 In general [ratio.general]

This subclause describes the ratio library.
It provides a class template ratio which exactly represents any finite rational number with a numerator and denominator representable by compile-time constants of type intmax_­t.
Throughout this subclause, the names of template parameters are used to express type requirements.
If a template parameter is named R1 or R2, and the template argument is not a specialization of the ratio template, the program is ill-formed.

23.16.2 Header <ratio> synopsis [ratio.syn]

namespace std {
  // [ratio.ratio], class template ratio
  template <intmax_t N, intmax_t D = 1> class ratio;

  // [ratio.arithmetic], ratio arithmetic
  template <class R1, class R2> using ratio_add = see below;
  template <class R1, class R2> using ratio_subtract = see below;
  template <class R1, class R2> using ratio_multiply = see below;
  template <class R1, class R2> using ratio_divide = see below;

  // [ratio.comparison], ratio comparison
  template <class R1, class R2> struct ratio_equal;
  template <class R1, class R2> struct ratio_not_equal;
  template <class R1, class R2> struct ratio_less;
  template <class R1, class R2> struct ratio_less_equal;
  template <class R1, class R2> struct ratio_greater;
  template <class R1, class R2> struct ratio_greater_equal;

  template <class R1, class R2>
    inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;

  // [ratio.si], convenience SI typedefs
  using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>;  // see below
  using zepto = ratio<1,     1'000'000'000'000'000'000'000>;  // see below
  using atto  = ratio<1,         1'000'000'000'000'000'000>;
  using femto = ratio<1,             1'000'000'000'000'000>;
  using pico  = ratio<1,                 1'000'000'000'000>;
  using nano  = ratio<1,                     1'000'000'000>;
  using micro = ratio<1,                         1'000'000>;
  using milli = ratio<1,                             1'000>;
  using centi = ratio<1,                               100>;
  using deci  = ratio<1,                                10>;
  using deca  = ratio<                               10, 1>;
  using hecto = ratio<                              100, 1>;
  using kilo  = ratio<                            1'000, 1>;
  using mega  = ratio<                        1'000'000, 1>;
  using giga  = ratio<                    1'000'000'000, 1>;
  using tera  = ratio<                1'000'000'000'000, 1>;
  using peta  = ratio<            1'000'000'000'000'000, 1>;
  using exa   = ratio<        1'000'000'000'000'000'000, 1>;
  using zetta = ratio<    1'000'000'000'000'000'000'000, 1>;  // see below
  using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>;  // see below
}

23.16.3 Class template ratio [ratio.ratio]

namespace std {
  template <intmax_t N, intmax_t D = 1>
  class ratio {
  public:
    static constexpr intmax_t num;
    static constexpr intmax_t den;
    using type = ratio<num, den>;
  };
}
If the template argument D is zero or the absolute values of either of the template arguments N and D is not representable by type intmax_­t, the program is ill-formed.
[Note
:
These rules ensure that infinite ratios are avoided and that for any negative input, there exists a representable value of its absolute value which is positive.
In a two's complement representation, this excludes the most negative value.
end note
]
The static data members num and den shall have the following values, where gcd represents the greatest common divisor of the absolute values of N and D:
  • num shall have the value sign(N) * sign(D) * abs(N) / gcd.
  • den shall have the value abs(D) / gcd.

23.16.4 Arithmetic on ratios [ratio.arithmetic]

Each of the alias templates ratio_­add, ratio_­subtract, ratio_­multiply, and ratio_­divide denotes the result of an arithmetic computation on two ratios R1 and R2.
With X and Y computed (in the absence of arithmetic overflow) as specified by Table 46, each alias denotes a ratio<U, V> such that U is the same as ratio<X, Y>​::​num and V is the same as ratio<X, Y>​::​den.
If it is not possible to represent U or V with intmax_­t, the program is ill-formed.
Otherwise, an implementation should yield correct values of U and V.
If it is not possible to represent X or Y with intmax_­t, the program is ill-formed unless the implementation yields correct values of U and V.
Table 46 — Expressions used to perform ratio arithmetic
Type
Value of X
Value of Y
ratio_­add<R1, R2>
R1​::​num * R2​::​den +
R1​::​den * R2​::​den
R2​::​num * R1​::​den
ratio_­subtract<R1, R2>
R1​::​num * R2​::​den -
R1​::​den * R2​::​den
R2​::​num * R1​::​den
ratio_­multiply<R1, R2>
R1​::​num * R2​::​num
R1​::​den * R2​::​den
ratio_­divide<R1, R2>
R1​::​num * R2​::​den
R1​::​den * R2​::​num
[Example
:
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::num == 1, "1/3+1/6 == 1/2");
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::den == 2, "1/3*3/2 == 1/2");

// The following cases may cause the program to be ill-formed under some implementations
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::num == 2,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::den == INT_MAX,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::num == 1,
  "1/MAX * MAX/2 == 1/2");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::den == 2,
  "1/MAX * MAX/2 == 1/2");
end example
]

23.16.5 Comparison of ratios [ratio.comparison]

template <class R1, class R2> struct ratio_equal : bool_constant<R1::num == R2::num && R1::den == R2::den> { };
template <class R1, class R2> struct ratio_not_equal : bool_constant<!ratio_equal_v<R1, R2>> { };
template <class R1, class R2> struct ratio_less : bool_constant<see below> { };
If R1​::​num × R2​::​den is less than R2​::​num × R1​::​den, ratio_­less<R1, R2> shall be derived from bool_­constant<true>; otherwise it shall be derived from bool_­constant<false>.
Implementations may use other algorithms to compute this relationship to avoid overflow.
If overflow occurs, the program is ill-formed.
template <class R1, class R2> struct ratio_less_equal : bool_constant<!ratio_less_v<R2, R1>> { };
template <class R1, class R2> struct ratio_greater : bool_constant<ratio_less_v<R2, R1>> { };
template <class R1, class R2> struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };

23.16.6 SI types for ratio [ratio.si]

For each of the typedef-names yocto, zepto, zetta, and yotta, if both of the constants used in its specification are representable by intmax_­t, the typedef shall be defined; if either of the constants is not representable by intmax_­t, the typedef shall not be defined.

23.17 Time utilities [time]

23.17.1 In general [time.general]

This subclause describes the chrono library ([time.syn]) and various C functions ([ctime.syn]) that provide generally useful time utilities.

23.17.2 Header <chrono> synopsis [time.syn]

namespace std {
  namespace chrono {
    // [time.duration], class template duration
    template <class Rep, class Period = ratio<1>> class duration;

    // [time.point], class template time_­point
    template <class Clock, class Duration = typename Clock::duration> class time_point;
  }

  // [time.traits.specializations], common_­type specializations
  template <class Rep1, class Period1, class Rep2, class Period2>
    struct common_type<chrono::duration<Rep1, Period1>,
                       chrono::duration<Rep2, Period2>>;

  template <class Clock, class Duration1, class Duration2>
    struct common_type<chrono::time_point<Clock, Duration1>,
                       chrono::time_point<Clock, Duration2>>;

  namespace chrono {
    // [time.traits], customization traits
    template <class Rep> struct treat_as_floating_point;
    template <class Rep> struct duration_values;
    template <class Rep> inline constexpr bool treat_as_floating_point_v
      = treat_as_floating_point<Rep>::value;

    // [time.duration.nonmember], duration arithmetic
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator+(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator-(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator*(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Rep2, class Period>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator*(const Rep1& s, const duration<Rep2, Period>& d);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator/(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<Rep1, Rep2>
      constexpr operator/(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator%(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator%(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);

    // [time.duration.comparisons], duration comparisons
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator==(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator< (const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator> (const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);

    // [time.duration.cast], duration_­cast
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration floor(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration ceil(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration round(const duration<Rep, Period>& d);

    // convenience typedefs
    using nanoseconds  = duration<signed integer type of at least 64 bits, nano>;
    using microseconds = duration<signed integer type of at least 55 bits, micro>;
    using milliseconds = duration<signed integer type of at least 45 bits, milli>;
    using seconds      = duration<signed integer type of at least 35 bits>;
    using minutes      = duration<signed integer type of at least 29 bits, ratio<  60>>;
    using hours        = duration<signed integer type of at least 23 bits, ratio<3600>>;

    // [time.point.nonmember], time_­point arithmetic
    template <class Clock, class Duration1, class Rep2, class Period2>
      constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator+(const time_point<Clock, Duration1>& lhs,
                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Clock, class Duration2>
      constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
      operator+(const duration<Rep1, Period1>& lhs,
                const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Rep2, class Period2>
      constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator-(const time_point<Clock, Duration1>& lhs,
                const duration<Rep2, Period2>& rhs);
    template <class Clock, class Duration1, class Duration2>
      constexpr common_type_t<Duration1, Duration2>
      operator-(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

    // [time.point.comparisons], time_­point comparisons
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator< (const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator> (const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);

    // [time.point.cast], time_­point_­cast
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      time_point_cast(const time_point<Clock, Duration>& t);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      floor(const time_point<Clock, Duration>& tp);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      ceil(const time_point<Clock, Duration>& tp);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      round(const time_point<Clock, Duration>& tp);

    // [time.duration.alg], specialized algorithms
    template <class Rep, class Period>
      constexpr duration<Rep, Period> abs(duration<Rep, Period> d);

    // [time.clock], clocks
    class system_clock;
    class steady_clock;
    class high_resolution_clock;
  }

  inline namespace literals {
    inline namespace chrono_literals {
      // [time.duration.literals], suffixes for duration literals
      constexpr chrono::hours                                operator""h(unsigned long long);
      constexpr chrono::duration<unspecified, ratio<3600,1>> operator""h(long double);
      constexpr chrono::minutes                              operator""min(unsigned long long);
      constexpr chrono::duration<unspecified, ratio<60,1>>   operator""min(long double);
      constexpr chrono::seconds                              operator""s(unsigned long long);
      constexpr chrono::duration<unspecified>                operator""s(long double);
      constexpr chrono::milliseconds                         operator""ms(unsigned long long);
      constexpr chrono::duration<unspecified, milli>          operator""ms(long double);
      constexpr chrono::microseconds                         operator""us(unsigned long long);
      constexpr chrono::duration<unspecified, micro>         operator""us(long double);
      constexpr chrono::nanoseconds                          operator""ns(unsigned long long);
      constexpr chrono::duration<unspecified, nano>          operator""ns(long double);
    }
  }

  namespace chrono {
    using namespace literals::chrono_literals;
  }
}

23.17.3 Clock requirements [time.clock.req]

A clock is a bundle consisting of a duration, a time_­point, and a function now() to get the current time_­point.
The origin of the clock's time_­point is referred to as the clock's epoch.
A clock shall meet the requirements in Table 47.
In Table 47 C1 and C2 denote clock types.
t1 and t2 are values returned by C1​::​now() where the call returning t1 happens before ([intro.multithread]) the call returning t2 and both of these calls occur before C1​::​time_­point​::​max().
[Note
:
This means C1 did not wrap around between t1 and t2.
end note
]
Table 47 — Clock requirements
Expression
Return type
Operational semantics
C1​::​rep
An arithmetic type or a class emulating an arithmetic type
The representation type of C1​::​duration.
C1​::​period
a specialization of ratio
The tick period of the clock in seconds.
C1​::​duration
chrono​::​duration<C1​::​rep, C1​::​period>
The duration type of the clock.
C1​::​time_­point
chrono​::​time_­point<C1> or chrono​::​time_­point<C2, C1​::​duration>
The time_­point type of the clock.
C1 and C2 shall refer to the same epoch.
C1​::​is_­steady
const bool
true if t1 <= t2 is always true and the time between clock ticks is constant, otherwise false.
C1​::​now()
C1​::​time_­point
Returns a time_­point object representing the current point in time.
[Note
:
The relative difference in durations between those reported by a given clock and the SI definition is a measure of the quality of implementation.
end note
]
A type TC meets the TrivialClock requirements if:
  • TC satisfies the Clock requirements ([time.clock.req]),
  • the types TC​::​rep, TC​::​duration, and TC​::​time_­point satisfy the requirements of EqualityComparable (Table 20), LessThanComparable (Table 21), DefaultConstructible (Table 22), CopyConstructible (Table 24), CopyAssignable (Table 26), Destructible (Table 27), and the requirements of numeric types ([numeric.requirements]).
    [Note
    :
    This means, in particular, that operations on these types will not throw exceptions.
    end note
    ]
  • lvalues of the types TC​::​rep, TC​::​duration, and TC​::​time_­point are swappable ([swappable.requirements]),
  • the function TC​::​now() does not throw exceptions, and
  • the type TC​::​time_­point​::​clock meets the TrivialClock requirements, recursively.

23.17.4 Time-related traits [time.traits]

23.17.4.1 treat_­as_­floating_­point [time.traits.is_fp]

template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> { };
The duration template uses the treat_­as_­floating_­point trait to help determine if a duration object can be converted to another duration with a different tick period.
If treat_­as_­floating_­point_­v<Rep> is true, then implicit conversions are allowed among durations.
Otherwise, the implicit convertibility depends on the tick periods of the durations.
[Note
:
The intention of this trait is to indicate whether a given class behaves like a floating-point type, and thus allows division of one value by another with acceptable loss of precision.
If treat_­as_­floating_­point_­v<Rep> is false, Rep will be treated as if it behaved like an integral type for the purpose of these conversions.
end note
]

23.17.4.2 duration_­values [time.traits.duration_values]

template <class Rep> struct duration_values { public: static constexpr Rep zero(); static constexpr Rep min(); static constexpr Rep max(); };
The duration template uses the duration_­values trait to construct special values of the durations representation (Rep).
This is done because the representation might be a class type with behavior which requires some other implementation to return these special values.
In that case, the author of that class type should specialize duration_­values to return the indicated values.
static constexpr Rep zero();
Returns: Rep(0).
[Note
:
Rep(0) is specified instead of Rep() because Rep() may have some other meaning, such as an uninitialized value.
end note
]
Remarks: The value returned shall be the additive identity.
static constexpr Rep min();
Returns: numeric_­limits<Rep>​::​lowest().
Remarks: The value returned shall compare less than or equal to zero().
static constexpr Rep max();
Returns: numeric_­limits<Rep>​::​max().
Remarks: The value returned shall compare greater than zero().

23.17.4.3 Specializations of common_­type [time.traits.specializations]

template <class Rep1, class Period1, class Rep2, class Period2> struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> { using type = chrono::duration<common_type_t<Rep1, Rep2>, see below>; };
The period of the duration indicated by this specialization of common_­type shall be the greatest common divisor of Period1 and Period2.
[Note
:
This can be computed by forming a ratio of the greatest common divisor of Period1​::​num and Period2​::​num and the least common multiple of Period1​::​den and Period2​::​den.
end note
]
[Note
:
The typedef name type is a synonym for the duration with the largest tick period possible where both duration arguments will convert to it without requiring a division operation.
The representation of this type is intended to be able to hold any value resulting from this conversion with no truncation error, although floating-point durations may have round-off errors.
end note
]
template <class Clock, class Duration1, class Duration2> struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>> { using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>; };
The common type of two time_­point types is a time_­point with the same clock as the two types and the common type of their two durations.

23.17.5 Class template duration [time.duration]

A duration type measures time between two points in time (time_­points).
A duration has a representation which holds a count of ticks and a tick period.
The tick period is the amount of time which occurs from one tick to the next, in units of seconds.
It is expressed as a rational constant using the template ratio.
template <class Rep, class Period = ratio<1>>
class duration {
public:
  using rep    = Rep;
  using period = typename Period::type;
private:
  rep rep_;  // exposition only
public:
  // [time.duration.cons], construct/copy/destroy
  constexpr duration() = default;
  template <class Rep2>
      constexpr explicit duration(const Rep2& r);
  template <class Rep2, class Period2>
     constexpr duration(const duration<Rep2, Period2>& d);
  ~duration() = default;
  duration(const duration&) = default;
  duration& operator=(const duration&) = default;

  // [time.duration.observer], observer
  constexpr rep count() const;

  // [time.duration.arithmetic], arithmetic
  constexpr common_type_t<duration> operator+() const;
  constexpr common_type_t<duration> operator-() const;
  constexpr duration& operator++();
  constexpr duration  operator++(int);
  constexpr duration& operator--();
  constexpr duration  operator--(int);

  constexpr duration& operator+=(const duration& d);
  constexpr duration& operator-=(const duration& d);

  constexpr duration& operator*=(const rep& rhs);
  constexpr duration& operator/=(const rep& rhs);
  constexpr duration& operator%=(const rep& rhs);
  constexpr duration& operator%=(const duration& rhs);

  // [time.duration.special], special values
  static constexpr duration zero();
  static constexpr duration min();
  static constexpr duration max();
};
Rep shall be an arithmetic type or a class emulating an arithmetic type.
If duration is instantiated with a duration type as the argument for the template parameter Rep, the program is ill-formed.
If Period is not a specialization of ratio, the program is ill-formed.
If Period​::​num is not positive, the program is ill-formed.
Members of duration shall not throw exceptions other than those thrown by the indicated operations on their representations.
The defaulted copy constructor of duration shall be a constexpr function if and only if the required initialization of the member rep_­ for copy and move, respectively, would satisfy the requirements for a constexpr function.
[Example
:
duration<long, ratio<60>> d0;       // holds a count of minutes using a long
duration<long long, milli> d1;      // holds a count of milliseconds using a long long
duration<double, ratio<1, 30>>  d2; // holds a count with a tick period of  of a second
                                    // (30 Hz) using a double
end example
]

23.17.5.1 duration constructors [time.duration.cons]

template <class Rep2> constexpr explicit duration(const Rep2& r);
Remarks: This constructor shall not participate in overload resolution unless Rep2 is implicitly convertible to rep and
  • treat_­as_­floating_­point_­v<rep> is true or
  • treat_­as_­floating_­point_­v<Rep2> is false.
[Example
:
duration<int, milli> d(3);          // OK
duration<int, milli> d(3.5);        // error
end example
]
Effects: Constructs an object of type duration.
Postconditions: count() == static_­cast<rep>(r).
template <class Rep2, class Period2> constexpr duration(const duration<Rep2, Period2>& d);
Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in the conversion and treat_­as_­floating_­point_­v<rep> is true or both ratio_­divide<Period2, period>​::​den is 1 and treat_­as_­floating_­point_­v<Rep2> is false.
[Note
:
This requirement prevents implicit truncation error when converting between integral-based duration types.
Such a construction could easily lead to confusion about the value of the duration.
end note
]
[Example
:
duration<int, milli> ms(3);
duration<int, micro> us = ms;       // OK
duration<int, milli> ms2 = us;      // error
end example
]
Effects: Constructs an object of type duration, constructing rep_­ from
duration_­cast<duration>(d).count().

23.17.5.2 duration observer [time.duration.observer]

constexpr rep count() const;
Returns: rep_­.

23.17.5.3 duration arithmetic [time.duration.arithmetic]

constexpr common_type_t<duration> operator+() const;
Returns: common_­type_­t<duration>(*this).
constexpr common_type_t<duration> operator-() const;
Returns: common_­type_­t<duration>(-rep_­).
constexpr duration& operator++();
Effects: As if by ++rep_­.
Returns: *this.
constexpr duration operator++(int);
Returns: duration(rep_­++).
constexpr duration& operator--();
Effects: As if by --rep_­.
Returns: *this.
constexpr duration operator--(int);
Returns: duration(rep_­--).
constexpr duration& operator+=(const duration& d);
Effects: As if by: rep_­ += d.count();
Returns: *this.
constexpr duration& operator-=(const duration& d);
Effects: As if by: rep_­ -= d.count();
Returns: *this.
constexpr duration& operator*=(const rep& rhs);
Effects: As if by: rep_­ *= rhs;
Returns: *this.
constexpr duration& operator/=(const rep& rhs);
Effects: As if by: rep_­ /= rhs;
Returns: *this.
constexpr duration& operator%=(const rep& rhs);
Effects: As if by: rep_­ %= rhs;
Returns: *this.
constexpr duration& operator%=(const duration& rhs);
Effects: As if by: rep_­ %= rhs.count();
Returns: *this.

23.17.5.4 duration special values [time.duration.special]

static constexpr duration zero();
Returns: duration(duration_­values<rep>​::​zero()).
static constexpr duration min();
Returns: duration(duration_­values<rep>​::​min()).
static constexpr duration max();
Returns: duration(duration_­values<rep>​::​max()).

23.17.5.5 duration non-member arithmetic [time.duration.nonmember]

In the function descriptions that follow, CD represents the return type of the function.
CR(A, B) represents common_­type_­t<A, B>.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() + CD(rhs).count()).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() - CD(rhs).count()).
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2).
Returns: CD(CD(d).count() * s).
template <class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);
Remarks: This operator shall not participate in overload resolution unless Rep1 is implicitly convertible to CR(Rep1, Rep2).
Returns: d * s.
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() / s).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<Rep1, Rep2> operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(lhs).count() / CD(rhs).count().
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() % s).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() % CD(rhs).count()).

23.17.5.6 duration comparisons [time.duration.comparisons]

In the function descriptions that follow, CT represents common_­type_­t<A, B>, where A and B are the types of the two arguments to the function.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() == CT(rhs).count().
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(lhs == rhs).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() < CT(rhs).count().
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(rhs < lhs).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: rhs < lhs.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(lhs < rhs).

23.17.5.7 duration_­cast [time.duration.cast]

template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: Let CF be ratio_­divide<Period, typename ToDuration​::​period>, and CR be common_­type< typename ToDuration​::​rep, Rep, intmax_­t>​::​type.
  • If CF​::​num == 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(d.count()))
  • otherwise, if CF​::​num != 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
  • otherwise, if CF​::​num == 1 and CF​::​den != 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
  • otherwise, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
[Note
:
This function does not use any implicit conversions; all conversions are done with static_­cast.
It avoids multiplications and divisions when it is known at compile time that one or more arguments is 1.
Intermediate computations are carried out in the widest representation and only converted to the destination representation at the final step.
end note
]
template <class ToDuration, class Rep, class Period> constexpr ToDuration floor(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The greatest result t representable in ToDuration for which t <= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration ceil(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The least result t representable in ToDuration for which t >= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration round(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration, and treat_­as_­floating_­point_­v<typename ToDuration​::​rep> is false.
Returns: The value of ToDuration that is closest to d.
If there are two closest values, then return the value t for which t % 2 == 0.

23.17.5.8 Suffixes for duration literals [time.duration.literals]

This section describes literal suffixes for constructing duration literals.
The suffixes h, min, s, ms, us, ns denote duration values of the corresponding types hours, minutes, seconds, milliseconds, microseconds, and nanoseconds respectively if they are applied to integral literals.
If any of these suffixes are applied to a floating-point literal the result is a chrono​::​duration literal with an unspecified floating-point representation.
If any of these suffixes are applied to an integer literal and the resulting chrono​::​duration value cannot be represented in the result type because of overflow, the program is ill-formed.
[Example
:
The following code shows some duration literals.
using namespace std::chrono_literals;
auto constexpr aday=24h;
auto constexpr lesson=45min;
auto constexpr halfanhour=0.5h;
end example
]
constexpr chrono::hours operator""h(unsigned long long hours); constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);
Returns: A duration literal representing hours hours.
constexpr chrono::minutes operator""min(unsigned long long minutes); constexpr chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);
Returns: A duration literal representing minutes minutes.
constexpr chrono::seconds operator""s(unsigned long long sec); constexpr chrono::duration<unspecified> operator""s(long double sec);
Returns: A duration literal representing sec seconds.
[Note
:
The same suffix s is used for basic_­string but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals.
end note
]
constexpr chrono::milliseconds operator""ms(unsigned long long msec); constexpr chrono::duration<unspecified, milli> operator""ms(long double msec);
Returns: A duration literal representing msec milliseconds.
constexpr chrono::microseconds operator""us(unsigned long long usec); constexpr chrono::duration<unspecified, micro> operator""us(long double usec);
Returns: A duration literal representing usec microseconds.
constexpr chrono::nanoseconds operator""ns(unsigned long long nsec); constexpr chrono::duration<unspecified, nano> operator""ns(long double nsec);
Returns: A duration literal representing nsec nanoseconds.

23.17.5.9 duration algorithms [time.duration.alg]

template <class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
Remarks: This function shall not participate in overload resolution unless numeric_­limits<Rep>​::​is_­signed is true.
Returns: If d >= d.zero(), return d, otherwise return -d.

23.17.6 Class template time_­point [time.point]

template <class Clock, class Duration = typename Clock::duration>
class time_point {
public:
  using clock    = Clock;
  using duration = Duration;
  using rep      = typename duration::rep;
  using period   = typename duration::period;
private:
  duration d_;  // exposition only

public:
  // [time.point.cons], construct
  constexpr time_point();  // has value epoch
  constexpr explicit time_point(const duration& d);  // same as time_­point() + d
  template <class Duration2>
    constexpr time_point(const time_point<clock, Duration2>& t);

  // [time.point.observer], observer
  constexpr duration time_since_epoch() const;

  // [time.point.arithmetic], arithmetic
  constexpr time_point& operator+=(const duration& d);
  constexpr time_point& operator-=(const duration& d);

  // [time.point.special], special values
  static constexpr time_point min();
  static constexpr time_point max();
};
Clock shall meet the Clock requirements ([time.clock.req]).
If Duration is not an instance of duration, the program is ill-formed.

23.17.6.1 time_­point constructors [time.point.cons]

constexpr time_point();
Effects: Constructs an object of type time_­point, initializing d_­ with duration​::​zero().
Such a time_­point object represents the epoch.
constexpr explicit time_point(const duration& d);
Effects: Constructs an object of type time_­point, initializing d_­ with d.
Such a time_­point object represents the epoch + d.
template <class Duration2> constexpr time_point(const time_point<clock, Duration2>& t);
Remarks: This constructor shall not participate in overload resolution unless Duration2 is implicitly convertible to duration.
Effects: Constructs an object of type time_­point, initializing d_­ with t.time_­since_­epoch().

23.17.6.2 time_­point observer [time.point.observer]

constexpr duration time_since_epoch() const;
Returns: d_­.

23.17.6.3 time_­point arithmetic [time.point.arithmetic]

constexpr time_point& operator+=(const duration& d);
Effects: As if by: d_­ += d;
Returns: *this.
constexpr time_point& operator-=(const duration& d);
Effects: As if by: d_­ -= d;
Returns: *this.

23.17.6.4 time_­point special values [time.point.special]

static constexpr time_point min();
Returns: time_­point(duration​::​min()).
static constexpr time_point max();
Returns: time_­point(duration​::​max()).

23.17.6.5 time_­point non-member arithmetic [time.point.nonmember]

template <class Clock, class Duration1, class Rep2, class Period2> constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>> operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs.time_­since_­epoch() + rhs), where CT is the type of the return value.
template <class Rep1, class Period1, class Clock, class Duration2> constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>> operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: rhs + lhs.
template <class Clock, class Duration1, class Rep2, class Period2> constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>> operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs.time_­since_­epoch() - rhs), where CT is the type of the return value.
template <class Clock, class Duration1, class Duration2> constexpr common_type_t<Duration1, Duration2> operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() - rhs.time_­since_­epoch().

23.17.6.6 time_­point comparisons [time.point.comparisons]

template <class Clock, class Duration1, class Duration2> constexpr bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() == rhs.time_­since_­epoch().
template <class Clock, class Duration1, class Duration2> constexpr bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(lhs == rhs).
template <class Clock, class Duration1, class Duration2> constexpr bool operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() < rhs.time_­since_­epoch().
template <class Clock, class Duration1, class Duration2> constexpr bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(rhs < lhs).
template <class Clock, class Duration1, class Duration2> constexpr bool operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: rhs < lhs.
template <class Clock, class Duration1, class Duration2> constexpr bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(lhs < rhs).

23.17.6.7 time_­point_­cast [time.point.cast]

template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns:
time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()))
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: time_­point<Clock, ToDuration>(floor<ToDuration>(tp.time_­since_­epoch())).
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: time_­point<Clock, ToDuration>(ceil<ToDuration>(tp.time_­since_­epoch())).
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> round(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration, and treat_­as_­floating_­point_­v<typename ToDuration​::​rep> is false.
Returns: time_­point<Clock, ToDuration>(round<ToDuration>(tp.time_­since_­epoch())).

23.17.7 Clocks [time.clock]

The types defined in this subclause shall satisfy the TrivialClock requirements ([time.clock.req]).

23.17.7.1 Class system_­clock [time.clock.system]

Objects of class system_­clock represent wall clock time from the system-wide realtime clock.
class system_clock {
public:
  using rep        = see below;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<system_clock>;
  static constexpr bool is_steady = unspecified;

  static time_point now() noexcept;

  // Map to C API
  static time_t      to_time_t  (const time_point& t) noexcept;
  static time_point  from_time_t(time_t t) noexcept;
};
using system_clock::rep = unspecified;
Requires: system_­clock​::​duration​::​min() < system_­clock​::​duration​::​zero() shall be true.

[Note
:
This implies that rep is a signed type.
end note
]
static time_t to_time_t(const time_point& t) noexcept;
Returns: A time_­t object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_­t and time_­point.
It is implementation-defined whether values are rounded or truncated to the required precision.
static time_point from_time_t(time_t t) noexcept;
Returns: A time_­point object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_­t and time_­point.
It is implementation-defined whether values are rounded or truncated to the required precision.

23.17.7.2 Class steady_­clock [time.clock.steady]

Objects of class steady_­clock represent clocks for which values of time_­point never decrease as physical time advances and for which values of time_­point advance at a steady rate relative to real time.
That is, the clock may not be adjusted.
class steady_clock {
public:
  using rep        = unspecified;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<unspecified, duration>;
  static constexpr bool is_steady = true;

  static time_point now() noexcept;
};

23.17.7.3 Class high_­resolution_­clock [time.clock.hires]

Objects of class high_­resolution_­clock represent clocks with the shortest tick period.
high_­resolution_­clock may be a synonym for system_­clock or steady_­clock.
class high_resolution_clock {
public:
  using rep        = unspecified;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<unspecified, duration>;
  static constexpr bool is_steady = unspecified;

  static time_point now() noexcept;
};

23.17.8 Header <ctime> synopsis [ctime.syn]

#define NULL see [support.types.nullptr]
#define CLOCKS_PER_SEC see below
#define TIME_UTC see below

namespace std {
  using size_t = see [support.types.layout];
  using clock_t = see below;
  using time_t = see below;

  struct timespec;
  struct tm;

  clock_t clock();
  double difftime(time_t time1, time_t time0);
  time_t mktime(struct tm* timeptr);
  time_t time(time_t* timer);
  int timespec_get(timespec* ts, int base);
  char* asctime(const struct tm* timeptr);
  char* ctime(const time_t* timer);
  struct tm* gmtime(const time_t* timer);
  struct tm* localtime(const time_t* timer);
  size_t strftime(char* s, size_t maxsize, const char* format, const struct tm* timeptr);
}
The contents of the header <ctime> are the same as the C standard library header <time.h>.223
The functions asctime, ctime, gmtime, and localtime are not required to avoid data races ([res.on.data.races]).
See also: ISO C 7.27.
strftime supports the C conversion specifiers C, D, e, F, g, G, h, r, R, t, T, u, V, and z, and the modifiers E and O.

23.18 Class type_­index [type.index]

23.18.1 Header <typeindex> synopsis [type.index.synopsis]

namespace std {
  class type_index;
  template <class T> struct hash;
  template<> struct hash<type_index>;
}

23.18.2 type_­index overview [type.index.overview]

namespace std {
  class type_index {
  public:
    type_index(const type_info& rhs) noexcept;
    bool operator==(const type_index& rhs) const noexcept;
    bool operator!=(const type_index& rhs) const noexcept;
    bool operator< (const type_index& rhs) const noexcept;
    bool operator<= (const type_index& rhs) const noexcept;
    bool operator> (const type_index& rhs) const noexcept;
    bool operator>= (const type_index& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;
  private:
    const type_info* target;    // exposition only
    // Note that the use of a pointer here, rather than a reference,
    // means that the default copy/move constructor and assignment
    // operators will be provided and work as expected.
  };
}
The class type_­index provides a simple wrapper for type_­info which can be used as an index type in associative containers ([associative]) and in unordered associative containers ([unord]).

23.18.3 type_­index members [type.index.members]

type_index(const type_info& rhs) noexcept;
Effects: Constructs a type_­index object, the equivalent of target = &rhs.
bool operator==(const type_index& rhs) const noexcept;
Returns: *target == *rhs.target.
bool operator!=(const type_index& rhs) const noexcept;
Returns: *target != *rhs.target.
bool operator<(const type_index& rhs) const noexcept;
Returns: target->before(*rhs.target).
bool operator<=(const type_index& rhs) const noexcept;
Returns: !rhs.target->before(*target).
bool operator>(const type_index& rhs) const noexcept;
Returns: rhs.target->before(*target).
bool operator>=(const type_index& rhs) const noexcept;
Returns: !target->before(*rhs.target).
size_t hash_code() const noexcept;
Returns: target->hash_­code().
const char* name() const noexcept;
Returns: target->name().

23.18.4 Hash support [type.index.hash]

template <> struct hash<type_index>;
For an object index of type type_­index, hash<type_­index>()(index) shall evaluate to the same result as index.hash_­code().

23.19 Execution policies [execpol]

23.19.1 In general [execpol.general]

This subclause describes classes that are execution policy types.
An object of an execution policy type indicates the kinds of parallelism allowed in the execution of an algorithm and expresses the consequent requirements on the element access functions.
[Example
:
using namespace std;
vector<int> v = /* ... */;

// standard sequential sort
sort(v.begin(), v.end());

// explicitly sequential sort
sort(execution::seq, v.begin(), v.end());

// permitting parallel execution
sort(execution::par, v.begin(), v.end());

// permitting vectorization as well
sort(execution::par_unseq, v.begin(), v.end());
end example
]
[Note
:
Because different parallel architectures may require idiosyncratic parameters for efficient execution, implementations may provide additional execution policies to those described in this standard as extensions.
end note
]

23.19.2 Header <execution> synopsis [execution.syn]

namespace std {
  // [execpol.type], execution policy type trait
  template<class T> struct is_execution_policy;
  template<class T> inline constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
}

namespace std::execution {
  // [execpol.seq], sequenced execution policy
  class sequenced_policy;

  // [execpol.par], parallel execution policy
  class parallel_policy;

  // [execpol.parunseq], parallel and unsequenced execution policy
  class parallel_unsequenced_policy;

  // [execpol.objects], execution policy objects
  inline constexpr sequenced_policy            seq{ unspecified };
  inline constexpr parallel_policy             par{ unspecified };
  inline constexpr parallel_unsequenced_policy par_unseq{ unspecified };
}

23.19.3 Execution policy type trait [execpol.type]

template<class T> struct is_execution_policy { see below };
is_­execution_­policy can be used to detect execution policies for the purpose of excluding function signatures from otherwise ambiguous overload resolution participation.
is_­execution_­policy<T> shall be a UnaryTypeTrait with a base characteristic of true_­type if T is the type of a standard or implementation-defined execution policy, otherwise false_­type.
[Note
:
This provision reserves the privilege of creating non-standard execution policies to the library implementation.
end note
]
The behavior of a program that adds specializations for is_­execution_­policy is undefined.

23.19.4 Sequenced execution policy [execpol.seq]

class execution::sequenced_policy { unspecified };
The class execution​::​sequenced_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and require that a parallel algorithm's execution may not be parallelized.
During the execution of a parallel algorithm with the execution​::​sequenced_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.5 Parallel execution policy [execpol.par]

class execution::parallel_policy { unspecified };
The class execution​::​parallel_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized.
During the execution of a parallel algorithm with the execution​::​parallel_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.6 Parallel and unsequenced execution policy [execpol.parunseq]

class execution::parallel_unsequenced_policy { unspecified };
The class execution​::​parallel_­unsequenced_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized and vectorized.
During the execution of a parallel algorithm with the execution​::​parallel_­unsequenced_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.7 Execution policy objects [execpol.objects]

inline constexpr execution::sequenced_policy execution::seq{ unspecified }; inline constexpr execution::parallel_policy execution::par{ unspecified }; inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ unspecified };
The header <execution> declares global objects associated with each type of execution policy.