A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://timsong-cpp.github.io/cppwp/n4659/utilities below:

23 General utilities library [utilities]

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


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>     
namespace std {
    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&);
  }

    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>);

    template <class T, class U = T>
    T exchange(T& obj, U&& new_val);

    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;

    template <class T>
    constexpr add_const_t<T>& as_const(T& t) noexcept;
  template <class T>
    void as_const(const T&&) = delete;

    template <class T>
    add_rvalue_reference_t<T> declval() noexcept;  
    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)>;

    template <class T1, class T2>
    struct pair;

    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&&);

    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;

    struct piecewise_construct_t {
    explicit piecewise_construct_t() = default;
  };
  inline constexpr piecewise_construct_t piecewise_construct{};
  template <class... Types> class tuple;        
    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{};

    enum class chars_­format {
    scientific = unspecified,
    fixed = unspecified,
    hex = unspecified,
    general = fixed | scientific
  };



    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);



    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 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);

template <class T> bool operator>(const T& x, const T& y);

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

template <class T> bool operator>=(const T& x, const T& 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>

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 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);   int i = 2;
  shared_ptr<A> sp2 = factory<A>(i, 1.414); }

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&);        A(A&&);           };

void g() {
  A a;
  shared_ptr<A> sp1 = factory<A>(a);                  shared_ptr<A> sp1 = factory<A>(std::move(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;

23.2.6 Function template as_­const [utility.as_const]

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

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.

template <class T> add_rvalue_reference_t<T> declval() noexcept;

Remarks: If this function is odr-used, 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.

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.

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.

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.

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.

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

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.

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.

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.

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>

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.

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

Requires: first shall be swappable with 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);

template <class T1, class T2> constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);

template <class T1, class T2> constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);

template <class T1, class T2> constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);

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);   

a C++ program may contain:

  return make_pair(5, 3.1415926);           

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

tuple_element<1, pair<T1, T2>>::type

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 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. See [pairs].

23.5.2 Header <tuple> synopsis [tuple.syn]
namespace std {
    template <class... Types>
    class tuple;

    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&&...);

    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);

    template <class T> class tuple_size;                    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;       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;

    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;

    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...>&);

    template <class... Types, class Alloc>
    struct uses_allocator<tuple<Types...>, Alloc>;

    template <class... Types>
    void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);

    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:
            EXPLICIT constexpr tuple();
      EXPLICIT constexpr tuple(const Types&...);               template <class... UTypes>
        EXPLICIT constexpr tuple(UTypes&&...);           
      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>&);         template <class U1, class U2>
        EXPLICIT constexpr tuple(pair<U1, U2>&&);        
            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& 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>&);                    template <class U1, class U2>
        tuple& operator=(pair<U1, U2>&&);                   
            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, Ti be the ith type in Types, and Ui be the ith 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<Ti> 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 Ti is not implicitly default-constructible for at least one i. [Note: This behavior can be implemented with a trait that checks whether a const Ti& 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<Ti> is true for all i. The constructor is explicit if and only if is_­convertible_­v<const Ti&, Ti> 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<Ti, Ui&&> is true for all i. The constructor is explicit if and only if is_­convertible_­v<Ui&&, Ti> is false for at least one i.

tuple(const tuple& u) = default;

Requires: is_­copy_­constructible_­v<Ti> 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<Ti> is true for all i.

Effects: For all i, initializes the ith element of *this with std​::​forward<Ti>(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

The constructor is explicit if and only if is_­convertible_­v<const Ui&, Ti> is false for at least one i.

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

Effects: For all i, initializes the ith element of *this with std​::​forward<Ui>(get<i>(u)).

Remarks: This constructor shall not participate in overload resolution unless

The constructor is explicit if and only if is_­convertible_­v<Ui&&, Ti> 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<T0, const U1&> is true and is_­constructible_­v<T1, const U2&> is true.

The constructor is explicit if and only if is_­convertible_­v<const U1&, T0> is false or is_­convertible_­v<const U2&, T1> 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<T0, U1&&> is true and is_­constructible_­v<T1, U2&&> is true.

The constructor is explicit if and only if is_­convertible_­v<U1&&, T0> is false or is_­convertible_­v<U2&&, T1> 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.

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, Ti be the ith type in Types, and Ui be the ith 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<Ti> is true for all i.

tuple& operator=(tuple&& u) noexcept(see below);

Effects: For all i, assigns std​::​forward<Ti>(get<i>(u)) to get<i>(*this).

Remarks: This operator shall be defined as deleted unless is_­move_­assignable_­v<Ti> 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<Ti>

where Ti is the ith type in Types.

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<Ti&, const Ui&> is true for all i.

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

Effects: For all i, assigns std​::​forward<Ui>(get<i>(u)) to get<i>(*this).

Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<Ti&, Ui&&> == true for all i and sizeof...(Types) == sizeof...(UTypes).

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<T0&, const U1&> is true for the first type T0 in Types and is_­assignable_­v<T1&, const U2&> is true for the second type T1 in Types.

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<T0&, U1&&> is true for the first type T0 in Types and is_­assignable_­v<T1&, U2&&> is true for the second type T1 in Types.

23.5.3.3 swap [tuple.swap]

void swap(tuple& rhs) noexcept(see below);

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<Ti>

where Ti is the ith 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 Xi 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 Ui be decay_­t<Ti> for each Ti in TTypes. If Ui is a specialization of reference_­wrapper, then Vi in VTypes is Ui​::​type&, otherwise Vi is Ui.

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++");

end example]

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

In the following paragraphs, let Ti be the ith type in Tuples, Ui be remove_­reference_­t<Ti>, and tpi be the ith parameter in the function parameter pack tpls, where all indexing is zero-based.

Requires: For all i, Ui shall be the type cvi tuple<Argsi...>, where cvi is the (possibly empty) ith cv-qualifier-seq and Argsi is the parameter pack representing the element types in Ui. Let Aik be the kth type in Argsi. For all Aik the following requirements shall be satisfied:

Remarks: The types in CTypes shall be equal to the ordered sequence of the extended types Args0..., Args1..., , Argsn1..., where n is equal to sizeof...(Tuples). Let ei... be the ith ordered sequence of tuple elements of the resulting tuple object corresponding to the type sequence Argsi.

Returns: A tuple object constructed by initializing the kith type element eik in ei... with

get<ki>(std::forward<Ti>(tpi))

for each valid ki and each group ei 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...>) {                  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...>) {       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 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 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 with a member typedef type that names the following type:

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; template <size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>& t) noexcept; 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 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 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);          const int& i2 = get<const int>(t);    const double& d = get<double>(t);   

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)) && ttail < utail), where rtail 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);

template<class... TTypes, class... UTypes> constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

template<class... TTypes, class... UTypes> constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

template<class... TTypes, class... UTypes> constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

[Note: The above definitions for comparison functions do not require ttail (or utail) 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 { };

[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<Ti> is true for all i, where 0i<sizeof...(Types). 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 {
    template <class T>
    class optional;

    struct nullopt_t{see below};
  inline constexpr nullopt_t nullopt(unspecified);

    class bad_optional_access;

    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>&);

    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;

    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>&);

    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);

    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;

        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();

        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&&...);

        void swap(optional&) noexcept(see below);

        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&&) &&;

        void reset() noexcept;

  private:
    T *val;   };

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.

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.

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

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

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.

Postconditions: *this does not contain a value.

optional<T>& operator=(const optional& rhs);

Effects: See Table 35.

Table

35

optional​::​operator=(const optional&)

effects


*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

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 36. The result of the expression bool(rhs) remains unchanged.

Table

36

optional​::​operator=(optional&&)

effects


*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

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).

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);

Effects: See Table 37.

Table

37

optional​::​operator=(const optional<U>&)

effects


*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

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

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

Effects: See Table 38. The result of the expression bool(rhs) remains unchanged.

Table

38

optional​::​operator=(optional<U>&&)

effects


*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

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

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 39.

Table

39

optional​::​swap(optional&)

effects


*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 39.

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.

Remarks: These functions shall be constexpr functions.

constexpr const T& operator*() const&; constexpr T& operator*() &;

Requires: *this contains a value.

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;

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;

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;

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;

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;

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;

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 {
    template <class... Types>
    class variant;

    template <class T> struct variant_size;                     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;    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;

    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;

    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...>&);

    template <class Visitor, class... Variants>
    constexpr see below visit(Visitor&&, Variants&&...);

    struct monostate;

    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;

    template <class... Types>
    void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);

    class bad_variant_access;

    template <class T> struct hash;
  template <class... Types> struct hash<variant<Types...>>;
  template <> struct hash<monostate>;

    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:
            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&&...);

            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();

            variant& operator=(const variant&);
      variant& operator=(variant&&) noexcept(see below);

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

            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&&...);

            constexpr bool valueless_by_exception() const noexcept;
      constexpr size_t index() const noexcept;

            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 Ti be the ith type in Types....

constexpr variant() noexcept(see below);

Effects: Constructs a variant holding a value-initialized value of type T0.

Postconditions: valueless_­by_­exception() is false and index() is 0.

Throws: Any exception thrown by the value-initialization of T0.

Remarks: This function shall be constexpr if and only if the value-initialization of the alternative type T0 would satisfy the requirements for a constexpr function. The expression inside noexcept is equivalent to is_­nothrow_­default_­constructible_­v<T0>. This function shall not participate in overload resolution unless is_­default_­constructible_­v<T0> 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 Ti for all i.

Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<Ti> 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 Ti for all i.

Remarks: The expression inside noexcept is equivalent to the logical AND of is_­nothrow_­move_­constructible_­v<Ti> for all i. This function shall not participate in overload resolution unless is_­move_­constructible_­v<Ti> is true for all i.

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

Let Tj be a type that is determined as follows: build an imaginary function FUN(Ti) for each alternative type Ti. The overload FUN(Tj) selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative Tj which is the type of the contained value after construction.

Effects: Initializes *this to hold the alternative type Tj and direct-initializes the contained value as if direct-non-list-initializing it with std​::​forward<T>(t).

Postconditions: holds_­alternative<Tj>(*this) is true.

Throws: Any exception thrown by the initialization of the selected alternative Tj.

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<Tj, 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<Tj, T>. If Tj'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 TI with the arguments std​::​forward<Args>(args)....

Postconditions: index() is I.

Throws: Any exception thrown by calling the selected constructor of TI.

Remarks: This function shall not participate in overload resolution unless

If TI'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 TI with the arguments il, std​::​forward<Args>(args)....

Postconditions: index() is I.

Remarks: This function shall not participate in overload resolution unless

If TI's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.

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.

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<Ti> == true for all Ti then this destructor shall be a trivial destructor.

23.7.3.3 Assignment [variant.assign]

variant& operator=(const variant& rhs);

Effects:

Postconditions: index() == rhs.index().

Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<Ti> && is_­copy_­assignable_­v<Ti> is true for all i.

variant& operator=(variant&& rhs) noexcept(see below);

Effects:

Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<Ti> && is_­move_­assignable_­v<Ti> is true for all i. The expression inside noexcept is equivalent to: is_­nothrow_­move_­constructible_­v<Ti> && is_­nothrow_­move_­assignable_­v<Ti> for all i.

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

Let Tj be a type that is determined as follows: build an imaginary function FUN(Ti) for each alternative type Ti. The overload FUN(Tj) selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative Tj which is the type of the contained value after assignment.

Effects:

Postconditions: holds_­alternative<Tj>(*this) is true, with Tj selected by the imaginary function overload resolution described above.

Remarks: This function shall not participate in overload resolution unless is_­same_­v<decay_­t<T>, variant> is false, unless is_­assignable_­v<Tj&, T> && is_­constructible_­v<Tj, 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<Tj&, T> && is_nothrow_constructible_v<Tj, T>
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 TI 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<TI, 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 TI 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<TI, 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 Ti shall be swappable ([swappable.requirements]) and is_­move_­constructible_­v<Ti> shall be true for all i.

Effects:

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 Ti or Tj 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 Ti 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<Ti> && is_­nothrow_­swappable_­v<Ti> 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 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 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 with a member typedef type that names the following type:

variant_alternative<I, variant<Types...>>::type

Requires: I < sizeof...(Types).

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<Ti> && is_­swappable_­v<Ti> 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>;

23.7.13 Allocator-related traits [variant.traits]

template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc> : true_type { };

[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 {
    class bad_any_cast;

    class any;

    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.

const char* what() const noexcept override;

Returns: An implementation-defined ntbs.

23.8.3 Class any [any.class]
class any {
public:
    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& operator=(const any& rhs);
  any& operator=(any&& rhs) noexcept;

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

    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;

    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);

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);

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);

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.

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).

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);

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.

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);

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);

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);                                   assert(any_cast<int>(x) == 5);              any_cast<int&>(x) = 10;                     assert(any_cast<int>(x) == 10);

x = "Meow";                                 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");                         string s, s2("Jane");
s = move(any_cast<string&>(x));             assert(s == "Meow");
any_cast<string&>(x) = move(s2);            assert(any_cast<const string&>(x) == "Jane");

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

any_cast<string&>(y);                                                                   

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>   
namespace std {
  template <size_t N> class bitset;

    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:
        class reference {
      friend class bitset;
      reference() noexcept;
    public:
      ~reference() noexcept;
      reference& operator=(bool x) noexcept;                   reference& operator=(const reference&) noexcept;         bool operator~() const noexcept;                         operator bool() const noexcept;                          reference& flip() noexcept;                            };

        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<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);

        constexpr bool operator[](size_t pos) const;           reference operator[](size_t pos);                  
    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;
  };

    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.

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 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.

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.

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.

bitset<N>& operator<<=(size_t pos) noexcept;

Effects: Replaces each bit at position I in *this with a value determined as follows:

bitset<N>& operator>>=(size_t pos) noexcept;

Effects: Replaces each bit at position I in *this with a value determined as follows:

bitset<N>& set() noexcept;

Effects: Sets all bits in *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.

bitset<N>& reset() noexcept;

Effects: Resets all bits in *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.

bitset<N> operator~() const noexcept;

Effects: Constructs an object x of class bitset<N> and initializes it with *this.

bitset<N>& flip() noexcept;

Effects: Toggles all bits in *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.

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.

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.

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;

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;

bool none() const noexcept;

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.

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).

Remarks: For the purpose of determining the presence of a data race, any access or update through the resulting reference potentially accesses or modifies, respectively, the entire underlying bitset.

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);

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:

If no characters are stored in str, calls is.setstate(ios_­base​::​failbit) (which may throw ios_­base​::​failure ([iostate.flags])).

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.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 {
    template <class Ptr> struct pointer_traits;
  template <class T> struct pointer_traits<T*>;

    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;

    void* align(size_t alignment, size_t size, void*& ptr, size_t& space);

    struct allocator_arg_t { explicit allocator_arg_t() = default; };
  inline constexpr allocator_arg_t allocator_arg{};

    template <class T, class Alloc> struct uses_allocator;

    template <class Alloc> struct allocator_traits;

    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;

    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,                                          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,                                                       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,                                        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,                                                     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,                                        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,                                          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,                                        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,                            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,                             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,                                          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,                  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,                               ForwardIterator first, Size n);

    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);

    class bad_weak_ptr;

    template<class T> class shared_ptr;

    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);

    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;

    template<class T>
    void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

    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 D, class T>
    D* get_deleter(const shared_ptr<T>& p) noexcept;

    template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);

    template<class T> class weak_ptr;

    template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

    template<class T = void> struct owner_less;

    template<class T> class enable_shared_from_this;

    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);

    template <class T> struct hash;
  template <class T, class D> struct hash<unique_ptr<T, D>>;
  template <class T> struct hash<shared_ptr<T>>;

    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);

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.

[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]

[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.

pointer_safety get_pointer_safety() noexcept;

Returns: pointer_­safety​::​strict if the implementation has strict pointer 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

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:

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.

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. 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:

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:

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;

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);

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).

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 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, 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 .

23.10.9.2 allocator globals [allocator.globals]

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;

23.10.10 Specialized algorithms [specialized.algorithms]

Throughout this subclause, the names of template parameters are used to express type requirements.

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&.

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);

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);
}
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> 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:

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;

        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();

        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;

        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;

        pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;

        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, 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.

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.

[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, 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, 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());        unique_ptr<int, D> p2(new int, d);          unique_ptr<int, D&> p3(new int, d);         unique_ptr<int, const D&> p4(new int, D());                                             

end example]

unique_ptr(unique_ptr&& u) noexcept;

Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible. 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:

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 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()).

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:

Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_­deleter() = std​::​forward<E>(u.get_­deleter()).

unique_ptr& operator=(nullptr_t) noexcept;

Effects: As if by reset().

Postconditions: get() == nullptr.

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

add_lvalue_reference_t<T> operator*() const;

Requires: get() != nullptr.

pointer operator->() const noexcept;

Requires: get() != nullptr.

[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 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;

        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;

        ~unique_ptr();

        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;

        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;

        pointer release() noexcept;
    template <class U> void reset(U p) noexcept;
    void reset(nullptr_t = nullptr) noexcept;
    void swap(unique_ptr& u) noexcept;

        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.

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

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

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>:

[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>:

[Note: This replaces the overload-resolution specification of the primary template end note]

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

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 that induces a strict weak ordering 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);

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>& x) 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>& x) 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>& x);

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.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;

        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;

        ~weak_ptr();

        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;

        void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

        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>;


    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.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.

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).

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

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

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)); }

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;   };
}

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;

[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;

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 {
    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;

    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;

    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;

    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); 
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.

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;

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

A specialization of class template pmr​::​polymorphic_­allocator conforms to the 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; 
public:
  using value_type = Tp;

    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;

    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);

Effects: Sets memory_­rsrc to r.

[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]

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)).

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]

Let yprime be a tuple constructed from y according to the appropriate rule from the following list:

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;

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;

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:

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;

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().

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:

class monotonic_buffer_resource : public memory_resource {
  memory_resource *upstream_rsrc;   void *current_buffer;             size_t next_buffer_size;        
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;

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;

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]
    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>;     scoped_allocator_adaptor<InnerAllocs...> inner;     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:

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

Effects: Constructs a tuple object xprime from x by the following rules:

and constructs a tuple object yprime from y by the following rules:

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;

23.14 Function objects [function.objects] 23.14.1 Header <functional> synopsis [functional.syn]
namespace std {
    template <class F, class... Args>
    invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
      noexcept(is_nothrow_invocable_v<F, Args...>);

    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;

    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>;

    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>;

    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>;

    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>;

    template <class F>
    unspecified not_fn(F&& f);

    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 {
        see below _1;
    see below _2;
               .
               .
               .
    see below _M;
  }

    template<class R, class T>
    unspecified mem_fn(R T::*) noexcept;

    class bad_function_call;

  template<class> class function;   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;

    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;

    template <class T>
    struct hash;

    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 call wrapper type is a type that holds a callable object and supports a call operation that forwards to that object.

23.14.3 Requirements [func.require]

Define INVOKE(f, t1, t2, ..., tN) as follows:

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 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 :
        using type = T;

        reference_wrapper(T&) noexcept;
    reference_wrapper(T&&) = delete;         reference_wrapper(const reference_wrapper& x) noexcept;

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

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

        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.

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)...). ([func.require])

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;

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;

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;

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;

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;

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;

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;

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;

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;

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;

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;

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;

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;

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;

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] 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;

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;

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;

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] 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;

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;

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;

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;

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.

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)...);              

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)...);   
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;  }

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. 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;      }

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. 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:

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

Requires: is_­constructible_­v<FD, F> shall be true. For each Ti in BoundArgs, is_­constructible_­v<TDi, Ti> shall be true. INVOKE(fd, w1, w2, …, wN) ([func.require]) shall be a valid expression for some values w1, w2, …, wN, 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. The effect of g(u1, u2, …, uM) shall be

INVOKE(fd, std::forward<V1>(v1), std::forward<V2>(v2), …, std::forward<VN>(vN))

where the values and types of the bound arguments v1, v2, …, vN 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 TDi throws an exception.

Throws: Nothing unless the construction of fd or of one of the values tdi throws an exception.

Remarks: The return type shall satisfy the requirements of MoveConstructible. If all of FD and TDi satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible. [Note: This implies that all of FD and TDi 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 Ti in BoundArgs, is_­constructible_­v<TDi, Ti> shall be true. INVOKE(fd, w1, w2, …, wN) shall be a valid expression for some values w1, w2, …, wN, 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. The effect of g(u1, u2, …, uM) shall be

INVOKE<R>(fd, std::forward<V1>(v1), std::forward<V2>(v2), …, std::forward<VN>(vN))

where the values and types of the bound arguments v1, v2, …, vN 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 TDi throws an exception.

Throws: Nothing unless the construction of fd or of one of the values tdi throws an exception.

Remarks: The return type shall satisfy the requirements of MoveConstructible. If all of FD and TDi satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible. [Note: This implies that all of FD and TDi are MoveConstructible. end note]

The values of the bound arguments v1, v2, …, vN and their corresponding types V1, V2, …, VN depend on the types TDi derived from the call to bind and the cv-qualifiers cv of the call wrapper g as follows:

23.14.11.4 Placeholders [func.bind.place]
namespace std::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 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:
        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; 
  template<class R, class... ArgTypes>
  class function<R(ArgTypes...)> {
  public:
    using result_type = R;

        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();

        void swap(function&) noexcept;

        explicit operator bool() const noexcept;

        R operator()(ArgTypes...) const;

        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>;

    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;

    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, given a call signature, allowing functions to be first-class objects.

[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;

function(nullptr_t) noexcept;

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 for argument types ArgTypes... and return type R.

Postconditions: !*this if any of the following hold:

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 &opt noexceptopt for a class type G, then the deduced type is function<R(A...)>.

[Example:

void f() {
  int i{5};
  function g = [&](double) { return i; }; }

end example]

function& operator=(const function& f);

Effects: As if by function(f).swap(*this);

function& operator=(function&& f);

Effects: Replaces the target of *this with the target of f.

function& operator=(nullptr_t) noexcept;

Effects: If *this != nullptr, destroys the target of this.

Postconditions: !(*this).

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

Effects: As if by: function(std​::​forward<F>(f)).swap(*this);

Remarks: This assignment operator shall not participate in overload resolution unless decay_­t<F> is Lvalue-Callable 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);

~function();

Effects: If *this != nullptr, destroys the target of this.

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

R operator()(ArgTypes... args) const;

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;

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;

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 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_;            ForwardIterator1 pat_last_;             BinaryPredicate pred_;                };

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

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_;       RandomAccessIterator1 pat_last_;        Hash hash_;                             BinaryPredicate pred_;                };

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

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_;       RandomAccessIterator1 pat_last_;        Hash hash_;                             BinaryPredicate pred_;                };

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

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. [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:

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 {
    template <intmax_t N, intmax_t D = 1> class ratio;

    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;

    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;

    using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>;    using zepto = ratio<1,     1'000'000'000'000'000'000'000>;    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>;    using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>;  }
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:

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 51, 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

51

— 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");

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.2 Header <chrono> synopsis [time.syn]
namespace std {
  namespace chrono {
        template <class Rep, class Period = ratio<1>> class duration;

        template <class Clock, class Duration = typename Clock::duration> class time_point;
  }

    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 {
        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;

        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);

        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);

        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);

        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>>;

        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);

        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);

        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);

        template <class Rep, class Period>
      constexpr duration<Rep, Period> abs(duration<Rep, Period> d);

        class system_clock;
    class steady_clock;
    class high_resolution_clock;
  }

  inline namespace literals {
    inline namespace chrono_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 52.

In Table 52 C1 and C2 denote clock types. t1 and t2 are values returned by C1​::​now() where the call returning t1 happens before 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

52

— 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:

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_;  public:
    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;

    constexpr rep count() const;

    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);

    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;       duration<long long, milli> d1;      duration<double, ratio<1, 30>>  d2;                                     

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

[Example:

duration<int, milli> d(3);          duration<int, milli> d(3.5);        

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;       duration<int, milli> ms2 = us;      

end example]

Effects: Constructs an object of type duration, constructing rep_­ from
duration_­cast<duration>(d).count().

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_­.

constexpr duration operator++(int);

Returns: duration(rep_­++).

constexpr duration& operator--();

Effects: As if by --rep_­.

constexpr duration operator--(int);

Returns: duration(rep_­--).

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

Effects: As if by: rep_­ += d.count();

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

Effects: As if by: rep_­ -= d.count();

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

Effects: As if by: rep_­ *= rhs;

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

Effects: As if by: rep_­ /= rhs;

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

Effects: As if by: rep_­ %= rhs;

constexpr duration& operator%=(const duration& rhs);

Effects: As if by: rep_­ %= rhs.count();

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).

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);

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);

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);

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.

[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_;  
public:
    constexpr time_point();    constexpr explicit time_point(const duration& d);    template <class Duration2>
    constexpr time_point(const time_point<clock, Duration2>& t);

    constexpr duration time_since_epoch() const;

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

    static constexpr time_point min();
  static constexpr time_point max();
};

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.3 time_­point arithmetic [time.point.arithmetic]

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

Effects: As if by: d_­ += d;

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

Effects: As if by: d_­ -= d;

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);

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);

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);

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);

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] 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;

    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.

See also: ISO C 7.27.

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;                  };
}
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;

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 = /* ... */;

sort(v.begin(), v.end());

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

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

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 {
    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 {
    class sequenced_policy;

    class parallel_policy;

    class parallel_unsequenced_policy;

    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.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4