Subclause | Header | |
Utility components | <utility> | |
Compile-time integer sequences | ||
Pairs | ||
Tuples | <tuple> | |
Optional objects | <optional> | |
Variants | <variant> | |
Storage for any type | <any> | |
Fixed-size sequences of bits | <bitset> | |
Memory | <cstdlib>, <memory> | |
Smart pointers | <memory> | |
Memory resources | <memory_resource> | |
Scoped allocators | <scoped_allocator> | |
Function objects | <functional> | |
Type traits | <type_traits> | |
Compile-time rational arithmetic | <ratio> | |
Type indexes | <typeindex> | |
Execution policies | <execution> | |
Primitive numeric conversions | <charconv> | |
Formatting | <format> |
#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [utility.swap], swap template<class T> constexpr void swap(T& a, T& b) noexcept(see below); template<class T, size_t N> constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>); // [utility.exchange], exchange template<class T, class U = T> constexpr T exchange(T& obj, U&& new_val); // [forward], forward/move template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept; template<class T> constexpr remove_reference_t<T>&& move(T&&) noexcept; template<class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept; // [utility.as.const], as_const template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept; template<class T> void as_const(const T&&) = delete; // [declval], declval template<class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand // [utility.intcmp], integer comparison functions template<class T, class U> constexpr bool cmp_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_not_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_less(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_greater(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_less_equal(T t, U u) noexcept; template<class T, class U> constexpr bool cmp_greater_equal(T t, U u) noexcept; template<class R, class T> constexpr bool in_range(T t) noexcept; // [intseq], compile-time integer sequences template<class T, T...> struct integer_sequence; template<size_t... I> using index_sequence = integer_sequence<size_t, I...>; template<class T, T N> using make_integer_sequence = integer_sequence<T, see below>; template<size_t N> using make_index_sequence = make_integer_sequence<size_t, N>; template<class... T> using index_sequence_for = make_index_sequence<sizeof...(T)>; // [pairs], class template pair template<class T1, class T2> struct pair; // [pairs.spec], pair specialized algorithms template<class T1, class T2> constexpr bool operator==(const pair<T1, T2>&, const pair<T1, T2>&); template<class T1, class T2> constexpr common_comparison_category_t<synth-three-way-result<T1>, synth-three-way-result<T2>> operator<=>(const pair<T1, T2>&, const pair<T1, T2>&); template<class T1, class T2> constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); template<class T1, class T2> constexpr see below make_pair(T1&&, T2&&); // [pair.astuple], tuple-like access to pair template<class T> struct tuple_size; template<size_t I, class T> struct tuple_element; template<class T1, class T2> struct tuple_size<pair<T1, T2>>; template<size_t I, class T1, class T2> struct tuple_element<I, pair<T1, T2>>; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&&) noexcept; template<class T1, class T2> constexpr T1& get(pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr const T1& get(const pair<T1, T2>& p) noexcept; template<class T1, class T2> constexpr T1&& get(pair<T1, T2>&& p) noexcept; template<class T1, class T2> constexpr const T1&& get(const pair<T1, T2>&& p) noexcept; template<class T2, class T1> constexpr T2& get(pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr const T2& get(const pair<T1, T2>& p) noexcept; template<class T2, class T1> constexpr T2&& get(pair<T1, T2>&& p) noexcept; template<class T2, class T1> constexpr const T2&& get(const pair<T1, T2>&& p) noexcept; // [pair.piecewise], pair piecewise construction struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{}; template<class... Types> class tuple; // defined in <tuple> ([tuple.syn]) // in-place construction struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; template<class T> struct in_place_type_t { explicit in_place_type_t() = default; }; template<class T> inline constexpr in_place_type_t<T> in_place_type{}; template<size_t I> struct in_place_index_t { explicit in_place_index_t() = default; }; template<size_t I> inline constexpr in_place_index_t<I> in_place_index{}; }
template<class T>
constexpr void swap(T& a, T& b) noexcept(see below);
is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
template<class T, size_t N>
constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
template<class T, class U = T>
constexpr 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, class A1, class A2> shared_ptr<T> factory(A1&& a1, A2&& a2) { return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2))); } struct A { A(int&, const double&); }; void g() { shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int& int i = 2; shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK }
template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
template<class T, class A1> shared_ptr<T> factory(A1&& a1) { return shared_ptr<T>(new T(std::forward<A1>(a1))); } struct A { A(); A(const A&); // copies from lvalues A(A&&); // moves from rvalues }; void g() { A a; shared_ptr<A> sp1 = factory<A>(a); // “a” binds to A(const A&) shared_ptr<A> sp1 = factory<A>(std::move(a)); // “a” binds to A(A&&) }
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> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
template<class T, class U>
constexpr bool cmp_equal(T t, U u) noexcept;
using UT = make_unsigned_t<T>; using UU = make_unsigned_t<U>; if constexpr (is_signed_v<T> == is_signed_v<U>) return t == u; else if constexpr (is_signed_v<T>) return t < 0 ? false : UT(t) == u; else return u < 0 ? false : t == UU(u);
template<class T, class U>
constexpr bool cmp_not_equal(T t, U u) noexcept;
template<class T, class U>
constexpr bool cmp_less(T t, U u) noexcept;
using UT = make_unsigned_t<T>; using UU = make_unsigned_t<U>; if constexpr (is_signed_v<T> == is_signed_v<U>) return t < u; else if constexpr (is_signed_v<T>) return t < 0 ? true : UT(t) < u; else return u < 0 ? false : t < UU(u);
template<class T, class U>
constexpr bool cmp_greater(T t, U u) noexcept;
template<class T, class U>
constexpr bool cmp_less_equal(T t, U u) noexcept;
template<class T, class U>
constexpr bool cmp_greater_equal(T t, U u) noexcept;
template<class R, class T>
constexpr bool in_range(T t) noexcept;
return cmp_greater_equal(t, numeric_limits<R>::min()) && cmp_less_equal(t, numeric_limits<R>::max());
namespace std { template<class T, T... I> struct integer_sequence { using value_type = T; static constexpr size_t size() noexcept { return sizeof...(I); } }; }
template<class T, T N>
using make_integer_sequence = integer_sequence<T, see below>;
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; constexpr explicit(see below) pair(); constexpr explicit(see below) pair(const T1& x, const T2& y); template<class U1, class U2> constexpr explicit(see below) pair(U1&& x, U2&& y); template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p); template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p); template<class... Args1, class... Args2> constexpr pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args); constexpr pair& operator=(const pair& p); template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p); constexpr pair& operator=(pair&& p) noexcept(see below); template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p); constexpr void swap(pair& p) noexcept(see below); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>; }
constexpr explicit(see below) pair();
constexpr explicit(see below) pair(const T1& x, const T2& y);
!is_convertible_v<const first_type&, first_type> || !is_convertible_v<const second_type&, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(U1&& x, U2&& y);
!is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
!is_convertible_v<const U1&, first_type> || !is_convertible_v<const U2&, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
!is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
template<class... Args1, class... Args2>
constexpr pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args);
constexpr pair& operator=(const pair& p);
template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
constexpr pair& operator=(pair&& p) noexcept(see below);
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
constexpr void swap(pair& p) noexcept(see below);
template<class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
template<class T1, class T2>
constexpr common_comparison_category_t<synth-three-way-result<T1>,
synth-three-way-result<T2>>
operator<=>(const pair<T1, T2>& x, const pair<T1, T2>& y);
if (auto c = synth-three-way(x.first, y.first); c != 0) return c; return synth-three-way(x.second, y.second);
template<class T1, class T2>
constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
template<class T1, class T2>
constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>> make_pair(T1&& x, T2&& y);
pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>>(std::forward<T1>(x), std::forward<T2>(y))
template<class T1, class T2>
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
template<size_t I, class T1, class T2>
struct tuple_element<I, pair<T1, T2>> {
using type = see below ;
};
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;
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{};
#include <compare> // see [compare.syn] namespace std { // [tuple.tuple], class template tuple template<class... Types> class tuple; // [tuple.creation], tuple creation functions inline constexpr unspecified ignore; template<class... TTypes> constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&...); template<class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept; template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&...) noexcept; template<class... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&...); // [tuple.apply], calling a function with a tuple of arguments template<class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t); template<class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); // [tuple.helper], tuple helper classes template<class T> struct tuple_size; // not defined template<class T> struct tuple_size<const T>; template<class... Types> struct tuple_size<tuple<Types...>>; template<size_t I, class T> struct tuple_element; // not defined template<size_t I, class T> struct tuple_element<I, const T>; template<size_t I, class... Types> struct tuple_element<I, tuple<Types...>>; template<size_t I, class T> using tuple_element_t = typename tuple_element<I, T>::type; // [tuple.elem], element access template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept; template<size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept; template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept; template<size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept; template<class T, class... Types> constexpr T& get(tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; template<class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; template<class T, class... Types> constexpr const T&& get(const tuple<Types...>&& t) noexcept; // [tuple.rel], relational operators template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&); template<class... TTypes, class... UTypes> constexpr common_comparison_category_t<synth-three-way-result<TTypes, UTypes>...> operator<=>(const tuple<TTypes...>&, const tuple<UTypes...>&); // [tuple.traits], allocator-related traits template<class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc>; // [tuple.special], specialized algorithms template<class... Types> constexpr void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below); // [tuple.helper], tuple helper classes template<class T> inline constexpr size_t tuple_size_v = tuple_size<T>::value; }
namespace std { template<class... Types> class tuple { public: // [tuple.cnstr], tuple construction constexpr explicit(see below) tuple(); constexpr explicit(see below) tuple(const Types&...); // only if sizeof...(Types) >= 1 template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&...); // only if sizeof...(Types) >= 1 tuple(const tuple&) = default; tuple(tuple&&) = default; template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&); template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&&); template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2 // allocator-extended constructors template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a); template<class Alloc> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const Types&...); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&); template<class Alloc> constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template<class Alloc, class... UTypes> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template<class Alloc, class U1, class U2> constexpr explicit(see below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // [tuple.assign], tuple assignment constexpr tuple& operator=(const tuple&); constexpr tuple& operator=(tuple&&) noexcept(see below); template<class... UTypes> constexpr tuple& operator=(const tuple<UTypes...>&); template<class... UTypes> constexpr tuple& operator=(tuple<UTypes...>&&); template<class U1, class U2> constexpr tuple& operator=(const pair<U1, U2>&); // only if sizeof...(Types) == 2 template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2 // [tuple.swap], tuple swap constexpr 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...>; }
constexpr explicit(see below) tuple();
constexpr explicit(see below) tuple(const Types&...);
!conjunction_v<is_convertible<const Types&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&... u);
!conjunction_v<is_convertible<UTypes, Types>...>
tuple(const tuple& u) = default;
tuple(tuple&& u) = default;
template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
!conjunction_v<is_convertible<const UTypes&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
!conjunction_v<is_convertible<UTypes, Types>...>
template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u);
!is_convertible_v<const U1&, > || !is_convertible_v<const U2&, >
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&& u);
!is_convertible_v<U1, > || !is_convertible_v<U2, >
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
constexpr tuple& operator=(const tuple& u);
constexpr tuple& operator=(tuple&& u) noexcept(see below);
template<class... UTypes> constexpr tuple& operator=(const tuple<UTypes...>& u);
template<class... UTypes> constexpr tuple& operator=(tuple<UTypes...>&& u);
template<class U1, class U2> constexpr tuple& operator=(const pair<U1, U2>& u);
template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>&& u);
constexpr void swap(tuple& rhs) noexcept(see below);
template<class... TTypes>
constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&... t);
template<class... TTypes>
constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
template<class... Tuples>
constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
template<class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t);
template<class F, class Tuple, size_t... I> constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, index_sequence<I...>) { // exposition only return INVOKE(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...); // see [func.require] }
return apply-impl(std::forward<F>(f), std::forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
template<class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t);
template<class T, class Tuple, size_t... I> constexpr T make-from-tuple-impl(Tuple&& t, index_sequence<I...>) { // exposition only return T(get<I>(std::forward<Tuple>(t))...); }
return make-from-tuple-impl<T>( forward<Tuple>(t), make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
template<class T> struct tuple_size;
template<class... Types>
struct tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
template<size_t I, class... Types>
struct tuple_element<I, tuple<Types...>> {
using type = TI;
};
template<class T> struct tuple_size<const T>;
integral_constant<size_t, TS::value>
template<size_t I, class T> struct tuple_element<I, const T>;
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>&
get(tuple<Types...>& t) noexcept;
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>&&
get(tuple<Types...>&& t) noexcept; // Note A
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&
get(const tuple<Types...>& t) noexcept; // Note B
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
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...>& t, const tuple<UTypes...>& u);
template<class... TTypes, class... UTypes>
constexpr common_comparison_category_t<synth-three-way-result<TTypes, UTypes>...>
operator<=>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
if (auto c = synth-three-way(get<0>(t), get<0>(u)); c != 0) return c; return <=> ;where for some tuple r is a tuple containing all but the first element of r.
template<class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
template<class... Types>
constexpr void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
#include <compare> // see [compare.syn] namespace std { // [optional.optional], class template optional template<class T> class optional; // [optional.nullopt], no-value state indicator struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified); // [optional.bad.access], class bad_optional_access class bad_optional_access; // [optional.relops], relational operators template<class T, class U> constexpr bool operator==(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator!=(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator<(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator>(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator<=(const optional<T>&, const optional<U>&); template<class T, class U> constexpr bool operator>=(const optional<T>&, const optional<U>&); template<class T, three_way_comparable_with<T> U> constexpr compare_three_way_result_t<T,U> operator<=>(const optional<T>&, const optional<U>&); // [optional.nullops], comparison with nullopt template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; template<class T> constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // [optional.comp.with.t], comparison with T template<class T, class U> constexpr bool operator==(const optional<T>&, const U&); template<class T, class U> constexpr bool operator==(const T&, const optional<U>&); template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); template<class T, three_way_comparable_with<T> U> constexpr compare_three_way_result_t<T,U> operator<=>(const optional<T>&, const U&); // [optional.specalg], specialized algorithms template<class T> void swap(optional<T>&, optional<T>&) noexcept(see below); template<class T> constexpr optional<see below> make_optional(T&&); template<class T, class... Args> constexpr optional<T> make_optional(Args&&... args); template<class T, class U, class... Args> constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); // [optional.hash], hash support template<class T> struct hash; template<class T> struct hash<optional<T>>; }
namespace std { template<class T> class optional { public: using value_type = T; // [optional.ctor], constructors constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(see below); template<class... Args> constexpr explicit optional(in_place_t, Args&&...); template<class U, class... Args> constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); template<class U = T> constexpr explicit(see below) optional(U&&); template<class U> explicit(see below) optional(const optional<U>&); template<class U> explicit(see below) optional(optional<U>&&); // [optional.dtor], destructor ~optional(); // [optional.assign], assignment optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional&); constexpr optional& operator=(optional&&) noexcept(see below); template<class U = T> optional& operator=(U&&); template<class U> optional& operator=(const optional<U>&); template<class U> optional& operator=(optional<U>&&); template<class... Args> T& emplace(Args&&...); template<class U, class... Args> T& emplace(initializer_list<U>, Args&&...); // [optional.swap], swap void swap(optional&) noexcept(see below); // [optional.observe], observers constexpr const T* operator->() const; constexpr T* operator->(); constexpr const T& operator*() const&; constexpr T& operator*() &; constexpr T&& operator*() &&; constexpr const T&& operator*() const&&; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const&; constexpr T& value() &; constexpr T&& value() &&; constexpr const T&& value() const&&; template<class U> constexpr T value_or(U&&) const&; template<class U> constexpr T value_or(U&&) &&; // [optional.mod], modifiers void reset() noexcept; private: T *val; // exposition only }; template<class T> optional(T) -> optional<T>; }
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
constexpr optional(const optional& rhs);
constexpr optional(optional&& rhs) noexcept(see below);
template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
template<class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
template<class U = T> constexpr explicit(see below) optional(U&& v);
template<class U> explicit(see below) optional(const optional<U>& rhs);
template<class U> explicit(see below) optional(optional<U>&& rhs);
~optional();
val->T::~T()
optional<T>& operator=(nullopt_t) noexcept;
constexpr optional<T>& operator=(const optional& rhs);
*this contains a value | *this does not contain a value | ||
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with *rhs | |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
constexpr optional& operator=(optional&& rhs) noexcept(see below);
*this contains a value | *this does not contain a value | ||
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with std::move(*rhs) | |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
template<class U = T> optional<T>& operator=(U&& v);
template<class U> optional<T>& operator=(const optional<U>& rhs);
*this contains a value | *this does not contain a value | ||
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing
an object of type T with *rhs | |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
template<class U> optional<T>& operator=(optional<U>&& rhs);
*this contains a value | *this does not contain a value | ||
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing
an object of type T with std::move(*rhs) | |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
template<class... Args> T& emplace(Args&&... args);
template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
void swap(optional& rhs) noexcept(see below);
*this contains a value | *this does not contain a value | ||
rhs contains a value | calls swap(*(*this), *rhs) | initializes the contained value of *this as if
direct-non-list-initializing an object of type T with the expression std::move(*rhs),
followed by rhs.val->T::~T();
postcondition is that *this contains a value and rhs does not contain a value | |
rhs does not contain a value | initializes the contained value of rhs as if
direct-non-list-initializing an object of type T with the expression std::move(*(*this)),
followed by val->T::~T();
postcondition is that *this does not contain a value and rhs contains a value | no effect |
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
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&& v) const&;
template<class U> constexpr T value_or(U&& v) &&;
struct nullopt_t{see below};
inline constexpr nullopt_t nullopt(unspecified);
class bad_optional_access : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; };
const char* what() const noexcept override;
template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr strong_ordering operator<=>(const optional<T>& x, nullopt_t) noexcept;
template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);
template<class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
template<class T> constexpr optional<decay_t<T>> make_optional(T&& v);
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<optional<T>>;
#include <compare> // see [compare.syn] namespace std { // [variant.variant], class template variant template<class... Types> class variant; // [variant.helper], variant helper classes template<class T> struct variant_size; // not defined template<class T> struct variant_size<const T>; template<class T> inline constexpr size_t variant_size_v = variant_size<T>::value; template<class... Types> struct variant_size<variant<Types...>>; template<size_t I, class T> struct variant_alternative; // not defined template<size_t I, class T> struct variant_alternative<I, const T>; template<size_t I, class T> using variant_alternative_t = typename variant_alternative<I, T>::type; template<size_t I, class... Types> struct variant_alternative<I, variant<Types...>>; inline constexpr size_t variant_npos = -1; // [variant.get], value access template<class T, class... Types> constexpr bool holds_alternative(const variant<Types...>&) noexcept; template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&); template<size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&); template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&); template<size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&); template<class T, class... Types> constexpr T& get(variant<Types...>&); template<class T, class... Types> constexpr T&& get(variant<Types...>&&); template<class T, class... Types> constexpr const T& get(const variant<Types...>&); template<class T, class... Types> constexpr const T&& get(const variant<Types...>&&); template<size_t I, class... Types> constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>*) noexcept; template<size_t I, class... Types> constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>*) noexcept; template<class T, class... Types> constexpr add_pointer_t<T> get_if(variant<Types...>*) noexcept; template<class T, class... Types> constexpr add_pointer_t<const T> get_if(const variant<Types...>*) noexcept; // [variant.relops], relational operators template<class... Types> constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); template<class... Types> constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); template<class... Types> requires (three_way_comparable<Types> && ...) constexpr common_comparison_category_t<compare_three_way_result_t<Types>...> operator<=>(const variant<Types...>&, const variant<Types...>&); // [variant.visit], visitation template<class Visitor, class... Variants> constexpr see below visit(Visitor&&, Variants&&...); template<class R, class Visitor, class... Variants> constexpr R visit(Visitor&&, Variants&&...); // [variant.monostate], class monostate struct monostate; // [variant.monostate.relops], monostate relational operators constexpr bool operator==(monostate, monostate) noexcept; constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // [variant.specalg], specialized algorithms template<class... Types> void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); // [variant.bad.access], class bad_variant_access class bad_variant_access; // [variant.hash], hash support template<class T> struct hash; template<class... Types> struct hash<variant<Types...>>; template<> struct hash<monostate>; }
namespace std { template<class... Types> class variant { public: // [variant.ctor], constructors constexpr variant() noexcept(see below); constexpr variant(const variant&); constexpr 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&&...); // [variant.dtor], destructor ~variant(); // [variant.assign], assignment constexpr variant& operator=(const variant&); constexpr variant& operator=(variant&&) noexcept(see below); template<class T> variant& operator=(T&&) noexcept(see below); // [variant.mod], modifiers template<class T, class... Args> T& emplace(Args&&...); template<class T, class U, class... Args> T& emplace(initializer_list<U>, Args&&...); template<size_t I, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(Args&&...); template<size_t I, class U, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...); // [variant.status], value status constexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // [variant.swap], swap void swap(variant&) noexcept(see below); }; }
constexpr variant() noexcept(see below);
constexpr variant(const variant& w);
constexpr variant(variant&& w) noexcept(see below);
template<class T> constexpr variant(T&& t) noexcept(see below);
variant<string, string> v("abc");is ill-formed, as both alternative types have an equally viable constructor for the argument. — end note
template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
template<class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
template<size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
constexpr variant& operator=(const variant& rhs);
constexpr variant& operator=(variant&& rhs) noexcept(see below);
template<class T> variant& operator=(T&& t) noexcept(see below);
variant<string, string> v; v = "abc";is ill-formed, as both alternative types have an equally viable constructor for the argument. — end note
is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>
template<class T, class... Args> T& emplace(Args&&... args);
template<class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
template<size_t I, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
template<size_t I, class U, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
constexpr bool valueless_by_exception() const noexcept;
struct S { operator int() { throw 42; }}; variant<float, int> v{12.f}; v.emplace<1>(S());
constexpr size_t index() const noexcept;
void swap(variant& rhs) noexcept(see below);
template<class T> struct variant_size;
template<class T> class variant_size<const T>;
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>;
variant_alternative<I, variant<Types...>>::type
template<class T, class... Types>
constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
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);
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);
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;
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;
template<class... Types>
constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types>
constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types>
constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types>
constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types>
constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types>
constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
template<class... Types> requires (three_way_comparable<Types> && ...)
constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
operator<=>(const variant<Types...>& v, const variant<Types...>& w);
if (v.valueless_by_exception() && w.valueless_by_exception()) return strong_ordering::equal; if (v.valueless_by_exception()) return strong_ordering::less; if (w.valueless_by_exception()) return strong_ordering::greater; if (auto c = v.index() <=> w.index(); c != 0) return c; return get<i>(v) <=> get<i>(w);with i being v.index().
template<class Visitor, class... Variants>
constexpr see below visit(Visitor&& vis, Variants&&... vars);
template<class R, class Visitor, class... Variants>
constexpr R visit(Visitor&& vis, Variants&&... vars);
INVOKE(std::forward<Visitor>(vis), get<m>(std::forward<Variants>(vars))...) // see [func.require]for the first form and
INVOKE<R>(std::forward<Visitor>(vis), get<m>(std::forward<Variants>(vars))...) // see [func.require]for the second form.
struct monostate{};
constexpr bool operator==(monostate, monostate) noexcept { return true; }
constexpr strong_ordering operator<=>(monostate, monostate) noexcept
{ return strong_ordering::equal; }
template<class... Types>
void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
class bad_variant_access : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; };
const char* what() const noexcept override;
template<class... Types> struct hash<variant<Types...>>;
template<> struct hash<monostate>;
namespace std { // [any.bad.any.cast], class bad_any_cast class bad_any_cast; // [any.class], class any class any; // [any.nonmembers], non-member functions void swap(any& x, any& y) noexcept; template<class T, class... Args> any make_any(Args&&... args); template<class T, class U, class... Args> any make_any(initializer_list<U> il, Args&&... args); template<class T> T any_cast(const any& operand); template<class T> T any_cast(any& operand); template<class T> T any_cast(any&& operand); template<class T> const T* any_cast(const any* operand) noexcept; template<class T> T* any_cast(any* operand) noexcept; }
class bad_any_cast : public bad_cast { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; };
const char* what() const noexcept override;
namespace std { class any { public: // [any.cons], construction and destruction constexpr any() noexcept; any(const any& other); any(any&& other) noexcept; template<class T> any(T&& value); template<class T, class... Args> explicit any(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U>, Args&&...); ~any(); // [any.assign], assignments any& operator=(const any& rhs); any& operator=(any&& rhs) noexcept; template<class T> any& operator=(T&& rhs); // [any.modifiers], modifiers template<class T, class... Args> decay_t<T>& emplace(Args&&...); template<class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U>, Args&&...); void reset() noexcept; void swap(any& rhs) noexcept; // [any.observers], observers bool has_value() const noexcept; const type_info& type() const noexcept; }; }
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&&... args);
template<class T, class U, class... Args>
explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... 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&&... args);
template<class T, class U, class... Args>
decay_t<T>& emplace(initializer_list<U> il, Args&&... args);
void reset() noexcept;
void swap(any& rhs) noexcept;
bool has_value() const noexcept;
const type_info& type() const noexcept;
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);
any x(5); // x holds int assert(any_cast<int>(x) == 5); // cast to value any_cast<int&>(x) = 10; // cast to reference assert(any_cast<int>(x) == 10); x = "Meow"; // x holds const char* assert(strcmp(any_cast<const char*>(x), "Meow") == 0); any_cast<const char*&>(x) = "Harry"; assert(strcmp(any_cast<const char*>(x), "Harry") == 0); x = string("Meow"); // x holds string string s, s2("Jane"); s = move(any_cast<string&>(x)); // move from any assert(s == "Meow"); any_cast<string&>(x) = move(s2); // move to any assert(any_cast<const string&>(x) == "Jane"); string cat("Meow"); const any y(cat); // const y holds string assert(any_cast<const string&>(y) == cat); any_cast<string&>(y); // error: cannot any_cast away const— end example
template<class T>
const T* any_cast(const any* operand) noexcept;
template<class T>
T* any_cast(any* operand) noexcept;
#include <string> #include <iosfwd> // for istream, ostream, see [iosfwd.syn] namespace std { template<size_t N> class bitset; // [bitset.operators], bitset operators template<size_t N> bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept; template<size_t N> bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept; template<size_t N> bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept; template<class charT, class traits, size_t N> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, bitset<N>& x); template<class charT, class traits, size_t N> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x); }
namespace std { template<size_t N> class bitset { public: // bit reference class reference { friend class bitset; reference() noexcept; public: reference(const reference&) = default; ~reference(); reference& operator=(bool x) noexcept; // for b[i] = x; reference& operator=(const reference&) noexcept; // for b[i] = b[j]; bool operator~() const noexcept; // flips the bit operator bool() const noexcept; // for x = b[i]; reference& flip() noexcept; // for b[i].flip(); }; // [bitset.cons], constructors constexpr bitset() noexcept; constexpr bitset(unsigned long long val) noexcept; template<class charT, class traits, class Allocator> explicit bitset( const basic_string<charT, traits, Allocator>& str, typename basic_string<charT, traits, Allocator>::size_type pos = 0, typename basic_string<charT, traits, Allocator>::size_type n = basic_string<charT, traits, Allocator>::npos, charT zero = charT('0'), charT one = charT('1')); template<class charT> explicit bitset( const charT* str, typename basic_string<charT>::size_type n = basic_string<charT>::npos, charT zero = charT('0'), charT one = charT('1')); // [bitset.members], bitset operations bitset<N>& operator&=(const bitset<N>& rhs) noexcept; bitset<N>& operator|=(const bitset<N>& rhs) noexcept; bitset<N>& operator^=(const bitset<N>& rhs) noexcept; bitset<N>& operator<<=(size_t pos) noexcept; bitset<N>& operator>>=(size_t pos) noexcept; bitset<N>& set() noexcept; bitset<N>& set(size_t pos, bool val = true); bitset<N>& reset() noexcept; bitset<N>& reset(size_t pos); bitset<N> operator~() const noexcept; bitset<N>& flip() noexcept; bitset<N>& flip(size_t pos); // element access constexpr bool operator[](size_t pos) const; // for b[i]; reference operator[](size_t pos); // for b[i]; unsigned long to_ulong() const; unsigned long long to_ullong() const; template<class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const; size_t count() const noexcept; constexpr size_t size() const noexcept; bool operator==(const bitset<N>& rhs) const noexcept; bool test(size_t pos) const; bool all() const noexcept; bool any() const noexcept; bool none() const noexcept; bitset<N> operator<<(size_t pos) const noexcept; bitset<N> operator>>(size_t pos) const noexcept; }; // [bitset.hash], hash support template<class T> struct hash; template<size_t N> struct hash<bitset<N>>; }
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);
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 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;
constexpr bool operator[](size_t pos) const;
bitset<N>::reference operator[](size_t pos);
template<size_t N> struct hash<bitset<N>>;
bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) 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);
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]).
#include <compare> // see [compare.syn] namespace std { // [pointer.traits], pointer traits template<class Ptr> struct pointer_traits; template<class T> struct pointer_traits<T*>; // [pointer.conversion], pointer conversion template<class T> constexpr T* to_address(T* p) noexcept; template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // [util.dynamic.safety], pointer safety enum class pointer_safety { relaxed, preferred, strict }; void declare_reachable(void* p); template<class T> T* undeclare_reachable(T* p); void declare_no_pointers(char* p, size_t n); void undeclare_no_pointers(char* p, size_t n); pointer_safety get_pointer_safety() noexcept; // [ptr.align], pointer alignment void* align(size_t alignment, size_t size, void*& ptr, size_t& space); template<size_t N, class T> [[nodiscard]] constexpr T* assume_aligned(T* ptr); // [allocator.tag], allocator argument tag struct allocator_arg_t { explicit allocator_arg_t() = default; }; inline constexpr allocator_arg_t allocator_arg{}; // [allocator.uses], uses_allocator template<class T, class Alloc> struct uses_allocator; // [allocator.uses.trait], uses_allocator template<class T, class Alloc> inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; // [allocator.uses.construction], uses-allocator construction template<class T, class Alloc, class... Args> constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept -> see below; template<class T, class Alloc, class Tuple1, class Tuple2> constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, Tuple1&& x, Tuple2&& y) noexcept -> see below; template<class T, class Alloc> constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below; template<class T, class Alloc, class U, class V> constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept -> see below; template<class T, class Alloc, class U, class V> constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair<U,V>& pr) noexcept -> see below; template<class T, class Alloc, class U, class V> constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair<U,V>&& pr) noexcept -> see below; template<class T, class Alloc, class... Args> constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); template<class T, class Alloc, class... Args> constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); // [allocator.traits], allocator traits template<class Alloc> struct allocator_traits; // [default.allocator], the default allocator template<class T> class allocator; template<class T, class U> constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // [specialized.addressof], addressof template<class T> constexpr T* addressof(T& r) noexcept; template<class T> const T* addressof(const T&&) = delete; // [specialized.algorithms], specialized algorithms // [special.mem.concepts], special memory concepts template<class I> concept no-throw-input-iterator = see below; // exposition only template<class I> concept no-throw-forward-iterator = see below; // exposition only template<class S, class I> concept no-throw-sentinel = see below; // exposition only template<class R> concept no-throw-input-range = see below; // exposition only template<class R> concept no-throw-forward-range = see below; // exposition only template<class NoThrowForwardIterator> void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n); namespace ranges { template<no-throw-forward-iterator I, no-throw-sentinel<I> S> requires default_initializable<iter_value_t<I>> I uninitialized_default_construct(I first, S last); template<no-throw-forward-range R> requires default_initializable<range_value_t<R>> borrowed_iterator_t<R> uninitialized_default_construct(R&& r); template<no-throw-forward-iterator I> requires default_initializable<iter_value_t<I>> I uninitialized_default_construct_n(I first, iter_difference_t<I> n); } template<class NoThrowForwardIterator> void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n); namespace ranges { template<no-throw-forward-iterator I, no-throw-sentinel<I> S> requires default_initializable<iter_value_t<I>> I uninitialized_value_construct(I first, S last); template<no-throw-forward-range R> requires default_initializable<range_value_t<R>> borrowed_iterator_t<R> uninitialized_value_construct(R&& r); template<no-throw-forward-iterator I> requires default_initializable<iter_value_t<I>> I uninitialized_value_construct_n(I first, iter_difference_t<I> n); } template<class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, Size n, NoThrowForwardIterator result); namespace ranges { template<class I, class O> using uninitialized_copy_result = in_out_result<I, O>; template<input_iterator I, sentinel_for<I> S1, no-throw-forward-iterator O, no-throw-sentinel<O> S2> requires constructible_from<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_result<I, O> uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); template<input_range IR, no-throw-forward-range OR> requires constructible_from<range_value_t<OR>, range_reference_t<IR>> uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_copy(IR&& in_range, OR&& out_range); template<class I, class O> using uninitialized_copy_n_result = in_out_result<I, O>; template<input_iterator I, no-throw-forward-iterator O, no-throw-sentinel<O> S> requires constructible_from<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_n_result<I, O> uninitialized_copy_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast); } template<class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator> pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator> pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] InputIterator first, Size n, NoThrowForwardIterator result); namespace ranges { template<class I, class O> using uninitialized_move_result = in_out_result<I, O>; template<input_iterator I, sentinel_for<I> S1, no-throw-forward-iterator O, no-throw-sentinel<O> S2> requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_result<I, O> uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); template<input_range IR, no-throw-forward-range OR> requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>> uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_move(IR&& in_range, OR&& out_range); template<class I, class O> using uninitialized_move_n_result = in_out_result<I, O>; template<input_iterator I, no-throw-forward-iterator O, no-throw-sentinel<O> S> requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_n_result<I, O> uninitialized_move_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast); } template<class NoThrowForwardIterator, class T> void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); template<class ExecutionPolicy, class NoThrowForwardIterator, class T> void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); template<class NoThrowForwardIterator, class Size, class T> NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T> NoThrowForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n, const T& x); namespace ranges { template<no-throw-forward-iterator I, no-throw-sentinel<I> S, class T> requires constructible_from<iter_value_t<I>, const T&> I uninitialized_fill(I first, S last, const T& x); template<no-throw-forward-range R, class T> requires constructible_from<range_value_t<R>, const T&> borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); template<no-throw-forward-iterator I, class T> requires constructible_from<iter_value_t<I>, const T&> I uninitialized_fill_n(I first, iter_difference_t<I> n, const T& x); } // [specialized.construct], construct_at template<class T, class... Args> constexpr T* construct_at(T* location, Args&&... args); namespace ranges { template<class T, class... Args> constexpr T* construct_at(T* location, Args&&... args); } // [specialized.destroy], destroy template<class T> constexpr void destroy_at(T* location); template<class NoThrowForwardIterator> constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n); namespace ranges { template<destructible T> constexpr void destroy_at(T* location) noexcept; template<no-throw-input-iterator I, no-throw-sentinel<I> S> requires destructible<iter_value_t<I>> constexpr I destroy(I first, S last) noexcept; template<no-throw-input-range R> requires destructible<range_value_t<R>> constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; template<no-throw-input-iterator I> requires destructible<iter_value_t<I>> constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; } // [unique.ptr], class template unique_ptr template<class T> struct default_delete; template<class T> struct default_delete<T[]>; template<class T, class D = default_delete<T>> class unique_ptr; template<class T, class D> class unique_ptr<T[], D>; template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // T is not array template<class T> unique_ptr<T> make_unique(size_t n); // T is U[] template<class T, class... Args> unspecified make_unique(Args&&...) = delete; // T is U[N] template<class T> unique_ptr<T> make_unique_for_overwrite(); // T is not array template<class T> unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[] template<class T, class... Args> unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N] 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> requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer> compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer> 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<(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); template<class T, class D> requires three_way_comparable_with<typename unique_ptr<T, D>::pointer, nullptr_t> compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t> operator<=>(const unique_ptr<T, D>& x, nullptr_t); template<class E, class T, class Y, class D> basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p); // [util.smartptr.weak.bad], class bad_weak_ptr class bad_weak_ptr; // [util.smartptr.shared], class template shared_ptr template<class T> class shared_ptr; // [util.smartptr.shared.create], shared_ptr creation template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args); // T is not array template<class T, class A, class... Args> shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array template<class T> shared_ptr<T> make_shared(size_t N); // T is U[] template<class T, class A> shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[] template<class T> shared_ptr<T> make_shared(); // T is U[N] template<class T, class A> shared_ptr<T> allocate_shared(const A& a); // T is U[N] template<class T> shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[] template<class T, class A> shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[] template<class T> shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N] template<class T, class A> shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] template<class T> shared_ptr<T> make_shared_for_overwrite(); // T is not U[] template<class T, class A> shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[] template<class T> shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[] template<class T, class A> shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[] // [util.smartptr.shared.cmp], shared_ptr comparisons template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U> strong_ordering 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> strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept; // [util.smartptr.shared.spec], shared_ptr specialized algorithms template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; // [util.smartptr.shared.cast], shared_ptr casts template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> static_pointer_cast(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> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept; template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept; template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept; // [util.smartptr.getdeleter], shared_ptr get_deleter template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept; // [util.smartptr.shared.io], shared_ptr I/O template<class E, class T, class Y> basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p); // [util.smartptr.weak], class template weak_ptr template<class T> class weak_ptr; // [util.smartptr.weak.spec], weak_ptr specialized algorithms template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; // [util.smartptr.ownerless], class template owner_less template<class T = void> struct owner_less; // [util.smartptr.enab], class template enable_shared_from_this template<class T> class enable_shared_from_this; // [util.smartptr.hash], hash support template<class T> struct hash; template<class T, class D> struct hash<unique_ptr<T, D>>; template<class T> struct hash<shared_ptr<T>>; // [util.smartptr.atomic], atomic smart pointers template<class T> struct atomic; template<class T> struct atomic<shared_ptr<T>>; template<class T> struct atomic<weak_ptr<T>>; }
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 constexpr pointer pointer_to(see below r) noexcept; }; }
using element_type = see below;
using difference_type = see below;
template<class U> using rebind = see below;
static pointer pointer_traits::pointer_to(see below r);
static constexpr pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
static element_type* to_address(pointer p) noexcept;
template<class T> constexpr T* to_address(T* p) noexcept;
template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
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);
template<size_t N, class T>
[[nodiscard]] constexpr T* assume_aligned(T* ptr);
namespace std {
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 T, class Alloc, class... Args>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
Args&&... args) noexcept -> see below;
tuple<allocator_arg_t, const Alloc&, Args&&...>( allocator_arg, alloc, std::forward<Args>(args)...)
template<class T, class Alloc, class Tuple1, class Tuple2>
constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
Tuple1&& x, Tuple2&& y)
noexcept -> see below;
return make_tuple( piecewise_construct, apply([&alloc](auto&&... args1) { return uses_allocator_construction_args<T1>( alloc, std::forward<decltype(args1)>(args1)...); }, std::forward<Tuple1>(x)), apply([&alloc](auto&&... args2) { return uses_allocator_construction_args<T2>( alloc, std::forward<decltype(args2)>(args2)...); }, std::forward<Tuple2>(y)));
template<class T, class Alloc>
constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
return uses_allocator_construction_args<T>(alloc, piecewise_construct, tuple<>{}, tuple<>{});
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
U&& u, V&& v) noexcept -> see below;
return uses_allocator_construction_args<T>(alloc, piecewise_construct, forward_as_tuple(std::forward<U>(u)), forward_as_tuple(std::forward<V>(v)));
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
const pair<U,V>& pr) noexcept -> see below;
return uses_allocator_construction_args<T>(alloc, piecewise_construct, forward_as_tuple(pr.first), forward_as_tuple(pr.second));
template<class T, class Alloc, class U, class V>
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
pair<U,V>&& pr) noexcept -> see below;
return uses_allocator_construction_args<T>(alloc, piecewise_construct, forward_as_tuple(std::move(pr).first), forward_as_tuple(std::move(pr).second));
template<class T, class Alloc, class... Args>
constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
return make_from_tuple<T>(uses_allocator_construction_args<T>( alloc, std::forward<Args>(args)...));
template<class T, class Alloc, class... Args>
constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
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>>; [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n); [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static constexpr void deallocate(Alloc& a, pointer p, size_type n); template<class T, class... Args> static constexpr void construct(Alloc& a, T* p, Args&&... args); template<class T> static constexpr void destroy(Alloc& a, T* p); static constexpr size_type max_size(const Alloc& a) noexcept; static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); }; }
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;
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
static constexpr void deallocate(Alloc& a, pointer p, size_type n);
template<class T, class... Args>
static constexpr void construct(Alloc& a, T* p, Args&&... args);
template<class T>
static constexpr void destroy(Alloc& a, T* p);
static constexpr size_type max_size(const Alloc& a) noexcept;
static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
namespace std { template<class T> class allocator { public: using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = true_type; using is_always_equal = true_type; constexpr allocator() noexcept; constexpr allocator(const allocator&) noexcept; template<class U> constexpr allocator(const allocator<U>&) noexcept; constexpr ~allocator(); constexpr allocator& operator=(const allocator&) = default; [[nodiscard]] constexpr T* allocate(size_t n); constexpr void deallocate(T* p, size_t n); }; }
[[nodiscard]] constexpr T* allocate(size_t n);
constexpr void deallocate(T* p, size_t n);
template<class T, class U>
constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
template<class T> constexpr T* addressof(T& r) noexcept;
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);
void free(void* ptr);
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;
void operator()(T* ptr) const;
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;
template<class U> void operator()(U* ptr) const;
namespace std { template<class T, class D = default_delete<T>> class unique_ptr { public: using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.single.ctor], constructors constexpr unique_ptr() noexcept; explicit unique_ptr(pointer p) noexcept; unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept; unique_ptr(unique_ptr&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept; // [unique.ptr.single.dtor], destructor ~unique_ptr(); // [unique.ptr.single.asgn], assignment unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.single.observers], observers add_lvalue_reference_t<T> operator*() const; pointer operator->() const noexcept; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // [unique.ptr.single.modifiers], modifiers pointer release() noexcept; void reset(pointer p = pointer()) noexcept; void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; }
constexpr unique_ptr() noexcept;
constexpr unique_ptr(nullptr_t) noexcept;
explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, const D& d) noexcept;
unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
D d; unique_ptr<int, D> p1(new int, D()); // D must be Cpp17MoveConstructible unique_ptr<int, D> p2(new int, d); // D must be Cpp17CopyConstructible unique_ptr<int, D&> p3(new int, d); // p3 holds a reference to d unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined // with reference deleter type— end example
unique_ptr(unique_ptr&& u) noexcept;
template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
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;
namespace std { template<class T, class D> class unique_ptr<T[], D> { public: using pointer = see below; using element_type = T; using deleter_type = D; // [unique.ptr.runtime.ctor], constructors constexpr unique_ptr() noexcept; template<class U> explicit unique_ptr(U p) noexcept; template<class U> unique_ptr(U p, see below d) noexcept; template<class U> unique_ptr(U p, see below d) noexcept; unique_ptr(unique_ptr&& u) noexcept; template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept; constexpr unique_ptr(nullptr_t) noexcept; // destructor ~unique_ptr(); // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // [unique.ptr.runtime.observers], observers T& operator[](size_t i) const; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // [unique.ptr.runtime.modifiers], modifiers pointer release() noexcept; template<class U> void reset(U p) noexcept; void reset(nullptr_t = nullptr) noexcept; void swap(unique_ptr& u) noexcept; // disable copy from lvalue unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; }
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;
template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
void reset(nullptr_t p = nullptr) noexcept;
template<class U> void reset(U p) noexcept;
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> unique_ptr<T> make_unique_for_overwrite();
template<class T> unique_ptr<T> make_unique_for_overwrite(size_t n);
template<class T, class... Args> unspecified make_unique_for_overwrite(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);
common_type_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>
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>
requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
typename unique_ptr<T2, D2>::pointer>
compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
typename unique_ptr<T2, D2>::pointer>
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<(const unique_ptr<T, D>& x, nullptr_t);
template<class T, class D>
bool operator<(nullptr_t, const unique_ptr<T, D>& x);
less<unique_ptr<T, D>::pointer>()(x.get(), nullptr)
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);
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);
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);
namespace std { class bad_weak_ptr : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
const char* what() const noexcept override;
namespace std { template<class T> class weak_ptr { public: using element_type = remove_extent_t<T>; // [util.smartptr.weak.const], constructors constexpr weak_ptr() noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept; weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // [util.smartptr.weak.dest], destructor ~weak_ptr(); // [util.smartptr.weak.assign], assignment weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept; weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // [util.smartptr.weak.mod], modifiers void swap(weak_ptr& r) noexcept; void reset() noexcept; // [util.smartptr.weak.obs], observers long use_count() const noexcept; bool expired() const noexcept; shared_ptr<T> lock() const noexcept; template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept; }; template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>; // [util.smartptr.weak.spec], specialized algorithms template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; }
constexpr weak_ptr() noexcept;
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;
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;
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 noexcept;
template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
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; }; }
struct X: public enable_shared_from_this<X> { }; int main() { shared_ptr<X> p(new X); shared_ptr<X> q = p->shared_from_this(); assert(p == q); assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership }— end example
namespace std { template<class T> class enable_shared_from_this { protected: constexpr enable_shared_from_this() noexcept; enable_shared_from_this(const enable_shared_from_this&) noexcept; enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept; ~enable_shared_from_this(); public: shared_ptr<T> shared_from_this(); shared_ptr<T const> shared_from_this() const; weak_ptr<T> weak_from_this() noexcept; weak_ptr<T const> weak_from_this() const noexcept; private: mutable weak_ptr<T> weak_this; // exposition only }; }
constexpr enable_shared_from_this() noexcept;
enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
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;
template<class T, class D> struct hash<unique_ptr<T, D>>;
template<class T> struct hash<shared_ptr<T>>;
namespace std::pmr { // [mem.res.class], class memory_resource class memory_resource; bool operator==(const memory_resource& a, const memory_resource& b) noexcept; // [mem.poly.allocator.class], class template polymorphic_allocator template<class Tp> class polymorphic_allocator; template<class T1, class T2> bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept; // [mem.res.global], global memory resources memory_resource* new_delete_resource() noexcept; memory_resource* null_memory_resource() noexcept; memory_resource* set_default_resource(memory_resource* r) noexcept; memory_resource* get_default_resource() noexcept; // [mem.res.pool], pool resource classes struct pool_options; class synchronized_pool_resource; class unsynchronized_pool_resource; class monotonic_buffer_resource; }
namespace std::pmr { class memory_resource { static constexpr size_t max_align = alignof(max_align_t); // exposition only public: memory_resource() = default; memory_resource(const memory_resource&) = default; virtual ~memory_resource(); memory_resource& operator=(const memory_resource&) = default; [[nodiscard]] 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; }; }
~memory_resource();
[[nodiscard]] 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;
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;
namespace std::pmr { template<class Tp = byte> class polymorphic_allocator { memory_resource* memory_rsrc; // exposition only public: using value_type = Tp; // [mem.poly.allocator.ctor], constructors polymorphic_allocator() noexcept; polymorphic_allocator(memory_resource* r); polymorphic_allocator(const polymorphic_allocator& other) = default; template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept; polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; // [mem.poly.allocator.mem], member functions [[nodiscard]] Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); [[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); template<class T> [[nodiscard]] T* allocate_object(size_t n = 1); template<class T> void deallocate_object(T* p, size_t n = 1); template<class T, class... CtorArgs> [[nodiscard]] T* new_object(CtorArgs&&... ctor_args); template<class T> void delete_object(T* p); template<class T, class... Args> void construct(T* p, Args&&... args); template<class T> void destroy(T* p); polymorphic_allocator select_on_container_copy_construction() const; memory_resource* resource() const; }; }
polymorphic_allocator() noexcept;
polymorphic_allocator(memory_resource* r);
template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
[[nodiscard]] Tp* allocate(size_t n);
void deallocate(Tp* p, size_t n);
[[nodiscard]] void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
template<class T>
[[nodiscard]] T* allocate_object(size_t n = 1);
template<class T>
void deallocate_object(T* p, size_t n = 1);
template<class T, class CtorArgs...>
[[nodiscard]] T* new_object(CtorArgs&&... ctor_args);
template<class T>
void delete_object(T* p);
template<class T, class... Args>
void construct(T* p, Args&&... args);
template<class T>
void destroy(T* p);
polymorphic_allocator select_on_container_copy_construction() const;
memory_resource* resource() const;
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;
namespace std::pmr { 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; }; }
size_t max_blocks_per_chunk;
size_t largest_required_pool_block;
synchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
virtual ~synchronized_pool_resource();
virtual ~unsynchronized_pool_resource();
void release();
memory_resource* upstream_resource() const;
pool_options options() const;
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;
namespace std::pmr { class monotonic_buffer_resource : public memory_resource { memory_resource* upstream_rsrc; // exposition only void* current_buffer; // exposition only size_t next_buffer_size; // exposition only public: explicit monotonic_buffer_resource(memory_resource* upstream); monotonic_buffer_resource(size_t initial_size, memory_resource* upstream); monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream); monotonic_buffer_resource() : monotonic_buffer_resource(get_default_resource()) {} explicit monotonic_buffer_resource(size_t initial_size) : monotonic_buffer_resource(initial_size, get_default_resource()) {} monotonic_buffer_resource(void* buffer, size_t buffer_size) : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {} monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; virtual ~monotonic_buffer_resource(); monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; void release(); memory_resource* upstream_resource() const; protected: void* do_allocate(size_t bytes, size_t alignment) override; void do_deallocate(void* p, size_t bytes, size_t alignment) override; bool do_is_equal(const memory_resource& other) const noexcept override; }; }
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();
void release();
memory_resource* upstream_resource() const;
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;
namespace std { // class template scoped allocator adaptor template<class OuterAlloc, class... InnerAlloc> class scoped_allocator_adaptor; // [scoped.adaptor.operators], scoped allocator 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; }
namespace std { template<class OuterAlloc, class... InnerAllocs> class scoped_allocator_adaptor : public OuterAlloc { private: using OuterTraits = allocator_traits<OuterAlloc>; // exposition only scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only public: using outer_allocator_type = OuterAlloc; using inner_allocator_type = see below; using value_type = typename OuterTraits::value_type; using size_type = typename OuterTraits::size_type; using difference_type = typename OuterTraits::difference_type; using pointer = typename OuterTraits::pointer; using const_pointer = typename OuterTraits::const_pointer; using void_pointer = typename OuterTraits::void_pointer; using const_void_pointer = typename OuterTraits::const_void_pointer; using propagate_on_container_copy_assignment = see below; using propagate_on_container_move_assignment = see below; using propagate_on_container_swap = see below; using is_always_equal = see below; template<class Tp> struct rebind { using other = scoped_allocator_adaptor< OuterTraits::template rebind_alloc<Tp>, InnerAllocs...>; }; scoped_allocator_adaptor(); template<class OuterA2> scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept; scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; template<class OuterA2> scoped_allocator_adaptor( const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept; template<class OuterA2> scoped_allocator_adaptor( scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept; scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; ~scoped_allocator_adaptor(); inner_allocator_type& inner_allocator() noexcept; const inner_allocator_type& inner_allocator() const noexcept; outer_allocator_type& outer_allocator() noexcept; const outer_allocator_type& outer_allocator() const noexcept; [[nodiscard]] pointer allocate(size_type n); [[nodiscard]] 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 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...>; }
using inner_allocator_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;
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;
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;
[[nodiscard]] pointer allocate(size_type n);
[[nodiscard]] pointer allocate(size_type n, const_void_pointer hint);
void deallocate(pointer p, size_type n) noexcept;
size_type max_size() const;
template<class T, class... Args>
void construct(T* p, Args&&... args);
apply([p, this](auto&&... newargs) { OUTERMOST_ALLOC_TRAITS(*this)::construct( OUTERMOST(*this), p, std::forward<decltype(newargs)>(newargs)...); }, uses_allocator_construction_args<T>(inner_allocator(), std::forward<Args>(args)...));
template<class T>
void destroy(T* p);
scoped_allocator_adaptor select_on_container_copy_construction() const;
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 { // [func.invoke], invoke template<class F, class... Args> constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v<F, Args...>); // [refwrap], reference_wrapper template<class T> class reference_wrapper; template<class T> constexpr reference_wrapper<T> ref(T&) noexcept; template<class T> constexpr 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> constexpr reference_wrapper<T> ref(reference_wrapper<T>) noexcept; template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T>) noexcept; // [arithmetic.operations], arithmetic operations template<class T = void> struct plus; template<class T = void> struct minus; template<class T = void> struct multiplies; template<class T = void> struct divides; template<class T = void> struct modulus; template<class T = void> struct negate; template<> struct plus<void>; template<> struct minus<void>; template<> struct multiplies<void>; template<> struct divides<void>; template<> struct modulus<void>; template<> struct negate<void>; // [comparisons], comparisons template<class T = void> struct equal_to; template<class T = void> struct not_equal_to; template<class T = void> struct greater; template<class T = void> struct less; template<class T = void> struct greater_equal; template<class T = void> struct less_equal; template<> struct equal_to<void>; template<> struct not_equal_to<void>; template<> struct greater<void>; template<> struct less<void>; template<> struct greater_equal<void>; template<> struct less_equal<void>; // [comparisons.three.way], class compare_three_way struct compare_three_way; // [logical.operations], logical operations template<class T = void> struct logical_and; template<class T = void> struct logical_or; template<class T = void> struct logical_not; template<> struct logical_and<void>; template<> struct logical_or<void>; template<> struct logical_not<void>; // [bitwise.operations], bitwise operations template<class T = void> struct bit_and; template<class T = void> struct bit_or; template<class T = void> struct bit_xor; template<class T = void> struct bit_not; template<> struct bit_and<void>; template<> struct bit_or<void>; template<> struct bit_xor<void>; template<> struct bit_not<void>; // [func.identity], identity struct identity; // [func.not.fn], function template not_fn template<class F> constexpr unspecified not_fn(F&& f); // [func.bind.front], function template bind_front template<class F, class... Args> constexpr unspecified bind_front(F&&, Args&&...); // [func.bind], bind template<class T> struct is_bind_expression; template<class T> inline constexpr bool is_bind_expression_v = is_bind_expression<T>::value; template<class T> struct is_placeholder; template<class T> inline constexpr int is_placeholder_v = is_placeholder<T>::value; template<class F, class... BoundArgs> constexpr unspecified bind(F&&, BoundArgs&&...); template<class R, class F, class... BoundArgs> constexpr unspecified bind(F&&, BoundArgs&&...); namespace placeholders { // M is the implementation-defined number of placeholders see below _1; see below _2; . . . see below _M; } // [func.memfn], member function adaptors template<class R, class T> constexpr unspecified mem_fn(R T::*) noexcept; // [func.wrap], polymorphic function wrappers class bad_function_call; template<class> class function; // not defined template<class R, class... ArgTypes> class function<R(ArgTypes...)>; template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept; template<class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // [func.search], searchers template<class ForwardIterator, class BinaryPredicate = equal_to<>> class default_searcher; template<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_searcher; template<class RandomAccessIterator, class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher; // [unord.hash], class template hash template<class T> struct hash; namespace ranges { // [range.cmp], concept-constrained comparisons struct equal_to; struct not_equal_to; struct greater; struct less; struct greater_equal; struct less_equal; } }
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
template<class... UnBoundArgs> constexpr R operator()(UnBoundArgs&&... unbound_args) cv-qual;
template<class F, class... Args>
constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(is_nothrow_invocable_v<F, Args...>);
namespace std { template<class T> class reference_wrapper { public: // types using type = T; // construct/copy/destroy template<class U> constexpr reference_wrapper(U&&) noexcept(see below); constexpr reference_wrapper(const reference_wrapper& x) noexcept; // assignment constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept; // access constexpr operator T& () const noexcept; constexpr T& get() const noexcept; // invocation template<class... ArgTypes> constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&...) const; }; template<class T> reference_wrapper(T&) -> reference_wrapper<T>; }
template<class U>
constexpr reference_wrapper(U&& u) noexcept(see below);
constexpr reference_wrapper(const reference_wrapper& x) noexcept;
constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept;
constexpr operator T& () const noexcept;
constexpr T& get() const noexcept;
template<class... ArgTypes>
constexpr invoke_result_t<T&, ArgTypes...>
operator()(ArgTypes&&... args) const;
template<class T> constexpr reference_wrapper<T> ref(T& t) noexcept;
template<class T> constexpr reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
template<class T> constexpr reference_wrapper<const T> cref(const T& t) noexcept;
template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
declval<T>() <=> declval<U>()resolves to a built-in operator comparing pointers.
struct compare_three_way { template<class T, class U> requires three_way_comparable_with<T, U> || BUILTIN-PTR-THREE-WAY(T, U) constexpr auto operator()(T&& t, U&& u) const; using is_transparent = unspecified; };
template<class T, class U>
requires three_way_comparable_with<T, U> || BUILTIN-PTR-THREE-WAY(T, U)
constexpr auto operator()(T&& t, U&& u) const;
struct ranges::equal_to {
template<class T, class U>
requires equality_comparable_with<T, U> || BUILTIN-PTR-CMP(T, ==, U)
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
struct ranges::not_equal_to {
template<class T, class U>
requires equality_comparable_with<T, U> || BUILTIN-PTR-CMP(T, ==, U)
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
return !ranges::equal_to{}(std::forward<T>(t), std::forward<U>(u));
struct ranges::greater {
template<class T, class U>
requires totally_ordered_with<T, U> || BUILTIN-PTR-CMP(U, <, T)
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
return ranges::less{}(std::forward<U>(u), std::forward<T>(t));
struct ranges::less {
template<class T, class U>
requires totally_ordered_with<T, U> || BUILTIN-PTR-CMP(T, <, U)
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
struct ranges::greater_equal {
template<class T, class U>
requires totally_ordered_with<T, U> || BUILTIN-PTR-CMP(T, <, U)
constexpr bool operator()(T&& t, U&& u) const;
using is_transparent = unspecified;
};
return !ranges::less{}(std::forward<T>(t), std::forward<U>(u));
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));
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));
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));
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));
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));
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));
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));
struct identity {
template<class T>
constexpr T&& operator()(T&& t) const noexcept;
using is_transparent = unspecified;
};
template<class T>
constexpr T&& operator()(T&& t) const noexcept;
template<class F> constexpr unspecified not_fn(F&& f);
template<class F, class... Args>
constexpr unspecified bind_front(F&& f, Args&&... args);
namespace std { template<class T> struct is_bind_expression; // see below }
namespace std { template<class T> struct is_placeholder; // see below }
template<class F, class... BoundArgs>
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
template<class R, class F, class... BoundArgs>
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
INVOKE(static_cast<>(), static_cast<>(), static_cast<>(), …, static_cast<>())for the first overload, and
INVOKE<R>(static_cast<>(), static_cast<>(), static_cast<>(), …, static_cast<>())for the second overload, where the values and types of the target argument and of the bound arguments , , …, are determined as specified below.
static_cast<cv &>()(std::forward<>()...)and its type is invoke_result_t<cv &, ...>&&;
namespace std::placeholders { // M is the implementation-defined number of placeholders see below _1; see below _2; . . . see below _M; }
template<class R, class T> constexpr unspecified mem_fn(R T::* pm) noexcept;
namespace std { class bad_function_call : public exception { public: // see [exception] for the specification of the special member functions const char* what() const noexcept override; }; }
const char* what() const noexcept override;
namespace std { template<class> class function; // not defined template<class R, class... ArgTypes> class function<R(ArgTypes...)> { public: using result_type = R; // [func.wrap.func.con], construct/copy/destroy function() noexcept; function(nullptr_t) noexcept; function(const function&); function(function&&) noexcept; template<class F> function(F); function& operator=(const function&); function& operator=(function&&); function& operator=(nullptr_t) noexcept; template<class F> function& operator=(F&&); template<class F> function& operator=(reference_wrapper<F>) noexcept; ~function(); // [func.wrap.func.mod], function modifiers void swap(function&) noexcept; // [func.wrap.func.cap], function capacity explicit operator bool() const noexcept; // [func.wrap.func.inv], function invocation R operator()(ArgTypes...) const; // [func.wrap.func.targ], function target access const type_info& target_type() const noexcept; template<class T> T* target() noexcept; template<class T> const T* target() const noexcept; }; template<class R, class... ArgTypes> function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>; template<class F> function(F) -> function<see below>; // [func.wrap.func.nullptr], null pointer comparison functions template<class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // [func.wrap.func.alg], specialized algorithms template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept; }
function() noexcept;
function(nullptr_t) noexcept;
function(const function& f);
function(function&& f) noexcept;
template<class F> function(F f);
template<class F> function(F) -> function<see below>;
function& operator=(const function& f);
function& operator=(function&& f);
function& operator=(nullptr_t) noexcept;
template<class F> function& operator=(F&& f);
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
~function();
explicit operator bool() const noexcept;
R operator()(ArgTypes... args) 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>
bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept;
template<class R, class... ArgTypes>
void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
template<class ForwardIterator1, class BinaryPredicate = equal_to<>> class default_searcher { public: constexpr default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last, BinaryPredicate pred = BinaryPredicate()); template<class ForwardIterator2> constexpr pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const; private: ForwardIterator1 pat_first_; // exposition only ForwardIterator1 pat_last_; // exposition only BinaryPredicate pred_; // exposition only };
constexpr default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
BinaryPredicate pred = BinaryPredicate());
template<class ForwardIterator2>
constexpr pair<ForwardIterator2, ForwardIterator2>
operator()(ForwardIterator2 first, ForwardIterator2 last) const;
template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_searcher { public: boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // exposition only RandomAccessIterator1 pat_last_; // exposition only Hash hash_; // exposition only BinaryPredicate pred_; // exposition only };
boyer_moore_searcher(RandomAccessIterator1 pat_first,
RandomAccessIterator1 pat_last,
Hash hf = Hash(),
BinaryPredicate pred = BinaryPredicate());
template<class RandomAccessIterator2>
pair<RandomAccessIterator2, RandomAccessIterator2>
operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>, class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher { public: boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; private: RandomAccessIterator1 pat_first_; // exposition only RandomAccessIterator1 pat_last_; // exposition only Hash hash_; // exposition only BinaryPredicate pred_; // exposition only };
boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first,
RandomAccessIterator1 pat_last,
Hash hf = Hash(),
BinaryPredicate pred = BinaryPredicate());
template<class RandomAccessIterator2>
pair<RandomAccessIterator2, RandomAccessIterator2>
operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
namespace std { // [meta.help], helper class template<class T, T v> struct integral_constant; template<bool B> using bool_constant = integral_constant<bool, B>; using true_type = bool_constant<true>; using false_type = bool_constant<false>; // [meta.unary.cat], primary type categories template<class T> struct is_void; template<class T> struct is_null_pointer; template<class T> struct is_integral; template<class T> struct is_floating_point; template<class T> struct is_array; template<class T> struct is_pointer; template<class T> struct is_lvalue_reference; template<class T> struct is_rvalue_reference; template<class T> struct is_member_object_pointer; template<class T> struct is_member_function_pointer; template<class T> struct is_enum; template<class T> struct is_union; template<class T> struct is_class; template<class T> struct is_function; // [meta.unary.comp], composite type categories template<class T> struct is_reference; template<class T> struct is_arithmetic; template<class T> struct is_fundamental; template<class T> struct is_object; template<class T> struct is_scalar; template<class T> struct is_compound; template<class T> struct is_member_pointer; // [meta.unary.prop], type properties template<class T> struct is_const; template<class T> struct is_volatile; template<class T> struct is_trivial; template<class T> struct is_trivially_copyable; template<class T> struct is_standard_layout; template<class T> struct is_empty; template<class T> struct is_polymorphic; template<class T> struct is_abstract; template<class T> struct is_final; template<class T> struct is_aggregate; template<class T> struct is_signed; template<class T> struct is_unsigned; template<class T> struct is_bounded_array; template<class T> struct is_unbounded_array; template<class T, class... Args> struct is_constructible; template<class T> struct is_default_constructible; template<class T> struct is_copy_constructible; template<class T> struct is_move_constructible; template<class T, class U> struct is_assignable; template<class T> struct is_copy_assignable; template<class T> struct is_move_assignable; template<class T, class U> struct is_swappable_with; template<class T> struct is_swappable; template<class T> struct is_destructible; template<class T, class... Args> struct is_trivially_constructible; template<class T> struct is_trivially_default_constructible; template<class T> struct is_trivially_copy_constructible; template<class T> struct is_trivially_move_constructible; template<class T, class U> struct is_trivially_assignable; template<class T> struct is_trivially_copy_assignable; template<class T> struct is_trivially_move_assignable; template<class T> struct is_trivially_destructible; template<class T, class... Args> struct is_nothrow_constructible; template<class T> struct is_nothrow_default_constructible; template<class T> struct is_nothrow_copy_constructible; template<class T> struct is_nothrow_move_constructible; template<class T, class U> struct is_nothrow_assignable; template<class T> struct is_nothrow_copy_assignable; template<class T> struct is_nothrow_move_assignable; template<class T, class U> struct is_nothrow_swappable_with; template<class T> struct is_nothrow_swappable; template<class T> struct is_nothrow_destructible; template<class T> struct has_virtual_destructor; template<class T> struct has_unique_object_representations; // [meta.unary.prop.query], type property queries template<class T> struct alignment_of; template<class T> struct rank; template<class T, unsigned I = 0> struct extent; // [meta.rel], type relations template<class T, class U> struct is_same; template<class Base, class Derived> struct is_base_of; template<class From, class To> struct is_convertible; template<class From, class To> struct is_nothrow_convertible; template<class T, class U> struct is_layout_compatible; template<class Base, class Derived> struct is_pointer_interconvertible_base_of; template<class Fn, class... ArgTypes> struct is_invocable; template<class R, class Fn, class... ArgTypes> struct is_invocable_r; template<class Fn, class... ArgTypes> struct is_nothrow_invocable; template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r; // [meta.trans.cv], const-volatile modifications template<class T> struct remove_const; template<class T> struct remove_volatile; template<class T> struct remove_cv; template<class T> struct add_const; template<class T> struct add_volatile; template<class T> struct add_cv; template<class T> using remove_const_t = typename remove_const<T>::type; template<class T> using remove_volatile_t = typename remove_volatile<T>::type; template<class T> using remove_cv_t = typename remove_cv<T>::type; template<class T> using add_const_t = typename add_const<T>::type; template<class T> using add_volatile_t = typename add_volatile<T>::type; template<class T> using add_cv_t = typename add_cv<T>::type; // [meta.trans.ref], reference modifications template<class T> struct remove_reference; template<class T> struct add_lvalue_reference; template<class T> struct add_rvalue_reference; template<class T> using remove_reference_t = typename remove_reference<T>::type; template<class T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; template<class T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; // [meta.trans.sign], sign modifications template<class T> struct make_signed; template<class T> struct make_unsigned; template<class T> using make_signed_t = typename make_signed<T>::type; template<class T> using make_unsigned_t = typename make_unsigned<T>::type; // [meta.trans.arr], array modifications template<class T> struct remove_extent; template<class T> struct remove_all_extents; template<class T> using remove_extent_t = typename remove_extent<T>::type; template<class T> using remove_all_extents_t = typename remove_all_extents<T>::type; // [meta.trans.ptr], pointer modifications template<class T> struct remove_pointer; template<class T> struct add_pointer; template<class T> using remove_pointer_t = typename remove_pointer<T>::type; template<class T> using add_pointer_t = typename add_pointer<T>::type; // [meta.trans.other], other transformations template<class T> struct type_identity; template<size_t Len, size_t Align = default-alignment> // see [meta.trans.other] struct aligned_storage; template<size_t Len, class... Types> struct aligned_union; template<class T> struct remove_cvref; template<class T> struct decay; template<bool, class T = void> struct enable_if; template<bool, class T, class F> struct conditional; template<class... T> struct common_type; template<class T, class U, template<class> class TQual, template<class> class UQual> struct basic_common_reference { }; template<class... T> struct common_reference; template<class T> struct underlying_type; template<class Fn, class... ArgTypes> struct invoke_result; template<class T> struct unwrap_reference; template<class T> struct unwrap_ref_decay; template<class T> using type_identity_t = typename type_identity<T>::type; template<size_t Len, size_t Align = default-alignment> // see [meta.trans.other] using aligned_storage_t = typename aligned_storage<Len, Align>::type; template<size_t Len, class... Types> using aligned_union_t = typename aligned_union<Len, Types...>::type; template<class T> using remove_cvref_t = typename remove_cvref<T>::type; template<class T> using decay_t = typename decay<T>::type; template<bool b, class T = void> using enable_if_t = typename enable_if<b, T>::type; template<bool b, class T, class F> using conditional_t = typename conditional<b, T, F>::type; template<class... T> using common_type_t = typename common_type<T...>::type; template<class... T> using common_reference_t = typename common_reference<T...>::type; template<class T> using underlying_type_t = typename underlying_type<T>::type; template<class Fn, class... ArgTypes> using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type; template<class T> using unwrap_reference_t = typename unwrap_reference<T>::type; template<class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; template<class...> using void_t = void; // [meta.logical], logical operator traits template<class... B> struct conjunction; template<class... B> struct disjunction; template<class B> struct negation; // [meta.unary.cat], primary type categories template<class T> inline constexpr bool is_void_v = is_void<T>::value; template<class T> inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value; template<class T> inline constexpr bool is_integral_v = is_integral<T>::value; template<class T> inline constexpr bool is_floating_point_v = is_floating_point<T>::value; template<class T> inline constexpr bool is_array_v = is_array<T>::value; template<class T> inline constexpr bool is_pointer_v = is_pointer<T>::value; template<class T> inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value; template<class T> inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value; template<class T> inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<T>::value; template<class T> inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<T>::value; template<class T> inline constexpr bool is_enum_v = is_enum<T>::value; template<class T> inline constexpr bool is_union_v = is_union<T>::value; template<class T> inline constexpr bool is_class_v = is_class<T>::value; template<class T> inline constexpr bool is_function_v = is_function<T>::value; // [meta.unary.comp], composite type categories template<class T> inline constexpr bool is_reference_v = is_reference<T>::value; template<class T> inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value; template<class T> inline constexpr bool is_fundamental_v = is_fundamental<T>::value; template<class T> inline constexpr bool is_object_v = is_object<T>::value; template<class T> inline constexpr bool is_scalar_v = is_scalar<T>::value; template<class T> inline constexpr bool is_compound_v = is_compound<T>::value; template<class T> inline constexpr bool is_member_pointer_v = is_member_pointer<T>::value; // [meta.unary.prop], type properties template<class T> inline constexpr bool is_const_v = is_const<T>::value; template<class T> inline constexpr bool is_volatile_v = is_volatile<T>::value; template<class T> inline constexpr bool is_trivial_v = is_trivial<T>::value; template<class T> inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value; template<class T> inline constexpr bool is_standard_layout_v = is_standard_layout<T>::value; template<class T> inline constexpr bool is_empty_v = is_empty<T>::value; template<class T> inline constexpr bool is_polymorphic_v = is_polymorphic<T>::value; template<class T> inline constexpr bool is_abstract_v = is_abstract<T>::value; template<class T> inline constexpr bool is_final_v = is_final<T>::value; template<class T> inline constexpr bool is_aggregate_v = is_aggregate<T>::value; template<class T> inline constexpr bool is_signed_v = is_signed<T>::value; template<class T> inline constexpr bool is_unsigned_v = is_unsigned<T>::value; template<class T> inline constexpr bool is_bounded_array_v = is_bounded_array<T>::value; template<class T> inline constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value; template<class T, class... Args> inline constexpr bool is_constructible_v = is_constructible<T, Args...>::value; template<class T> inline constexpr bool is_default_constructible_v = is_default_constructible<T>::value; template<class T> inline constexpr bool is_copy_constructible_v = is_copy_constructible<T>::value; template<class T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_assignable_v = is_assignable<T, U>::value; template<class T> inline constexpr bool is_copy_assignable_v = is_copy_assignable<T>::value; template<class T> inline constexpr bool is_move_assignable_v = is_move_assignable<T>::value; template<class T, class U> inline constexpr bool is_swappable_with_v = is_swappable_with<T, U>::value; template<class T> inline constexpr bool is_swappable_v = is_swappable<T>::value; template<class T> inline constexpr bool is_destructible_v = is_destructible<T>::value; template<class T, class... Args> inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value; template<class T> inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<T>::value; template<class T> inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value; template<class T> inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value; template<class T> inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<T>::value; template<class T> inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<T>::value; template<class T> inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value; template<class T, class... Args> inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value; template<class T> inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<T>::value; template<class T> inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value; template<class T> inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value; template<class T, class U> inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value; template<class T> inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value; template<class T> inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<T>::value; template<class T, class U> inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value; template<class T> inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value; template<class T> inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value; template<class T> inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value; template<class T> inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<T>::value; // [meta.unary.prop.query], type property queries template<class T> inline constexpr size_t alignment_of_v = alignment_of<T>::value; template<class T> inline constexpr size_t rank_v = rank<T>::value; template<class T, unsigned I = 0> inline constexpr size_t extent_v = extent<T, I>::value; // [meta.rel], type relations template<class T, class U> inline constexpr bool is_same_v = is_same<T, U>::value; template<class Base, class Derived> inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value; template<class From, class To> inline constexpr bool is_convertible_v = is_convertible<From, To>::value; template<class From, class To> inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value; template<class T, class U> inline constexpr bool is_layout_compatible_v = is_layout_compatible<T, U>::value; template<class Base, class Derived> inline constexpr bool is_pointer_interconvertible_base_of_v = is_pointer_interconvertible_base_of<Base, Derived>::value; template<class Fn, class... ArgTypes> inline constexpr bool is_invocable_v = is_invocable<Fn, ArgTypes...>::value; template<class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value; template<class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value; template<class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value; // [meta.logical], logical operator traits template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value; template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value; template<class B> inline constexpr bool negation_v = negation<B>::value; // [meta.member], member relationships template<class S, class M> constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept; template<class S1, class S2, class M1, class M2> constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept; // [meta.const.eval], constant evaluation context constexpr bool is_constant_evaluated() noexcept; }
namespace std { template<class T, T v> struct integral_constant { static constexpr T value = v; using value_type = T; using type = integral_constant<T, v>; constexpr operator value_type() const noexcept { return value; } constexpr value_type operator()() const noexcept { return value; } }; }
Template | Condition | Comments |
T is void | ||
T is an integral type ([basic.fundamental]) | ||
T is a floating-point type ([basic.fundamental]) | ||
T is an array type ([basic.compound]) of known or unknown extent | ||
T is a pointer type ([basic.compound]) | Includes pointers to functions
but not pointers to non-static members. | |
T is an lvalue reference type ([dcl.ref]) | ||
T is an rvalue reference type ([dcl.ref]) | ||
T is a pointer to data member | ||
T is a pointer to member function | ||
T is an enumeration type ([basic.compound]) | ||
T is a union type ([basic.compound]) | ||
T is a non-union class type ([basic.compound]) | ||
T is a function type ([basic.compound]) |
Template | Condition | Comments |
T is an lvalue reference or an rvalue reference | ||
T is an arithmetic type ([basic.fundamental]) | ||
T is a fundamental type ([basic.fundamental]) | ||
T is an object type ([basic.types]) | ||
T is a scalar type ([basic.types]) | ||
T is a compound type ([basic.compound]) | ||
T is a pointer-to-member type |
Template | Condition | Preconditions |
T is const-qualified ([basic.type.qualifier]) | ||
T is volatile-qualified ([basic.type.qualifier]) | ||
T is a trivial type ([basic.types]) | ||
T is a trivially copyable type ([basic.types]) | ||
T is a standard-layout type ([basic.types]) | ||
T is a class type, but not a union type, with no non-static data
members other than subobjects of zero size, no virtual member functions,
no virtual base classes, and no base class B for
which is_empty_v<B> is false. | ||
T is a polymorphic class ([class.virtual]) | ||
T is an abstract class ([class.abstract]) | ||
T is an aggregate type ([dcl.init.aggr]) | ||
If is_arithmetic_v<T> is true, the same result as
T(-1) < T(0);
otherwise, false | ||
If is_arithmetic_v<T> is true, the same result as
T(0) < T(-1);
otherwise, false | ||
T is an array type of known bound ([dcl.array]) | ||
T is an array type of unknown bound ([dcl.array]) | ||
For a function type T or
for a cv void type T,
is_constructible_v<T, Args...> is false,
otherwise see below | T and all types in the template parameter pack Args
shall be complete types, cv void,
or arrays of unknown bound. | |
For a referenceable type T ([defns.referenceable]), the same result as
is_constructible_v<T, const T&>, otherwise false. | ||
Only the validity of the immediate context
of the assignment expression is considered. [Note : ]The compilation of the
expression can result in side effects such as the instantiation of class template
specializations and function template specializations, the generation of
implicitly-defined functions, and so on. Such side effects are not in the “immediate
context” and can result in the program being ill-formed. — end note | ||
The expressions swap(declval<T>(), declval<U>()) and
swap(declval<U>(), declval<T>()) are each well-formed
when treated as an unevaluated operand
in an overload-resolution context
for swappable values ([swappable.requirements]). Only the validity of the immediate context
of the swap expressions is considered. [Note : ]The compilation of the expressions can result in side effects
such as the instantiation of class template specializations and
function template specializations,
the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and
can result in the program being ill-formed. — end note | ||
Either T is a reference type,
or T is a complete object type
for which the expression
declval<U&>().~U()
is well-formed
when treated as an unevaluated operand,
where U is
remove_all_extents_t<T>. | ||
is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known to call no operation that is not trivial ([basic.types], [special]). | T and all types in the template parameter pack Args shall be complete types,
cv void, or arrays of unknown bound. | |
For a referenceable type T, the same result as
is_trivially_constructible_v<T, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_trivially_constructible_v<T, T&&>, otherwise false. | ||
is_assignable_v<T, U> is true and the assignment, as defined by
is_assignable, is known to call no operation that is not trivial
([basic.types], [special]). | ||
For a referenceable type T, the same result as
is_trivially_assignable_v<T&, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_trivially_assignable_v<T&, T&&>, otherwise false. | ||
is_destructible_v<T> is true and
remove_all_extents_t<T> is either a non-class type or
a class type with a trivial destructor. | ||
is_constructible_v<T, Args...> is true
and the
variable definition for is_constructible, as defined below, is known not to
throw any exceptions ([expr.unary.noexcept]). | T and all types in the template parameter pack Args
shall be complete types, cv void,
or arrays of unknown bound. | |
For a referenceable type T, the same result as
is_nothrow_constructible_v<T, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_nothrow_constructible_v<T, T&&>, otherwise false. | ||
is_assignable_v<T, U> is true and the assignment is known not to
throw any exceptions ([expr.unary.noexcept]). | ||
For a referenceable type T, the same result as
is_nothrow_assignable_v<T&, const T&>, otherwise false. | ||
For a referenceable type T, the same result as
is_nothrow_assignable_v<T&, T&&>, otherwise false. | ||
is_swappable_with_v<T, U> is true and
each swap expression of the definition of
is_swappable_with<T, U> is known not to throw
any exceptions ([expr.unary.noexcept]). | ||
For a referenceable type T,
the same result as is_nothrow_swappable_with_v<T&, T&>,
otherwise false. | ||
is_destructible_v<T> is true and the indicated destructor is known
not to throw any exceptions ([expr.unary.noexcept]). | ||
T has a virtual destructor ([class.dtor]) | ||
For an array type T, the same result as
has_unique_object_representations_v<remove_all_extents_t<T>>,
otherwise see below. |
is_const_v<const volatile int> // true is_const_v<const int*> // false is_const_v<const int&> // false is_const_v<int[3]> // false is_const_v<const int[3]> // true— end example
remove_const_t<const volatile int> // volatile int remove_const_t<const int* const> // const int* remove_const_t<const int&> // const int& remove_const_t<const int[3]> // int[3]— end example
// Given: struct P final { }; union U1 { }; union U2 final { }; // the following assertions hold: static_assert(!is_final_v<int>); static_assert(is_final_v<P>); static_assert(!is_final_v<U1>); static_assert(is_final_v<U2>);— end example
T t(declval<Args>()...);
Template | Value |
alignof(T). | |
If T names an array type, an integer value representing
the number of dimensions of T; otherwise, 0. | |
If T is not an array type, or if it has rank less
than or equal to I, or if I is 0 and T
has type “array of unknown bound of U”, then
0; otherwise, the bound ([dcl.array]) of the dimension of
T, where indexing of I is zero-based |
// the following assertions hold: assert(rank_v<int> == 0); assert(rank_v<int[2]> == 1); assert(rank_v<int[][4]> == 2);— end example
// the following assertions hold: assert(extent_v<int> == 0); assert(extent_v<int[2]> == 2); assert(extent_v<int[2][4]> == 2); assert(extent_v<int[][4]> == 0); assert((extent_v<int, 1>) == 0); assert((extent_v<int[2], 1>) == 0); assert((extent_v<int[2][4], 1>) == 4); assert((extent_v<int[][4], 1>) == 4);— end example
Template | Condition | Comments |
template<class T, class U> struct is_same; | T and U name the same type with the same cv-qualifications | |
Base is a base class of Derived ([class.derived])
without regard to cv-qualifiers
or Base and Derived are not unions and
name the same class type
without regard to cv-qualifiers | If Base and
Derived are non-union class types and are
not possibly cv-qualified versions of the same type,
Derived shall be a complete
type. | |
see below | ||
is_convertible_v<From, To> is true and
the conversion, as defined by is_convertible,
is known not to throw any exceptions ([expr.unary.noexcept]) | ||
Derived is unambiguously derived from Base
without regard to cv-qualifiers,
and each object of type Derived
is pointer-interconvertible ([basic.compound]) with
its Base subobject,
or Base and Derived are not unions
and name the same class type
without regard to cv-qualifiers. | If Base and Derived are non-union class types
and are not (possibly cv-qualified versions of) the same type,
Derived shall be a complete type. | |
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand | Fn and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand | Fn, R, and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
is_invocable_v< Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([expr.unary.noexcept]) | Fn and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. | |
is_invocable_r_v< R, Fn, ArgTypes...> is true and the expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([expr.unary.noexcept]) | Fn, R, and all types in the template parameter pack ArgTypes
shall be complete types, cv void, or
arrays of unknown bound. |
struct B {}; struct B1 : B {}; struct B2 : B {}; struct D : private B1, private B2 {}; is_base_of_v<B, D> // true is_base_of_v<const B, D> // true is_base_of_v<B, const D> // true is_base_of_v<B, const B> // true is_base_of_v<D, B> // false is_base_of_v<B&, D&> // false is_base_of_v<B[3], D[3]> // false is_base_of_v<int, int> // false— end example
To test() { return declval<From>(); }
Template | Comments |
The member typedef type names
the same type as T
except that any top-level const-qualifier has been removed. | |
The member typedef type names
the same type as T
except that any top-level volatile-qualifier has been removed. | |
The member typedef type shall be the same as T
except that any top-level cv-qualifier has been removed. | |
If T is a reference, function, or top-level const-qualified
type, then type names
the same type as T, otherwise
T const. | |
If T is a reference, function, or top-level volatile-qualified
type, then type names
the same type as T, otherwise
T volatile. | |
Template | Comments |
If T names a (possibly cv-qualified)
signed integer type then the member typedef
type names the type T; otherwise,
if T names a (possibly cv-qualified) unsigned integer
type then type names the corresponding
signed integer type, with the same cv-qualifiers as T;
otherwise, type names the signed integer type with smallest
rank for which
sizeof(T) == sizeof(type), with the same
cv-qualifiers as T. | |
If T names a (possibly cv-qualified)
unsigned integer type then the member typedef
type names the type T; otherwise,
if T names a (possibly cv-qualified) signed integer
type then type names the corresponding
unsigned integer type, with the same cv-qualifiers as T;
otherwise, type names the unsigned integer type with smallest
rank for which
sizeof(T) == sizeof(type), with the same
cv-qualifiers as T. |
// the following assertions hold: assert((is_same_v<remove_extent_t<int>, int>)); assert((is_same_v<remove_extent_t<int[2]>, int>)); assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>)); assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));— end example
Template | Comments |
If T has type “(possibly cv-qualified) pointer
to T1” then the member typedef type
names T1; otherwise, it names T. | |
If T names a referenceable type or a
cv void type then
the member typedef type names the same type as
remove_reference_t<T>*;
otherwise, type names T. |
Template | Comments |
The value of default-alignment shall be the most
stringent alignment requirement for any object type whose size
is no greater than Len ([basic.types]). The member typedef type shall be a trivial standard-layout type
suitable for use as uninitialized storage for any object whose size
is at most Len and whose alignment is a divisor of Align. | |
The member typedef type shall be a trivial standard-layout type suitable for use as
uninitialized storage for any object whose type is listed in Types;
its size shall be at least Len. The static member alignment_value
shall be an integral constant of type size_t whose value is the
strictest alignment of all types listed in Types. Each type in the template parameter pack Types
is a complete object type. | |
[Note : ]This behavior is similar to the lvalue-to-rvalue ([conv.lval]),
array-to-pointer ([conv.array]), and function-to-pointer ([conv.func])
conversions applied when an lvalue is used as an rvalue, but also
strips cv-qualifiers from class types in order to more closely model by-value
argument passing. — end note | |
template<bool B, class T,
class F> struct conditional; | |
template<class... T> struct common_type; | Unless this trait is specialized (as specified in Note B, below),
the member type is defined or omitted as specified in Note A, below. If it is omitted, there shall be no member type. Each type in the template parameter pack T shall be
complete, cv void, or an array of unknown bound. |
Unless this trait is specialized (as specified in Note D, below),
there shall be no member type. | |
If T is an enumeration type, the member typedef type names
the underlying type of T ([dcl.enum]);
otherwise, there is no member type. | |
template<class Fn, class... ArgTypes> struct invoke_result; | If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand,
the member typedef type names the type
decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));
otherwise, there shall be no member type. 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 notePreconditions: Fn and all types in the template parameter pack ArgTypes are complete types, cv void, or arrays of unknown bound. |
If T is
a specialization reference_wrapper<X> for some type X,
the member typedef type of unwrap_reference<T> is X&,
otherwise it is T. | |
The member typedef type of unwrap_ref_decay<T>
denotes the type unwrap_reference_t<decay_t<T>>. |
template<size_t Len, size_t Alignment> struct aligned_storage { typedef struct { alignas(Alignment) unsigned char __data[Len]; } type; };
decay_t<decltype(false ? declval<D1>() : declval<D2>())>denotes a valid type, let C denote that type.
using PF1 = bool (&)(); using PF2 = short (*)(long); struct S { operator PF2() const; double operator()(char, int&); void fn(long) const; char data; }; using PMF = void (S::*)(long) const; using PMD = char S::*;the following assertions will hold:
static_assert(is_same_v<invoke_result_t<S, int>, short>); static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>); static_assert(is_same_v<invoke_result_t<PF1>, bool>); static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>); static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>); static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
template<class... B> struct conjunction : see below { };
template<class... B> struct disjunction : see below { };
template<class B> struct negation : see below { };
template<class S, class M>
constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept;
template<class S1, class S2, class M1, class M2>
constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
struct A { int a; }; // a standard-layout class struct B { int b; }; // a standard-layout class struct C: public A, public B { }; // not a standard-layout class static_assert( is_pointer_interconvertible_with_class( &C::b ) ); // Succeeds because, despite its appearance, &C::b has type // “pointer to member of B of type int”. static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) ); // Forces the use of class C, and fails. static_assert( is_corresponding_member( &C::a, &C::b ) ); // Succeeds because, despite its appearance, &C::a and &C::b have types // “pointer to member of A of type int” and // “pointer to member of B of type int”, respectively. static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) ); // Forces the use of class C, and fails.— end example
constexpr bool is_constant_evaluated() noexcept;
namespace std { // [ratio.ratio], class template ratio template<intmax_t N, intmax_t D = 1> class ratio; // [ratio.arithmetic], ratio arithmetic template<class R1, class R2> using ratio_add = see below; template<class R1, class R2> using ratio_subtract = see below; template<class R1, class R2> using ratio_multiply = see below; template<class R1, class R2> using ratio_divide = see below; // [ratio.comparison], ratio comparison template<class R1, class R2> struct ratio_equal; template<class R1, class R2> struct ratio_not_equal; template<class R1, class R2> struct ratio_less; template<class R1, class R2> struct ratio_less_equal; template<class R1, class R2> struct ratio_greater; template<class R1, class R2> struct ratio_greater_equal; template<class R1, class R2> inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value; template<class R1, class R2> inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value; template<class R1, class R2> inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value; template<class R1, class R2> inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value; template<class R1, class R2> inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value; template<class R1, class R2> inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value; // [ratio.si], convenience SI typedefs using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; // see below using zepto = ratio<1, 1'000'000'000'000'000'000'000>; // see below using atto = ratio<1, 1'000'000'000'000'000'000>; using femto = ratio<1, 1'000'000'000'000'000>; using pico = ratio<1, 1'000'000'000'000>; using nano = ratio<1, 1'000'000'000>; using micro = ratio<1, 1'000'000>; using milli = ratio<1, 1'000>; using centi = ratio<1, 100>; using deci = ratio<1, 10>; using deca = ratio< 10, 1>; using hecto = ratio< 100, 1>; using kilo = ratio< 1'000, 1>; using mega = ratio< 1'000'000, 1>; using giga = ratio< 1'000'000'000, 1>; using tera = ratio< 1'000'000'000'000, 1>; using peta = ratio< 1'000'000'000'000'000, 1>; using exa = ratio< 1'000'000'000'000'000'000, 1>; using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; // see below using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>; // see below }
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>; }; }
Type | Value of X | Value of Y |
ratio_add<R1, R2> | R1::num * R2::den + | R1::den * R2::den |
R2::num * R1::den | ||
ratio_subtract<R1, R2> | R1::num * R2::den - | R1::den * R2::den |
R2::num * R1::den | ||
ratio_multiply<R1, R2> | R1::num * R2::num | R1::den * R2::den |
ratio_divide<R1, R2> | R1::num * R2::den | R1::den * R2::num |
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::num == 1, "1/3+1/6 == 1/2"); static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2"); static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2"); static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::den == 2, "1/3*3/2 == 1/2"); // The following cases may cause the program to be ill-formed under some implementations static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::num == 2, "1/MAX+1/MAX == 2/MAX"); static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::den == INT_MAX, "1/MAX+1/MAX == 2/MAX"); static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::num == 1, "1/MAX * MAX/2 == 1/2"); static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::den == 2, "1/MAX * MAX/2 == 1/2");— end example
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> { };
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>> { };
#include <compare> // see [compare.syn] namespace std { class type_index; template<class T> struct hash; template<> struct hash<type_index>; }
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; strong_ordering operator<=>(const type_index& rhs) const noexcept; size_t hash_code() const noexcept; const char* name() const noexcept; private: const type_info* target; // exposition only // Note that the use of a pointer here, rather than a reference, // means that the default copy/move constructor and assignment // operators will be provided and work as expected. }; }
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;
strong_ordering operator<=>(const type_index& rhs) const noexcept;
if (*target == *rhs.target) return strong_ordering::equal; if (target->before(*rhs.target)) return strong_ordering::less; return strong_ordering::greater;
size_t hash_code() const noexcept;
const char* name() const noexcept;
using namespace std; vector<int> v = /* ... */; // standard sequential sort sort(v.begin(), v.end()); // explicitly sequential sort sort(execution::seq, v.begin(), v.end()); // permitting parallel execution sort(execution::par, v.begin(), v.end()); // permitting vectorization as well sort(execution::par_unseq, v.begin(), v.end());— end example
namespace std { // [execpol.type], execution policy type trait template<class T> struct is_execution_policy; template<class T> inline constexpr bool is_execution_policy_v = is_execution_policy<T>::value; } namespace std::execution { // [execpol.seq], sequenced execution policy class sequenced_policy; // [execpol.par], parallel execution policy class parallel_policy; // [execpol.parunseq], parallel and unsequenced execution policy class parallel_unsequenced_policy; // [execpol.unseq], unsequenced execution policy class unsequenced_policy; // [execpol.objects], execution policy objects inline constexpr sequenced_policy seq{ unspecified }; inline constexpr parallel_policy par{ unspecified }; inline constexpr parallel_unsequenced_policy par_unseq{ unspecified }; inline constexpr unsequenced_policy unseq{ unspecified }; }
template<class T> struct is_execution_policy { see below };
class execution::sequenced_policy { unspecified };
class execution::parallel_unsequenced_policy { unspecified };
class execution::unsequenced_policy { unspecified };
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 };
inline constexpr execution::unsequenced_policy execution::unseq{ unspecified };
namespace std { // floating-point format for primitive numerical conversion enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific }; // [charconv.to.chars], primitive numerical output conversion struct to_chars_result { char* ptr; errc ec; friend bool operator==(const to_chars_result&, const to_chars_result&) = default; }; to_chars_result to_chars(char* first, char* last, see below value, int base = 10); to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; 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); // [charconv.from.chars], primitive numerical input conversion struct from_chars_result { const char* ptr; errc ec; friend bool operator==(const from_chars_result&, const from_chars_result&) = default; }; 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); }
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);
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);
namespace std { // [format.functions], formatting functions template<class... Args> string format(string_view fmt, const Args&... args); template<class... Args> wstring format(wstring_view fmt, const Args&... args); template<class... Args> string format(const locale& loc, string_view fmt, const Args&... args); template<class... Args> wstring format(const locale& loc, wstring_view fmt, const Args&... args); string vformat(string_view fmt, format_args args); wstring vformat(wstring_view fmt, wformat_args args); string vformat(const locale& loc, string_view fmt, format_args args); wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); template<class Out, class... Args> Out format_to(Out out, string_view fmt, const Args&... args); template<class Out, class... Args> Out format_to(Out out, wstring_view fmt, const Args&... args); template<class Out, class... Args> Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); template<class Out, class... Args> Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); template<class Out> Out vformat_to(Out out, string_view fmt, format_args_t<type_identity_t<Out>, char> args); template<class Out> Out vformat_to(Out out, wstring_view fmt, format_args_t<type_identity_t<Out>, wchar_t> args); template<class Out> Out vformat_to(Out out, const locale& loc, string_view fmt, format_args_t<type_identity_t<Out>, char> args); template<class Out> Out vformat_to(Out out, const locale& loc, wstring_view fmt, format_args_t<type_identity_t<Out>, wchar_t> args); template<class Out> struct format_to_n_result { Out out; iter_difference_t<Out> size; }; template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args); template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, wstring_view fmt, const Args&... args); template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, string_view fmt, const Args&... args); template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, const locale& loc, wstring_view fmt, const Args&... args); template<class... Args> size_t formatted_size(string_view fmt, const Args&... args); template<class... Args> size_t formatted_size(wstring_view fmt, const Args&... args); template<class... Args> size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); template<class... Args> size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); // [format.formatter], formatter template<class T, class charT = char> struct formatter; // [format.parse.ctx], class template basic_format_parse_context template<class charT> class basic_format_parse_context; using format_parse_context = basic_format_parse_context<char>; using wformat_parse_context = basic_format_parse_context<wchar_t>; // [format.context], class template basic_format_context template<class Out, class charT> class basic_format_context; using format_context = basic_format_context<unspecified, char>; using wformat_context = basic_format_context<unspecified, wchar_t>; // [format.arguments], arguments // [format.arg], class template basic_format_arg template<class Context> class basic_format_arg; template<class Visitor, class Context> see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); // [format.arg.store], class template format-arg-store template<class Context, class... Args> struct format-arg-store; // exposition only template<class Context = format_context, class... Args> format-arg-store<Context, Args...> make_format_args(const Args&... args); template<class... Args> format-arg-store<wformat_context, Args...> make_wformat_args(const Args&... args); // [format.args], class template basic_format_args template<class Context> class basic_format_args; using format_args = basic_format_args<format_context>; using wformat_args = basic_format_args<wformat_context>; template<class Out, class charT> using format_args_t = basic_format_args<basic_format_context<Out, charT>>; // [format.error], class format_error class format_error; }
string s0 = format("{} to {}", "a", "b"); // OK, automatic indexing string s1 = format("{1} to {0}", "a", "b"); // OK, manual indexing string s2 = format("{0} to {}", "a", "b"); // not a format string (mixing automatic and manual indexing), // throws format_error string s3 = format("{} to {1}", "a", "b"); // not a format string (mixing automatic and manual indexing), // throws format_error— end example
char c = 120; string s0 = format("{:6}", 42); // value of s0 is " 42" string s1 = format("{:6}", 'x'); // value of s1 is "x " string s2 = format("{:*<6}", 'x'); // value of s2 is "x*****" string s3 = format("{:*>6}", 'x'); // value of s3 is "*****x" string s4 = format("{:*^6}", 'x'); // value of s4 is "**x***" string s5 = format("{:6d}", c); // value of s5 is " 120" string s6 = format("{:6}", true); // value of s6 is "true "— end example
Option | Meaning |
< | Forces the field to be aligned to the start of the available space. This is the default for
non-arithmetic types, charT, and bool,
unless an integer presentation type is specified. |
> | Forces the field to be aligned to the end of the available space. This is the default for
arithmetic types other than charT and bool
or when an integer presentation type is specified. |
^ | Forces the field to be centered within the available space
by inserting
characters before and
characters after the value, where
n is the total number of fill characters to insert. |
Option | Meaning |
+ | Indicates that a sign should be used for both non-negative and negative
numbers. The + sign is inserted before the output of to_chars for
non-negative numbers other than negative zero. |
- | Indicates that a sign should be used for
negative numbers and negative zero only (this is the default behavior). |
space | Indicates that a leading space should be used for
non-negative numbers other than negative zero, and
a minus sign for negative numbers and negative zero. |
double inf = numeric_limits<double>::infinity(); double nan = numeric_limits<double>::quiet_NaN(); string s0 = format("{0:},{0:+},{0:-},{0: }", 1); // value of s0 is "1,+1,1, 1" string s1 = format("{0:},{0:+},{0:-},{0: }", -1); // value of s1 is "-1,-1,-1,-1" string s2 = format("{0:},{0:+},{0:-},{0: }", inf); // value of s2 is "inf,+inf,inf, inf" string s3 = format("{0:},{0:+},{0:-},{0: }", nan); // value of s3 is "nan,+nan,nan, nan"— end example
char c = 120; string s1 = format("{:+06d}", c); // value of s1 is "+00120" string s2 = format("{:#06x}", 0xa); // value of s2 is "0x000a" string s3 = format("{:<06}", -42); // value of s3 is "-42 " (0 is ignored because of < alignment)— end example
string s0 = format("{}", 42); // value of s0 is "42" string s1 = format("{0:b} {0:d} {0:o} {0:x}", 42); // value of s1 is "101010 42 52 2a" string s2 = format("{0:#x} {0:#X}", 42); // value of s2 is "0x2a 0X2A" string s3 = format("{:L}", 1234); // value of s3 might be "1,234" // (depending on the locale)— end example
Type | Meaning |
a | If precision is specified, equivalent to
to_chars(first, last, value, chars_format::hex, precision)where precision is the specified formatting precision; equivalent to to_chars(first, last, value, chars_format::hex)otherwise. |
A | The same as a, except that
it uses uppercase letters for digits above 9 and
P to indicate the exponent. |
e | Equivalent to
to_chars(first, last, value, chars_format::scientific, precision)where precision is the specified formatting precision, or 6 if precision is not specified. |
E | |
f, F | Equivalent to
to_chars(first, last, value, chars_format::fixed, precision)where precision is the specified formatting precision, or 6 if precision is not specified. |
g | Equivalent to
to_chars(first, last, value, chars_format::general, precision)where precision is the specified formatting precision, or 6 if precision is not specified. |
G | |
none | If precision is specified, equivalent to
to_chars(first, last, value, chars_format::general, precision)where precision is the specified formatting precision; equivalent to to_chars(first, last, value)otherwise. |
template<class... Args>
string format(string_view fmt, const Args&... args);
template<class... Args>
wstring format(wstring_view fmt, const Args&... args);
template<class... Args>
string format(const locale& loc, string_view fmt, const Args&... args);
template<class... Args>
wstring format(const locale& loc, wstring_view fmt, const Args&... args);
string vformat(string_view fmt, format_args args);
wstring vformat(wstring_view fmt, wformat_args args);
string vformat(const locale& loc, string_view fmt, format_args args);
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
template<class Out, class... Args>
Out format_to(Out out, string_view fmt, const Args&... args);
template<class Out, class... Args>
Out format_to(Out out, wstring_view fmt, const Args&... args);
using context = basic_format_context<Out, decltype(fmt)::value_type>; return vformat_to(out, fmt, make_format_args<context>(args...));
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);
using context = basic_format_context<Out, decltype(fmt)::value_type>; return vformat_to(out, loc, fmt, make_format_args<context>(args...));
template<class Out>
Out vformat_to(Out out, string_view fmt,
format_args_t<type_identity_t<Out>, char> args);
template<class Out>
Out vformat_to(Out out, wstring_view fmt,
format_args_t<type_identity_t<Out>, wchar_t> args);
template<class Out>
Out vformat_to(Out out, const locale& loc, string_view fmt,
format_args_t<type_identity_t<Out>, char> args);
template<class Out>
Out vformat_to(Out out, const locale& loc, wstring_view fmt,
format_args_t<type_identity_t<Out>, wchar_t> args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
string_view fmt, const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
wstring_view fmt, const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, string_view fmt,
const Args&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wstring_view fmt,
const Args&... args);
template<class... Args>
size_t formatted_size(string_view fmt, const Args&... args);
template<class... Args>
size_t formatted_size(wstring_view fmt, const Args&... args);
template<class... Args>
size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
template<class... Args>
size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);
Expression | Return type | Requirement |
f.parse(pc) | PC::iterator | Parses format-spec ([format.string])
for type T
in the range [pc.begin(), pc.end())
until the first unmatched character.
Stores the parsed format specifiers in *this and
returns an iterator past the end of the parsed range. |
f.format(t, fc) | FC::iterator | Formats t according to the specifiers stored in *this,
writes the output to fc.out() and
returns an iterator past the end of the output range. The output shall only depend on
t,
fc.locale(),
and the range [pc.begin(), pc.end())
from the last call to f.parse(pc). |
f.format(u, fc) | FC::iterator | As above, but does not modify u. |
template<> struct formatter<char, char>; template<> struct formatter<char, wchar_t>; template<> struct formatter<wchar_t, wchar_t>;
template<> struct formatter<charT*, charT>; template<> struct formatter<const charT*, charT>; template<size_t N> struct formatter<const charT[N], charT>; template<class traits, class Allocator> struct formatter<basic_string<charT, traits, Allocator>, charT>; template<class traits> struct formatter<basic_string_view<charT, traits>, charT>;
template<> struct formatter<ArithmeticT, charT>;
template<> struct formatter<nullptr_t, charT>; template<> struct formatter<void*, charT>; template<> struct formatter<const void*, charT>;
#include <format> enum color { red, green, blue }; const char* color_names[] = { "red", "green", "blue" }; template<> struct std::formatter<color> : std::formatter<const char*> { auto format(color c, format_context& ctx) { return formatter<const char*>::format(color_names[c], ctx); } }; struct err {}; std::string s0 = std::format("{}", 42); // OK, library-provided formatter std::string s1 = std::format("{}", L"foo"); // error: disabled formatter std::string s2 = std::format("{}", red); // OK, user-provided formatter std::string s3 = std::format("{}", err{}); // error: disabled formatter— end example
namespace std { template<class charT> class basic_format_parse_context { public: using char_type = charT; using const_iterator = typename basic_string_view<charT>::const_iterator; using iterator = const_iterator; private: iterator begin_; // exposition only iterator end_; // exposition only enum indexing { unknown, manual, automatic }; // exposition only indexing indexing_; // exposition only size_t next_arg_id_; // exposition only size_t num_args_; // exposition only public: constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, size_t num_args = 0) noexcept; basic_format_parse_context(const basic_format_parse_context&) = delete; basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; constexpr const_iterator begin() const noexcept; constexpr const_iterator end() const noexcept; constexpr void advance_to(const_iterator it); constexpr size_t next_arg_id(); constexpr void check_arg_id(size_t id); }; }
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
size_t num_args = 0) noexcept;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr void advance_to(const_iterator it);
constexpr size_t next_arg_id();
if (indexing_ == unknown) indexing_ = automatic; return next_arg_id_++;
constexpr void check_arg_id(size_t id);
namespace std { template<class Out, class charT> class basic_format_context { basic_format_args<basic_format_context> args_; // exposition only Out out_; // exposition only public: using iterator = Out; using char_type = charT; template<class T> using formatter_type = formatter<T, charT>; basic_format_arg<basic_format_context> arg(size_t id) const; std::locale locale(); iterator out(); void advance_to(iterator it); }; }
basic_format_arg<basic_format_context> arg(size_t id) const;
std::locale locale();
iterator out();
void advance_to(iterator it);
struct S { int value; }; template<> struct std::formatter<S> { size_t width_arg_id = 0; // Parses a width argument id in the format { digit }. constexpr auto parse(format_parse_context& ctx) { auto iter = ctx.begin(); auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; }; if (get_char() != '{') return iter; ++iter; char c = get_char(); if (!isdigit(c) || (++iter, get_char()) != '}') throw format_error("invalid format"); width_arg_id = c - '0'; ctx.check_arg_id(width_arg_id); return ++iter; } // Formats an S with width given by the argument width_arg_id. auto format(S s, format_context& ctx) { int width = visit_format_arg([](auto value) -> int { if constexpr (!is_integral_v<decltype(value)>) throw format_error("width is not integral"); else if (value < 0 || value > numeric_limits<int>::max()) throw format_error("invalid width"); else return value; }, ctx.arg(width_arg_id)); return format_to(ctx.out(), "{0:x<{1}}", s.value, width); } }; std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42"— end example
namespace std { template<class Context> class basic_format_arg { public: class handle; private: using char_type = typename Context::char_type; // exposition only variant<monostate, bool, char_type, int, unsigned int, long long int, unsigned long long int, float, double, long double, const char_type*, basic_string_view<char_type>, const void*, handle> value; // exposition only template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only explicit basic_format_arg(float n) noexcept; // exposition only explicit basic_format_arg(double n) noexcept; // exposition only explicit basic_format_arg(long double n) noexcept; // exposition only explicit basic_format_arg(const char_type* s); // exposition only template<class traits> explicit basic_format_arg( basic_string_view<char_type, traits> s) noexcept; // exposition only template<class traits, class Allocator> explicit basic_format_arg( const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only explicit basic_format_arg(nullptr_t) noexcept; // exposition only template<class T> explicit basic_format_arg(const T* p) noexcept; // exposition only public: basic_format_arg() noexcept; explicit operator bool() const noexcept; }; }
basic_format_arg() noexcept;
template<class T> explicit basic_format_arg(const T& v) noexcept;
typename Context::template formatter_type<T>meets the Formatter requirements ([formatter.requirements]).
typename Context::template formatter_type<T>() .format(declval<const T&>(), declval<Context&>())shall be well-formed when treated as an unevaluated operand.
explicit basic_format_arg(float n) noexcept;
explicit basic_format_arg(double n) noexcept;
explicit basic_format_arg(long double n) noexcept;
explicit basic_format_arg(const char_type* s);
template<class traits>
explicit basic_format_arg(basic_string_view<char_type, traits> s) noexcept;
template<class traits, class Allocator>
explicit basic_format_arg(
const basic_string<char_type, traits, Allocator>& s) noexcept;
explicit basic_format_arg(nullptr_t) noexcept;
template<class T> explicit basic_format_arg(const T* p) noexcept;
explicit operator bool() const noexcept;
namespace std { template<class Context> class basic_format_arg<Context>::handle { const void* ptr_; // exposition only void (*format_)(basic_format_parse_context<char_type>&, Context&, const void*); // exposition only template<class T> explicit handle(const T& val) noexcept; // exposition only friend class basic_format_arg<Context>; // exposition only public: void format(basic_format_parse_context<char_type>&, Context& ctx) const; }; }
template<class T> explicit handle(const T& val) noexcept;
[](basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx, const void* ptr) { typename Context::template formatter_type<T> f; parse_ctx.advance_to(f.parse(parse_ctx)); format_ctx.advance_to(f.format(*static_cast<const T*>(ptr), format_ctx)); }
void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
template<class Visitor, class Context>
see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
namespace std { template<class Context, class... Args> struct format-arg-store { // exposition only array<basic_format_arg<Context>, sizeof...(Args)> args; }; }
template<class Context = format_context, class... Args>
format-arg-store<Context, Args...> make_format_args(const Args&... args);
template<class... Args>
format-arg-store<wformat_context, Args...> make_wformat_args(const Args&... args);
namespace std { template<class Context> class basic_format_args { size_t size_; // exposition only const basic_format_arg<Context>* data_; // exposition only public: basic_format_args() noexcept; template<class... Args> basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; basic_format_arg<Context> get(size_t i) const noexcept; }; }
basic_format_args() noexcept;
template<class... Args>
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
basic_format_arg<Context> get(size_t i) const noexcept;
namespace std { class format_error : public runtime_error { public: explicit format_error(const string& what_arg); explicit format_error(const char* what_arg); }; }
format_error(const string& what_arg);
format_error(const char* what_arg);