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
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;
template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
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
the only sign that may appear is a minus sign;
if fmt has chars_format::scientific set but not chars_format::fixed, the otherwise optional exponent part shall appear;
if fmt has chars_format::fixed set but not chars_format::scientific, the optional exponent part shall not appear; and
if fmt is chars_format::hex, the prefix "0x" or "0X" is assumed. [ Example: The string 0x123 is parsed to have the value 0 with remaining characters x123. — end example ]
In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern.
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
sizeof...(Types) == sizeof...(UTypes) and
is_constructible_v<Ti, const Ui&> is true for all i, and
sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
!is_convertible_v<const tuple<U>&, T> && !is_constructible_v<T, const tuple<U>&>
&& !is_same_v<T, U> is true.
The constructor is explicit if and only if is_convertible_v<const 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
sizeof...(Types) == sizeof...(UTypes), and
is_constructible_v<Ti, Ui&&> is true for all i, and
sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
!is_convertible_v<tuple<U>, T> && !is_constructible_v<T, tuple<U>> &&
!is_same_v<T, U> is true.
The constructor is explicit if and only if is_convertible_v<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:
If Ti is deduced as an lvalue reference type, then is_constructible_v<Aik, cviAik&> == true, otherwise
is_constructible_v<Aik, cviAik&&> == true.
Remarks: The types in CTypes shall be equal to the ordered sequence of the extended types Args0..., Args1..., …, Argsn−1..., 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:
for the first specialization, add_const_t<TE>,
for the second specialization, add_volatile_t<TE>, and
for the third specialization, add_cv_t<TE>.
In addition to being available via inclusion of the <tuple> header, the three templates are available when either of the headers <array> or <utility> are included.
23.5.3.7 Element access [tuple.elem]template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>& t) noexcept; template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&& t) noexcept; 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 0≤i<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
is_constructible_v<T, const U&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false, and
is_convertible_v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_convertible_v<const U&, T> is false.
template <class U> EXPLICIT optional(optional<U>&& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std::move(*rhs). bool(rhs) is unchanged.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless
is_constructible_v<T, U&&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false, and
is_convertible_v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_convertible_v<U&&, T> is false.
23.6.3.2 Destructor [optional.dtor]~optional();
Effects: If is_trivially_destructible_v<T> != true and *this contains a value, calls
val->T::~T()
Remarks: If is_trivially_destructible_v<T> == true then this destructor shall be a trivial destructor.
23.6.3.3 Assignment [optional.assign]optional<T>& operator=(nullopt_t) noexcept;
Effects: If *this contains a value, calls val->T::~T() to destroy the contained value; otherwise no effect.
Postconditions: *this does not contain a value.
optional<T>& operator=(const optional& rhs);
Effects: See Table 35.
Table
35—
optional::operator=(const optional&)effects
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
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
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged. If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor. If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment. This function shall not participate in overload resolution unless
is_constructible_v<T, const U&> is true,
is_assignable_v<T&, const U&> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false,
is_convertible_v<const optional<U>&&, T> is false,
is_assignable_v<T&, optional<U>&> is false,
is_assignable_v<T&, optional<U>&&> is false,
is_assignable_v<T&, const optional<U>&> is false, and
is_assignable_v<T&, const optional<U>&&> is false.
template <class U> optional<T>& operator=(optional<U>&& rhs);
Effects: See Table 38. The result of the expression bool(rhs) remains unchanged.
Table
38—
optional::operator=(optional<U>&&)effects
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged. If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor. If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment. This function shall not participate in overload resolution unless
is_constructible_v<T, U> is true,
is_assignable_v<T&, U> is true,
is_constructible_v<T, optional<U>&> is false,
is_constructible_v<T, optional<U>&&> is false,
is_constructible_v<T, const optional<U>&> is false,
is_constructible_v<T, const optional<U>&&> is false,
is_convertible_v<optional<U>&, T> is false,
is_convertible_v<optional<U>&&, T> is false,
is_convertible_v<const optional<U>&, T> is false,
is_convertible_v<const optional<U>&&, T> is false,
is_assignable_v<T&, optional<U>&> is false,
is_assignable_v<T&, optional<U>&&> is false,
is_assignable_v<T&, const optional<U>&> is false, and
is_assignable_v<T&, const optional<U>&&> is false.
template <class... Args> T& emplace(Args&&... args);
Requires: is_constructible_v<T, Args&&...> is true.
Effects: Calls *this = nullopt. Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std::forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
template <class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Effects: Calls *this = nullopt. Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std::forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed. This function shall not participate in overload resolution unless is_constructible_v<T, initializer_list<U>&, Args&&...> is true.
23.6.3.4 Swap [optional.swap]void swap(optional& rhs) noexcept(see below);
Requires: Lvalues of type T shall be swappable and is_move_constructible_v<T> is true.
Effects: See Table 39.
Table
39—
optional::swap(optional&)effects
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;
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
I is less than sizeof...(Types) and
is_constructible_v<TI, Args...> is true.
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
I is less than sizeof...(Types) and
is_constructible_v<TI, initializer_list<U>&, Args...> is true.
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:
If neither *this nor rhs holds a value, there is no effect. Otherwise,
if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value. Otherwise,
if index() == j, assigns the value contained in rhs to the value contained in *this. Otherwise,
if either is_nothrow_copy_constructible_v<Tj> or !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(get<j>(rhs)). Otherwise,
equivalent to operator=(variant(rhs)).
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:
If neither *this nor rhs holds a value, there is no effect. Otherwise,
if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value. Otherwise,
if index() == j, assigns get<j>(std::move(rhs)) to the value contained in *this. Otherwise,
equivalent to emplace<j>(get<j>(std::move(rhs))).
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.
If an exception is thrown during the call to Tj's move construction (with j being rhs.index()), the variant will hold no value.
If an exception is thrown during the call to Tj's move assignment, the state of the contained value is as defined by the exception safety guarantee of Tj's move assignment; index() will be j.
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:
If *this holds a Tj, assigns std::forward<T>(t) to the value contained in *this. Otherwise,
if is_nothrow_constructible_v<Tj, T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to emplace<j>(std::forward<T>(t)). Otherwise,
equivalent to operator=(variant(std::forward<T>(t))).
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>
If an exception is thrown during the assignment of std::forward<T>(t) to the value contained in *this, the state of the contained value and t are as defined by the exception safety guarantee of the assignment expression; valueless_by_exception() will be false.
If an exception is thrown during the initialization of the contained value, the variant object might not hold a value.
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:
if valueless_by_exception() && rhs.valueless_by_exception() no effect. Otherwise,
if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs)) where i is index(). Otherwise,
exchanges values of rhs and *this.
Throws: If index() == rhs.index(), any exception thrown by swap(get<i>(*this), get<i>(rhs)) with i being index(). Otherwise, any exception thrown by the move constructor of 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:
for the first specialization, add_const_t<VA::type>,
for the second specialization, add_volatile_t<VA::type>, and
for the third specialization, add_cv_t<VA::type>.
variant_alternative<I, variant<Types...>>::type
Requires: I < sizeof...(Types).
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>;
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:
If I < pos, the new value is zero;
If I >= pos, the new value is the previous value of the bit at position I - pos.
bitset<N>& operator>>=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
If pos >= N - I, the new value is zero;
If pos < N - I, the new value is the previous value of the bit at position I + pos.
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:
N characters have been extracted and stored;
the next input character is neither is.widen('0') nor is.widen('1') (in which case the input character is not extracted).
If no characters are stored in str, calls is.setstate(ios_base::failbit) (which may throw ios_base::failure ([iostate.flags])).
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:
alignment shall be a power of two
ptr shall represent the address of contiguous storage of at least space bytes
Returns: A null pointer if the requested aligned buffer would not fit into the available space, otherwise the adjusted value of ptr.
[ Note: The function updates its ptr and space arguments so that it can be called repeatedly with possibly different alignment and size arguments for the same buffer. — end note ]
23.10.6 Allocator argument tag [allocator.tag]namespace std { struct allocator_arg_t { explicit allocator_arg_t() = default; }; inline constexpr allocator_arg_t allocator_arg{}; }
The allocator_arg_t struct is an empty structure type used as a unique type to disambiguate constructor and function overloading. Specifically, several types (see tuple [tuple]) have constructors with allocator_arg_t as the first argument, immediately followed by an argument of a type that satisfies the Allocator requirements.
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:
the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or
the last argument of a constructor has type Alloc.
Uses-allocator construction with allocator Alloc refers to the construction of an object obj of type T, using constructor arguments v1, v2, ..., vN of types V1, V2, ..., VN, respectively, and an allocator alloc of type Alloc, according to the following rules:
if uses_allocator_v<T, Alloc> is false and is_constructible_v<T, V1, V2, ..., VN> is true, then obj is initialized as obj(v1, v2, ..., vN);
otherwise, if uses_allocator_v<T, Alloc> is true and is_constructible_v<T, allocator_arg_t, Alloc, V1, V2, ..., VN> is true, then obj is initialized as obj(allocator_arg, alloc, v1, v2, ..., vN);
otherwise, if uses_allocator_v<T, Alloc> is true and is_constructible_v<T, V1, V2, ..., VN, Alloc> is true, then obj is initialized as obj(v1, v2, ..., vN, alloc);
otherwise, the request for uses-allocator construction is ill-formed. [ Note: An error will result if uses_allocator_v<T, Alloc> is true but the specific constructor does not take an allocator. This definition prevents a silent failure to pass the allocator to an element. — end note ]
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;
Throughout this subclause, the names of template parameters are used to express type requirements.
If an algorithm's template parameter is named InputIterator, the template argument shall satisfy the requirements of an input iterator.
If an algorithm's template parameter is named ForwardIterator, the template argument shall satisfy the requirements of a forward iterator, and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.
Unless otherwise specified, if an exception is thrown in the following algorithms there are no effects.
23.10.10.1 addressof [specialized.addressof]template <class T> constexpr T* addressof(T& r) noexcept;
Returns: The actual address of the object or function referenced by r, even in the presence of an overloaded operator&.
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:
u2.p is equal to the pre-transfer u.p,
u.p is equal to nullptr, and
if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete. [ Note: A deleter's state need never be copied, only moved or swapped as ownership is transferred. — end note ]
Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable. The template parameter T of unique_ptr may be an incomplete type.
[ Note: The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function. — end note ]
namespace std { template<class T> struct default_delete; template<class T> struct default_delete<T[]>; template<class T, class D = default_delete<T>> class unique_ptr; template<class T, class D> class unique_ptr<T[], D>; template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); template<class T> unique_ptr<T> make_unique(size_t n); template<class T, class... Args> unspecified make_unique(Args&&...) = delete; template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; template<class T1, class D1, class T2, class D2> bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2> bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; template <class T, class D> bool operator<(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<=(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator>(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>(nullptr_t, const unique_ptr<T, D>& y); template <class T, class D> bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>=(nullptr_t, const unique_ptr<T, D>& y); }23.11.1.1 Default deleters [unique.ptr.dltr] 23.11.1.1.1 In general [unique.ptr.dltr.general]
The class template default_delete serves as the default deleter (destruction policy) for the class template unique_ptr.
The template parameter T of default_delete may be an incomplete type.
23.11.1.1.2 default_delete [unique.ptr.dltr.dflt]namespace std { template <class T> struct default_delete { constexpr default_delete() noexcept = default; template <class U> default_delete(const default_delete<U>&) noexcept; void operator()(T*) const; }; }
template <class U> default_delete(const default_delete<U>& other) noexcept;
Effects: Constructs a default_delete object from another default_delete<U> object.
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T*.
void operator()(T* ptr) const;
Effects: Calls delete on ptr.
Remarks: If T is an incomplete type, the program is ill-formed.
23.11.1.1.3 default_delete<T[]> [unique.ptr.dltr.dflt1]namespace std { template <class T> struct default_delete<T[]> { constexpr default_delete() noexcept = default; template <class U> default_delete(const default_delete<U[]>&) noexcept; template <class U> void operator()(U* ptr) const; }; }
template <class U> default_delete(const default_delete<U[]>& other) noexcept;
Effects: constructs a default_delete object from another default_delete<U[]> object.
Remarks: This constructor shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].
template <class U> void operator()(U* ptr) const;
Effects: Calls delete[] on ptr.
Remarks: If U is an incomplete type, the program is ill-formed. This function shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].
23.11.1.2 unique_ptr for single objects [unique.ptr.single]namespace std { template <class T, class D = default_delete<T>> class unique_ptr { public: using pointer = see below; using element_type = T; using deleter_type = D; 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:
unique_ptr<U, E>::pointer is implicitly convertible to pointer,
U is not an array type, and
either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Effects: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter. [ Note: The deleter constructor can be implemented with std::forward<E>. — end note ]
Postconditions: get() yields the value u.get() yielded before the construction. get_deleter() returns a reference to the stored deleter that was constructed from u.get_deleter().
23.11.1.2.2 unique_ptr destructor [unique.ptr.single.dtor]~unique_ptr();
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions. [ Note: The use of default_delete requires T to be a complete type. — end note ]
Effects: If get() == nullptr there are no effects. Otherwise get_deleter()(get()).
23.11.1.2.3 unique_ptr assignment [unique.ptr.single.asgn]unique_ptr& operator=(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable 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:
unique_ptr<U, E>::pointer is implicitly convertible to pointer, and
U is not an array type, and
is_assignable_v<D&, E&&> is true.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_deleter() = std::forward<E>(u.get_deleter()).
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.
Conversions between different types of unique_ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms of unique_ptr, produce an ill-formed program.
Pointers to types derived from T are rejected by the constructors, and by reset.
The observers operator* and operator-> are not provided.
The indexing observer operator[] is provided.
The default deleter will call delete[].
Descriptions are provided below only for members that differ from the primary template.
The template argument T shall be a complete type.
23.11.1.3.1 unique_ptr constructors [unique.ptr.runtime.ctor]template <class U> explicit unique_ptr(U p) noexcept;
This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer except that it additionally shall not participate in overload resolution unless
U is the same type as pointer, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept;
These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter except that they shall not participate in overload resolution unless either
U is the same type as pointer,
U is nullptr_t, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
This constructor behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_ptr<U, E>:
U is an array type, and
pointer is the same type as element_type*, and
UP::pointer is the same type as UP::element_type*, and
UP::element_type(*)[] is convertible to element_type(*)[], and
either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
[ Note: This replaces the overload-resolution specification of the primary template — end note ]
23.11.1.3.2 unique_ptr assignment [unique.ptr.runtime.asgn]template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u)noexcept;
This operator behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_ptr<U, E>:
U is an array type, and
pointer is the same type as element_type*, and
UP::pointer is the same type as UP::element_type*, and
UP::element_type(*)[] is convertible to element_type(*)[], and
is_assignable_v<D&, E&&> is true.
[ Note: This replaces the overload-resolution specification of the primary template — end note ]
23.11.1.3.4 unique_ptr modifiers [unique.ptr.runtime.modifiers]void reset(nullptr_t p = nullptr) noexcept;
Effects: Equivalent to reset(pointer()).
template <class U> void reset(U p) noexcept;
This function behaves the same as the reset member of the primary template, except that it shall not participate in overload resolution unless either
U is the same type as pointer, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
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
x.owner_before(y) defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by owner_before, !a.owner_before(b) && !b.owner_before(a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
The class template owner_less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std { template<class T = void> struct owner_less; template<class T> struct owner_less<shared_ptr<T>> { bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept; bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<class T> struct owner_less<weak_ptr<T>> { bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept; bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept; bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept; }; template<> struct owner_less<void> { template<class T, class U> bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U> bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept; template<class T, class U> bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept; template<class T, class U> bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept; using is_transparent = unspecified; }; }
operator()(x, y) shall return x.owner_before(y). [ Note: Note that
operator() defines a strict weak ordering as defined in [alg.sorting];
under the equivalence relation defined by operator(), !operator()(a, b) && !operator()(b, a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.
— end note ]
23.11.2.5 Class template enable_shared_from_this [util.smartptr.enab]A class T can inherit from enable_shared_from_this<T> to inherit the shared_from_this member functions that obtain a shared_ptr instance pointing to *this.
[ Example:
struct X: public enable_shared_from_this<X> { }; int main() { shared_ptr<X> p(new X); shared_ptr<X> q = p->shared_from_this(); assert(p == q); assert(!p.owner_before(q) && !q.owner_before(p)); }
— 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;
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;
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 ]
If uses_allocator_v<T1,memory_resource*> is false
and is_constructible_v<T1,Args1...> is true,
then xprime is x.
Otherwise, if uses_allocator_v<T1,memory_resource*> is true
and is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true,
then xprime is tuple_cat(make_tuple(allocator_arg, resource()), std::move(x)).
Otherwise, if uses_allocator_v<T1,memory_resource*> is true
and is_constructible_v<T1,Args1...,memory_resource*> is true,
then xprime is tuple_cat(std::move(x), make_tuple(resource())).
Otherwise the program is ill formed.
Let yprime be a tuple constructed from y according to the appropriate rule from the following list:
If uses_allocator_v<T2,memory_resource*> is false
and is_constructible_v<T2,Args2...> is true,
then yprime is y.
Otherwise, if uses_allocator_v<T2,memory_resource*> is true
and is_constructible_v<T2,allocator_arg_t,memory_resource*,Args2...> is true,
then yprime is tuple_cat(make_tuple(allocator_arg, resource()), std::move(y)).
Otherwise, if uses_allocator_v<T2,memory_resource*> is true
and is_constructible_v<T2,Args2...,memory_resource*> is true,
then yprime is tuple_cat(std::move(y), make_tuple(resource())).
Otherwise the program is ill formed.
Then, using piecewise_construct, xprime, and yprime as the constructor arguments, this function constructs a pair<T1, T2> object in the storage whose address is represented by p.
template <class T1, class T2> void construct(pair<T1,T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(std::forward<U>(x)), forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, const pair<U, V>& pr);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(pr.first), forward_as_tuple(pr.second));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, pair<U, V>&& pr);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(std::forward<U>(pr.first)), forward_as_tuple(std::forward<V>(pr.second)));
template <class T> void destroy(T* p);
Effects: As if by p->~T().
polymorphic_allocator select_on_container_copy_construction() const;
Returns: polymorphic_allocator().
[ Note: The memory resource is not propagated. — end note ]
memory_resource* resource() const;
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;
memory_resource* new_delete_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_resource that can serve as a resource for allocating memory using ::operator new and ::operator delete. The same value is returned every time this function is called. For a return value p and a memory resource r, p->is_equal(r) returns &r == p.
memory_resource* null_memory_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_resource for which allocate() always throws bad_alloc and for which deallocate() has no effect. The same value is returned every time this function is called. For a return value p and a memory resource r, p->is_equal(r) returns &r == p.
The default memory resource pointer is a pointer to a memory resource that is used by certain facilities when an explicit memory resource is not supplied through the interface. Its initial value is the return value of new_delete_resource().
memory_resource* set_default_resource(memory_resource* r) noexcept;
Effects: If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_delete_resource().
Postconditions: get_default_resource() == r.
Returns: The previous value of the default memory resource pointer.
Remarks: Calling the set_default_resource and get_default_resource functions shall not incur a data race. A call to the set_default_resource function shall synchronize with subsequent calls to the set_default_resource and get_default_resource functions.
memory_resource* get_default_resource() noexcept;
Returns: The current value of the default memory resource pointer.
23.12.5 Pool resource classes [mem.res.pool] 23.12.5.1 Classes synchronized_pool_resource and unsynchronized_pool_resource [mem.res.pool.overview]The synchronized_pool_resource and unsynchronized_pool_resource classes (collectively called pool resource classes) are general-purpose memory resources having the following qualities:
Each resource frees its allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
A pool resource consists of a collection of pools, serving requests for different block sizes. Each individual pool manages a collection of chunks that are in turn divided into blocks of uniform size, returned via calls to do_allocate. Each call to do_allocate(size, alignment) is dispatched to the pool serving the smallest blocks accommodating at least size bytes.
When a particular pool is exhausted, allocating a block from that pool results in the allocation of an additional chunk of memory from the upstream allocator (supplied at construction), thus replenishing the pool. With each successive replenishment, the chunk size obtained increases geometrically. [ Note: By allocating memory in chunks, the pooling strategy increases the chance that consecutive allocations will be close together in memory. — end note ]
Allocation requests that exceed the largest block size of any pool are fulfilled directly from the upstream allocator.
A pool_options struct may be passed to the pool resource constructors to tune the largest block size and the maximum chunk size.
A synchronized_pool_resource may be accessed from multiple threads without external synchronization and may have thread-specific pools to reduce synchronization costs. An unsynchronized_pool_resource class may not be accessed from multiple threads simultaneously and thus avoids the cost of synchronization entirely in single-threaded applications.
struct pool_options { size_t max_blocks_per_chunk = 0; size_t largest_required_pool_block = 0; }; class synchronized_pool_resource : public memory_resource { public: synchronized_pool_resource(const pool_options& opts, memory_resource* upstream); synchronized_pool_resource() : synchronized_pool_resource(pool_options(), get_default_resource()) {} explicit synchronized_pool_resource(memory_resource* upstream) : synchronized_pool_resource(pool_options(), upstream) {} explicit synchronized_pool_resource(const pool_options& opts) : synchronized_pool_resource(opts, get_default_resource()) {} synchronized_pool_resource(const synchronized_pool_resource&) = delete; virtual ~synchronized_pool_resource(); synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete; void release(); memory_resource* upstream_resource() const; pool_options options() const; protected: void *do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void *p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; }; class unsynchronized_pool_resource : public memory_resource { public: unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream); unsynchronized_pool_resource() : unsynchronized_pool_resource(pool_options(), get_default_resource()) {} explicit unsynchronized_pool_resource(memory_resource* upstream) : unsynchronized_pool_resource(pool_options(), upstream) {} explicit unsynchronized_pool_resource(const pool_options& opts) : unsynchronized_pool_resource(opts, get_default_resource()) {} unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete; virtual ~unsynchronized_pool_resource(); unsynchronized_pool_resource& operator=(const unsynchronized_pool_resource&) = delete; void release(); memory_resource *upstream_resource() const; pool_options options() const; protected: void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; };23.12.5.2 pool_options data members [mem.res.pool.options]
The members of pool_options comprise a set of constructor options for pool resources. The effect of each option on the pool resource behavior is described below:
size_t max_blocks_per_chunk;
The maximum number of blocks that will be allocated at once from the upstream memory resource ([mem.res.monotonic.buffer]) to replenish a pool. If the value of max_blocks_per_chunk is zero or is greater than an implementation-defined limit, that limit is used instead. The implementation may choose to use a smaller value than is specified in this field and may use different values for different pools.
size_t largest_required_pool_block;
The largest allocation size that is required to be fulfilled using the pooling mechanism. Attempts to allocate a single block larger than this threshold will be allocated directly from the upstream memory resource. If largest_required_pool_block is zero or is greater than an implementation-defined limit, that limit is used instead. The implementation may choose a pass-through threshold larger than specified in this field.
23.12.5.3 Pool resource constructors and destructors [mem.res.pool.ctor]synchronized_pool_resource(const pool_options& opts, memory_resource* upstream); unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
Requires: upstream is the address of a valid memory resource.
Effects: Constructs a pool resource object that will obtain memory from upstream whenever the pool resource is unable to satisfy a memory request from its own internal data structures. The resulting object will hold a copy of upstream, but will not own the resource to which upstream points. [ Note: The intention is that calls to upstream->allocate() will be substantially fewer than calls to this->allocate() in most cases. — end note ] The behavior of the pooling mechanism is tuned according to the value of the opts argument.
Throws: Nothing unless upstream->allocate() throws. It is unspecified if, or under what conditions, this constructor calls upstream->allocate().
virtual ~synchronized_pool_resource(); virtual ~unsynchronized_pool_resource();
Effects: Calls release().
23.12.5.4 Pool resource members [mem.res.pool.mem]void release();
Effects: Calls upstream_resource()->deallocate() as necessary to release all allocated memory. [ Note: The memory is released back to upstream_resource() even if deallocate has not been called for some of the allocated blocks. — end note ]
memory_resource* upstream_resource() const;
Returns: The value of the upstream argument provided to the constructor of this object.
pool_options options() const;
Returns: The options that control the pooling behavior of this resource. The values in the returned struct may differ from those supplied to the pool resource constructor in that values of zero will be replaced with implementation-defined defaults, and sizes may be rounded to unspecified granularity.
void* do_allocate(size_t bytes, size_t alignment) override;
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:
A call to deallocate has no effect, thus the amount of memory consumed increases monotonically until the resource is destroyed.
The program can supply an initial buffer, which the allocator uses to satisfy memory requests.
When the initial buffer (if any) is exhausted, it obtains additional buffers from an upstream memory resource supplied at construction. Each additional buffer is larger than the previous one, following a geometric progression.
It is intended for access from one thread of control at a time. Specifically, calls to allocate and deallocate do not synchronize with one another.
It frees the allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
class monotonic_buffer_resource : public memory_resource { memory_resource *upstream_rsrc; 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:
If uses_allocator_v<T, inner_allocator_type> is false and is_constructible_v<T,
Args...> is true, calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, std::forward<Args>(args)...)
Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is true, calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, allocator_arg, inner_allocator(), std::forward<Args>(args)...)
Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and is_constructible_v<T, Args..., inner_allocator_type&> is true, calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, std::forward<Args>(args)..., inner_allocator())
Otherwise, the program is ill-formed. [ Note: An error will result if uses_allocator evaluates to true but the specific constructor does not take an allocator. This definition prevents a silent failure to pass an inner allocator to a contained element. — end note ]
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
Effects: Constructs a tuple object xprime from x by the following rules:
If uses_allocator_v<T1, inner_allocator_type> is false and is_constructible_v<T1,
Args1...> is true, then xprime is x.
Otherwise, if uses_allocator_v<T1, inner_allocator_type> is true and is_constructible_v<T1, allocator_arg_t, inner_allocator_type&, Args1...> is true, then xprime is:
tuple_cat( tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()), std::move(x))
Otherwise, if uses_allocator_v<T1, inner_allocator_type> is true and is_constructible_v<T1, Args1..., inner_allocator_type&> is true, then xprime is:
tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator()))
Otherwise, the program is ill-formed.
and constructs a tuple object yprime from y by the following rules:
If uses_allocator_v<T2, inner_allocator_type> is false and is_constructible_v<T2,
Args2...> is true, then yprime is y.
Otherwise, if uses_allocator_v<T2, inner_allocator_type> is true and is_constructible_v<T2, allocator_arg_t, inner_allocator_type&, Args2...> is true, then yprime is:
tuple_cat( tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()), std::move(y))
Otherwise, if uses_allocator_v<T2, inner_allocator_type> is true and is_constructible_v<T2, Args2..., inner_allocator_type&> is true, then yprime is:
tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator()))
Otherwise, the program is ill-formed.
then calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, piecewise_construct, std::move(xprime), std::move(yprime))
template <class T1, class T2> void construct(pair<T1, T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(std::forward<U>(x)), forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, const pair<U, V>& x);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(x.first), forward_as_tuple(x.second));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x);
Effects: Equivalent to:
construct(p, piecewise_construct, forward_as_tuple(std::forward<U>(x.first)), forward_as_tuple(std::forward<V>(x.second)));
template <class T> void destroy(T* p);
Effects: Calls OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p).
scoped_allocator_adaptor select_on_container_copy_construction() const;
Returns: A new scoped_allocator_adaptor object where each allocator A in the adaptor is initialized from the result of calling allocator_traits<A>::select_on_container_copy_construction() on the corresponding allocator in *this.
23.13.5 Scoped allocator operators [scoped.adaptor.operators]template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: If sizeof...(InnerAllocs) is zero,
a.outer_allocator() == b.outer_allocator()
otherwise
a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
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:
(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and is_base_of_v<T, decay_t<decltype(t1)>> is true;
(t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of a class T and decay_t<decltype(t1)> is a specialization of reference_wrapper;
((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;
t1.*f when N == 1 and f is a pointer to data member of a class T and is_base_of_v<T, decay_t<decltype(t1)>> is true;
t1.get().*f when N == 1 and f is a pointer to data member of a class T and decay_t<decltype(t1)> is a specialization of reference_wrapper;
(*t1).*f when N == 1 and f is a pointer to data member of a class T and t1 does not satisfy the previous two items;
f(t1, t2, ..., tN) in all other cases.
Define INVOKE<R>(f, t1, t2, ..., tN) as static_cast<void>(INVOKE(f, t1, t2, ..., tN)) if R is cv void, otherwise INVOKE(f, t1, t2, ..., tN) implicitly converted to R.
Every call wrapper 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;
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:
FD is the type decay_t<F>,
fd is an lvalue of type FD constructed from std::forward<F>(f),
Ti is the ith type in the template parameter pack BoundArgs,
TDi is the type decay_t<Ti>,
ti is the ith argument in the function parameter pack bound_args,
tdi is an lvalue of type TDi constructed from std::forward<Ti>(ti),
Uj is the jth deduced type of the UnBoundArgs&&... parameter of the forwarding call wrapper, and
uj is the jth argument associated with Uj.
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:
if TDi is reference_wrapper<T>, the argument is tdi.get() and its type Vi is T&;
if the value of is_bind_expression_v<TDi> is true, the argument is tdi(std::forward<Uj>(uj)...) and its type Vi is invoke_result_t<TDi cv &, Uj...>&&;
if the value j of is_placeholder_v<TDi> is not zero, the argument is std::forward<Uj>(uj) and its type Vi is Uj&&;
otherwise, the value is tdi and its type Vi is TDi cv &.
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:
f is a null function pointer value.
f is a null member pointer value.
F is an instance of the function class template, and !f.
Otherwise, *this targets a copy of f initialized with std::move(f). [ Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f is an object holding only a pointer or reference to an object and a member function pointer. — end note ]
Throws: shall not throw exceptions when f is a function pointer or a reference_wrapper<T> for some T. Otherwise, may throw bad_alloc or any exception thrown by F's copy or move constructor.
template<class F> function(F) -> function<see below>;
Remarks: This deduction guide participates in overload resolution only if &F::operator() is well-formed when treated as an unevaluated operand. In that case, if decltype(&F::operator()) is of the form R(G::*)(A...) cv &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;
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
ForwardIterator,
ForwardIterator1,
ForwardIterator2,
RandomAccessIterator,
RandomAccessIterator1,
RandomAccessIterator2, and
BinaryPredicate
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
i == search(first, last, pat_first_, pat_last_, pred_), and
if i == last, then j == last, otherwise j == next(i, distance(pat_first_, pat_last_)).
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
i is the first iterator in the range [first, last - (pat_last_ - pat_first_)) such that for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds: pred(*(i + n), *(pat_first_ + n)) != false, and
j == next(i, distance(pat_first_, pat_last_)).
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty, otherwise returns make_pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate.
23.14.14.3 Class template boyer_moore_horspool_searcher [func.search.bmh]template <class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher { public: boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template <class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; 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
i is the first iterator i in the range [first, last - (pat_last_ - pat_first_)) such that for every non-negative integer n less than pat_last_ - pat_first_ the following condition holds: pred(*(i + n), *(pat_first_ + n)) != false, and
j == next(i, distance(pat_first_, pat_last_)).
Returns make_pair(first, first) if [pat_first_, pat_last_) is empty, otherwise returns make_pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_last_ - pat_first_) applications of the predicate.
23.14.15 Class template hash [unord.hash]The unordered associative containers defined in [unord] use specializations of the class template hash ([functional.syn]) as the default hash function.
Each specialization of hash is either enabled or disabled, as described below. [ Note: Enabled specializations meet the requirements of Hash, and disabled specializations do not. — end note ] Each header that declares the template hash provides enabled specializations of hash for nullptr_t and all cv-unqualified arithmetic, enumeration, and pointer types. For any type Key for which neither the library nor the user provides an explicit or partial specialization of the class template hash, hash<Key> is disabled.
If the library provides an explicit or partial specialization of hash<Key>, that specialization is enabled except as noted otherwise, and its member functions are noexcept except as noted otherwise.
If H is a disabled specialization of hash, these values are false: is_default_constructible_v<H>, is_copy_constructible_v<H>, is_move_constructible_v<H>, is_copy_assignable_v<H>, and is_move_assignable_v<H>. Disabled specializations of hash are not function object types. [ Note: This means that the specialization of hash exists, but any attempts to use it as a Hash will be ill-formed. — end note ]
An enabled specialization hash<Key> will:
satisfy the Hash requirements, with Key as the function call argument type, the DefaultConstructible requirements, the CopyAssignable requirements,
be swappable for lvalues,
satisfy the requirement that if k1 == k2 is true, h(k1) == h(k2) is also true, where h is an object of type hash<Key> and k1 and k2 are objects of type Key;
satisfy the requirement that the expression h(k), where h is an object of type hash<Key> and k is an object of type Key, shall not throw an exception unless hash<Key> is a user-defined specialization that depends on at least one user-defined type.
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:
num shall have the value sign(N) * sign(D) * abs(N) / gcd.
den shall have the value abs(D) / gcd.
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
[ 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>> { };
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
[ Note: The relative difference in durations between those reported by a given clock and the SI definition is a measure of the quality of implementation. — end note ]
A type TC meets the TrivialClock requirements if:
TC satisfies the Clock requirements,
the types TC::rep, TC::duration, and TC::time_point satisfy the requirements of EqualityComparable, LessThanComparable, DefaultConstructible, CopyConstructible, CopyAssignable, Destructible, and the requirements of numeric types. [ Note: This means, in particular, that operations on these types will not throw exceptions. — end note ]
lvalues of the types TC::rep, TC::duration, and TC::time_point are swappable,
the function TC::now() does not throw exceptions, and
the type TC::time_point::clock meets the TrivialClock requirements, recursively.
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
treat_as_floating_point_v<rep> is true or
treat_as_floating_point_v<Rep2> is false.
[ 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().
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);
template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: Let CF be ratio_divide<Period, typename ToDuration::period>, and CR be common_type< typename ToDuration::rep, Rep, intmax_t>::type.
If CF::num == 1 and CF::den == 1, returns
ToDuration(static_cast<typename ToDuration::rep>(d.count()))
otherwise, if CF::num != 1 and CF::den == 1, returns
ToDuration(static_cast<typename ToDuration::rep>( static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
otherwise, if CF::num == 1 and CF::den != 1, returns
ToDuration(static_cast<typename ToDuration::rep>( static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
otherwise, returns
ToDuration(static_cast<typename ToDuration::rep>( static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
[ Note: This function does not use any implicit conversions; all conversions are done with static_cast. It avoids multiplications and divisions when it is known at compile time that one or more arguments is 1. Intermediate computations are carried out in the widest representation and only converted to the destination representation at the final step. — end note ]
template <class ToDuration, class Rep, class Period> constexpr ToDuration floor(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The greatest result t representable in ToDuration for which t <= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration ceil(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The least result t representable in ToDuration for which t >= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration round(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration, and treat_as_floating_point_v<typename ToDuration::rep> is false.
Returns: The value of ToDuration that is closest to d. If there are two closest values, then return the value t for which t % 2 == 0.
23.17.5.8 Suffixes for duration literals [time.duration.literals]This section describes literal suffixes for constructing duration literals. The suffixes h, min, s, ms, us, ns denote duration values of the corresponding types hours, minutes, seconds, milliseconds, microseconds, and nanoseconds respectively if they are applied to integral literals.
If any of these suffixes are applied to a floating-point literal the result is a chrono::duration literal with an unspecified floating-point representation.
If any of these suffixes are applied to an integer literal and the resulting chrono::duration value cannot be represented in the result type because of overflow, the program is ill-formed.
[ Example: The following code shows some duration literals.
using namespace std::chrono_literals; auto constexpr aday=24h; auto constexpr lesson=45min; auto constexpr halfanhour=0.5h;
— end example ]
constexpr chrono::hours operator""h(unsigned long long hours); constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);
Returns: A duration literal representing hours hours.
constexpr chrono::minutes operator""min(unsigned long long minutes); constexpr chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);
Returns: A duration literal representing minutes minutes.
constexpr chrono::seconds operator""s(unsigned long long sec); constexpr chrono::duration<unspecified> operator""s(long double sec);
Returns: A duration literal representing sec seconds.
[ Note: The same suffix s is used for basic_string but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals. — end note ]
constexpr chrono::milliseconds operator""ms(unsigned long long msec); constexpr chrono::duration<unspecified, milli> operator""ms(long double msec);
Returns: A duration literal representing msec milliseconds.
constexpr chrono::microseconds operator""us(unsigned long long usec); constexpr chrono::duration<unspecified, micro> operator""us(long double usec);
Returns: A duration literal representing usec microseconds.
constexpr chrono::nanoseconds operator""ns(unsigned long long nsec); constexpr chrono::duration<unspecified, nano> operator""ns(long double nsec);
Returns: A duration literal representing nsec nanoseconds.
23.17.5.9 duration algorithms [time.duration.alg]template <class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
Remarks: This function shall not participate in overload resolution unless numeric_limits<Rep>::is_signed is true.
Returns: If d >= d.zero(), return d, otherwise return -d.
23.17.6 Class template time_point [time.point]template <class Clock, class Duration = typename Clock::duration> class time_point { public: using clock = Clock; using duration = Duration; using rep = typename duration::rep; using period = typename duration::period; private: duration d_; 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);
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;
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