#
The header <utility> contains some basic function and class templates that are used throughout the rest of the library.
/ all freestanding #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) noexcept(see below); / [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, class U> constexpr auto forward_like(U&& x) noexcept -> see below; 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; / [utility.underlying], to_underlying template<class T> constexpr underlying_type_t<T> to_underlying(T value) noexcept; / [utility.undefined], undefined behavior [[noreturn]] void unreachable(); void observable_checkpoint() 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)>; / [intseq.binding], structured binding support template<class T> struct tuple_size; template<size_t I, class T> struct tuple_element; template<class T, T.. Values> struct tuple_size<integer_sequence<T, Values..>; template<size_t I, class T, T.. Values> struct tuple_element<I, integer_sequence<T, Values..>; template<size_t I, class T, T.. Values> struct tuple_element<I, const integer_sequence<T, Values..>; template<size_t I, class T, T.. Values> constexpr T get(integer_sequence<T, Values..>) noexcept; / [pairs], class template pair template<class T1, class T2> struct pair; template<class T1, class T2, class U1, class U2, template<class> class TQual, template<class> class UQual> requires requires { typename pair<common_reference_t<TQual<T1>, UQual<U1>>, common_reference_t<TQual<T2>, UQual<U2>>; } struct basic_common_reference<pair<T1, T2>, pair<U1, U2>, TQual, UQual> { using type = pair<common_reference_t<TQual<T1>, UQual<U1>>, common_reference_t<TQual<T2>, UQual<U2>>; }; template<class T1, class T2, class U1, class U2> requires requires { typename pair<common_type_t<T1, U1>, common_type_t<T2, U2>>; } struct common_type<pair<T1, T2>, pair<U1, U2>> { using type = pair<common_type_t<T1, U1>, common_type_t<T2, U2>>; }; / [pairs.spec], pair specialized algorithms template<class T1, class T2, class U1, class U2> constexpr bool operator=(const pair<T1, T2>&, const pair<U1, U2>&); template<class T1, class T2, class U1, class U2> constexpr common_comparison_category_t<synth-three-way-result<T1, U1>, synth-three-way-result<T2, U2>> operator<=>(const pair<T1, T2>&, const pair<U1, U2>&); 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 void swap(const pair<T1, T2>& x, const 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 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> / 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> 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> constexpr in_place_index_t<I> in_place_index{}; / constant_arg argument tag template<auto V> struct constant_arg_t { explicit constant_arg_t() = default; }; template<auto V> constexpr constant_arg_t<V> constant_arg{}; / [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.hash], hash support template<class T> struct hash; template<> struct hash<monostate>; }

22.2.2 swap [utility.swap]

template<class T> constexpr void swap(T& a, T& b) noexcept(see below);
Constraints: is_move_constructible_v<T> is true and is_move_assignable_v<T> is true.
Preconditions: Type T meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements.
Remarks: The exception specification is equivalent to: 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>);
Preconditions: a[i] is swappable with ([swappable.requirements]) b[i] for all i in the range [0, N).
Effects: As if by swap_ranges(a, a + N, b).
template<class T, class U = T> constexpr T exchange(T& obj, U&& new_val) noexcept(see below);
Effects: Equivalent to: T old_val = std::move(obj); obj = std::forward<U>(new_val); return old_val;
Remarks: The exception specification is equivalent to: is_nothrow_move_constructible_v<T> && is_nothrow_assignable_v<T&, U>

22.2.4 Forward/move helpers [forward]

The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions.
All functions specified in this subclause are signal-safe.
template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
[Example 1: template<class T, class A1, class A2> shared_ptr<T> factory(A1&& a1, A2&& a2) { return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)); } struct A { A(int&, const double&); }; void g() { shared_ptr<A> sp1 = factory<A>(2, 1.414); / error: 2 will not bind to int& int i = 2; shared_ptr<A> sp2 = factory<A>(i, 1.414); / OK }
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an rvalue.
In the second call to factory, A1 is deduced as int&, so i is forwarded to A's constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.414 is forwarded to A's constructor as an rvalue.
— end example]
template<class T, class U> constexpr auto forward_like(U&& x) noexcept -> see below;
  • Let COPY_CONST(A, B) be const B if A is a const type, otherwise B.
  • Let OVERRIDE_REF(A, B) be remove_reference_t<B>& if A is an rvalue reference type, otherwise B&.
  • Let V be OVERRIDE_REF(T&&, COPY_CONST(remove_reference_t<T>, remove_reference_t<U>)
[Example 2: struct accessor { vector<string>* container; decltype(auto) operator[](this auto& self, size_t i) { return std::forward_like<decltype(self)>(*container)[i]); } }; void g() { vector v{"a"s, "b"s}; accessor a{&v}; string& x = a[0]; / OK, binds to lvalue reference string&& y = std::move(a)[0]; / OK, is rvalue reference string const& z = std::move(as_const(a))[1]; / OK, is const&& string& w = as_const(a)[1]; / error: will not bind to non-const } — end example]
template<class T> constexpr remove_reference_t<T>& move(T&& t) noexcept;
[Example 3: 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> sp2 = factory<A>(std::move(a)); / “a'' binds to A(A&&) }
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue.
This binds to the constructor A(const A&), which copies the value from a.
In the second call to factory, because of the call std​::​move(a), A1 is deduced as A, so a is forwarded as an rvalue.
This binds to the constructor A(A&&), which moves the value from a.
— end example]
template<class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;
Returns: std​::​move(x).

22.2.5 Function template as_const [utility.as.const]

template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.
template<class T> add_rvalue_reference_t<T> declval() noexcept; / as unevaluated operand
[Example 1: 
template<class To, class From> decltype(static_cast<To>(declval<From>() convert(From&&); declares a function template convert which only participates in overload resolution if the type From can be explicitly converted to type To.
For another example see class template common_type ([meta.trans.other]).
— end example]

22.2.7 Integer comparison functions [utility.intcmp]

template<class T, class U> constexpr bool cmp_equal(T t, U u) noexcept;
Mandates: Each of T and U is a signed or unsigned integer type ([basic.fundamental]).
Effects: Equivalent to: 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;
Effects: Equivalent to: return !cmp_equal(t, u);
template<class T, class U> constexpr bool cmp_less(T t, U u) noexcept;
Mandates: Each of T and U is a signed or unsigned integer type ([basic.fundamental]).
Effects: Equivalent to: 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;
Effects: Equivalent to: return cmp_less(u, t);
template<class T, class U> constexpr bool cmp_less_equal(T t, U u) noexcept;
Effects: Equivalent to: return !cmp_greater(t, u);
template<class T, class U> constexpr bool cmp_greater_equal(T t, U u) noexcept;
Effects: Equivalent to: return !cmp_less(t, u);
template<class R, class T> constexpr bool in_range(T t) noexcept;
Mandates: Each of T and U is a signed or unsigned integer type ([basic.fundamental]).
Effects: Equivalent to: return cmp_greater_equal(t, numeric_limits<R>::min() && cmp_less_equal(t, numeric_limits<R>::max();
[Note 1: 
These function templates cannot be used to compare byte, char, char8_t, char16_t, char32_t, wchar_t, and bool.
— end note]

22.2.8 Function template to_underlying [utility.underlying]

template<class T> constexpr underlying_type_t<T> to_underlying(T value) noexcept;
Returns: static_cast<underlying_type_t<T>>(value).

22.2.9 Undefined behavior [utility.undefined]

[[noreturn]] void unreachable();
Preconditions: false is true.
[Note 1: 
This precondition cannot be satisfied, thus the behavior of calling unreachable is undefined.
— end note]
[Example 1: int f(int x) { switch (x) { case 0: case 1: return x; default: std::unreachable(); } } int a = f(1); / OK, a has value 1 int b = f(3); / undefined behavior — end example]
void observable_checkpoint() noexcept;
Effects: Establishes an observable checkpoint ([intro.abstract]).

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant