Init
This commit is contained in:
465
cppdraft/utility.md
Normal file
465
cppdraft/utility.md
Normal file
@@ -0,0 +1,465 @@
|
||||
[utility]
|
||||
|
||||
# 22 General utilities library [[utilities]](./#utilities)
|
||||
|
||||
## 22.2 Utility components [utility]
|
||||
|
||||
### [22.2.1](#syn) Header <utility> synopsis [[utility.syn]](utility.syn)
|
||||
|
||||
[1](#syn-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L29)
|
||||
|
||||
The header <utility> contains some basic function and class templates that are used
|
||||
throughout the rest of the library[.](#syn-1.sentence-1)
|
||||
|
||||
// all freestanding#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2 Header <initializer_list> synopsis")namespace std {// [[utility.swap]](#swap "22.2.2 swap"), swaptemplate<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 "22.2.3 exchange"), exchangetemplate<class T, class U = T>constexpr T exchange(T& obj, U&& new_val) noexcept(*see below*); // [[forward]](#forward "22.2.4 Forward/move helpers"), forward/movetemplate<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 "22.2.5 Function template as_const"), as_consttemplate<class T>constexpr add_const_t<T>& as_const(T& t) noexcept; template<class T>void as_const(const T&&) = delete; // [[declval]](#declval "22.2.6 Function template declval"), declvaltemplate<class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand// [[utility.intcmp]](#intcmp "22.2.7 Integer comparison functions"), integer comparison functionstemplate<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]](#underlying "22.2.8 Function template to_underlying"), to_underlyingtemplate<class T>constexpr underlying_type_t<T> to_underlying(T value) noexcept; // [[utility.undefined]](#undefined "22.2.9 Undefined behavior"), undefined behavior[[noreturn]] void unreachable(); void observable_checkpoint() noexcept; // [[intseq]](intseq "21.2 Compile-time integer sequences"), compile-time integer sequencestemplate<class T, T...>struct integer_sequence; template<size_t... I>using [index_sequence](#lib:index_sequence "22.2.1 Header <utility> synopsis [utility.syn]") = 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](#lib:make_index_sequence "22.2.1 Header <utility> synopsis [utility.syn]") = make_integer_sequence<size_t, N>; template<class... T>using [index_sequence_for](#lib:index_sequence_for "22.2.1 Header <utility> synopsis [utility.syn]") = make_index_sequence<sizeof...(T)>; // [[pairs]](pairs "22.3 Pairs"), class template pairtemplate<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]](pairs.spec "22.3.3 Specialized algorithms"), pair specialized algorithmstemplate<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]](pair.astuple "22.3.4 Tuple-like access to pair"), tuple-like access to pairtemplate<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 "22.3.5 Piecewise construction"), pair piecewise constructionstruct 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#header:%3ctuple%3e "22.4.2 Header <tuple> synopsis [tuple.syn]")// in-place constructionstruct 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{}; // nontype argument tagtemplate<auto V>struct nontype_t {explicit nontype_t() = default; }; template<auto V> constexpr nontype_t<V> nontype{}; // [[variant.monostate]](variant.monostate "22.6.8 Class monostate"), class monostatestruct monostate; // [[variant.monostate.relops]](variant.monostate.relops "22.6.9 monostate relational operators"), monostate relational operatorsconstexpr bool operator==(monostate, monostate) noexcept; constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // [[variant.hash]](variant.hash "22.6.12 Hash support"), hash supporttemplate<class T> struct hash; template<> struct hash<monostate>;}
|
||||
|
||||
### [22.2.2](#swap) swap [[utility.swap]](utility.swap)
|
||||
|
||||
[ð](#lib:swap)
|
||||
|
||||
`template<class T>
|
||||
constexpr void swap(T& a, T& b) noexcept(see below);
|
||||
`
|
||||
|
||||
[1](#swap-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L251)
|
||||
|
||||
*Constraints*: is_move_constructible_v<T> is true andis_move_assignable_v<T> is true[.](#swap-1.sentence-1)
|
||||
|
||||
[2](#swap-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L256)
|
||||
|
||||
*Preconditions*: TypeT meets the[*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") (Table [31](utility.arg.requirements#tab:cpp17.moveconstructible "Table 31: Cpp17MoveConstructible requirements"))
|
||||
and[*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") (Table [33](utility.arg.requirements#tab:cpp17.moveassignable "Table 33: Cpp17MoveAssignable requirements"))
|
||||
requirements[.](#swap-2.sentence-1)
|
||||
|
||||
[3](#swap-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L266)
|
||||
|
||||
*Effects*: Exchanges values stored in two locations[.](#swap-3.sentence-1)
|
||||
|
||||
[4](#swap-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L270)
|
||||
|
||||
*Remarks*: The exception specification is equivalent to:is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
|
||||
|
||||
[ð](#lib:swap_)
|
||||
|
||||
`template<class T, size_t N>
|
||||
constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
|
||||
`
|
||||
|
||||
[5](#swap-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L285)
|
||||
|
||||
*Constraints*: is_swappable_v<T> is true[.](#swap-5.sentence-1)
|
||||
|
||||
[6](#swap-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L289)
|
||||
|
||||
*Preconditions*: a[i] is swappable with ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) b[i] for all i in the range [0, N)[.](#swap-6.sentence-1)
|
||||
|
||||
[7](#swap-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L294)
|
||||
|
||||
*Effects*: As if by swap_ranges(a, a + N, b)[.](#swap-7.sentence-1)
|
||||
|
||||
### [22.2.3](#exchange) exchange [[utility.exchange]](utility.exchange)
|
||||
|
||||
[ð](#lib:exchange)
|
||||
|
||||
`template<class T, class U = T>
|
||||
constexpr T exchange(T& obj, U&& new_val) noexcept(see below);
|
||||
`
|
||||
|
||||
[1](#exchange-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L308)
|
||||
|
||||
*Effects*: Equivalent to:T old_val = std::move(obj);
|
||||
obj = std::forward<U>(new_val);return old_val;
|
||||
|
||||
[2](#exchange-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L317)
|
||||
|
||||
*Remarks*: The exception specification is equivalent to:is_nothrow_move_constructible_v<T> && is_nothrow_assignable_v<T&, U>
|
||||
|
||||
### [22.2.4](#forward) Forward/move helpers [[forward]](forward)
|
||||
|
||||
[1](#forward-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L328)
|
||||
|
||||
The library provides templated helper functions to simplify
|
||||
applying move semantics to an lvalue and to simplify the implementation
|
||||
of forwarding functions[.](#forward-1.sentence-1)
|
||||
|
||||
All functions specified in this subclause are [signal-safe](support.signal#def:evaluation,signal-safe "17.14.5 Signal handlers [support.signal]")[.](#forward-1.sentence-2)
|
||||
|
||||
[ð](#lib:forward)
|
||||
|
||||
`template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
|
||||
template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
|
||||
`
|
||||
|
||||
[2](#forward-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L345)
|
||||
|
||||
*Mandates*: For the second overload, is_lvalue_reference_v<T> is false[.](#forward-2.sentence-1)
|
||||
|
||||
[3](#forward-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L349)
|
||||
|
||||
*Returns*: static_cast<T&&>(t)[.](#forward-3.sentence-1)
|
||||
|
||||
[4](#forward-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L353)
|
||||
|
||||
[*Example [1](#forward-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[.](#forward-4.sentence-1)
|
||||
|
||||
In the second call to factory,A1 is deduced as int&, so i is forwarded
|
||||
to A's constructor as an lvalue[.](#forward-4.sentence-2)
|
||||
|
||||
In
|
||||
both cases, A2 is deduced as double, so
|
||||
1.414 is forwarded to A's constructor as an rvalue[.](#forward-4.sentence-3)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[ð](#lib:forward_like)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr auto forward_like(U&& x) noexcept -> see below;
|
||||
`
|
||||
|
||||
[5](#forward-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L389)
|
||||
|
||||
*Mandates*: T is a referenceable type ([[defns.referenceable]](defns.referenceable "3.45 referenceable type"))[.](#forward-5.sentence-1)
|
||||
|
||||
[6](#forward-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L393)
|
||||
|
||||
- [(6.1)](#forward-6.1)
|
||||
|
||||
Let *COPY_CONST*(A, B) be const B if A is a const type, otherwise B[.](#forward-6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#forward-6.2)
|
||||
|
||||
Let *OVERRIDE_REF*(A, B) be remove_reference_t<B>&& if A is an rvalue reference type, otherwise B&[.](#forward-6.2.sentence-1)
|
||||
|
||||
- [(6.3)](#forward-6.3)
|
||||
|
||||
Let V be*OVERRIDE_REF*(T&&, *COPY_CONST*(remove_reference_t<T>, remove_reference_t<U>))
|
||||
|
||||
[7](#forward-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L408)
|
||||
|
||||
*Returns*: static_cast<V>(x)[.](#forward-7.sentence-1)
|
||||
|
||||
[8](#forward-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L412)
|
||||
|
||||
*Remarks*: The return type is V[.](#forward-8.sentence-1)
|
||||
|
||||
[9](#forward-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L416)
|
||||
|
||||
[*Example [2](#forward-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*]
|
||||
|
||||
[ð](#lib:move,function)
|
||||
|
||||
`template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
|
||||
`
|
||||
|
||||
[10](#forward-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L444)
|
||||
|
||||
*Returns*: static_cast<remove_reference_t<T>&&>(t)[.](#forward-10.sentence-1)
|
||||
|
||||
[11](#forward-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L448)
|
||||
|
||||
[*Example [3](#forward-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[.](#forward-11.sentence-1)
|
||||
|
||||
This binds to the constructor A(const A&),
|
||||
which copies the value from a[.](#forward-11.sentence-2)
|
||||
|
||||
In the second call to factory, because of the callstd::move(a),A1 is deduced as A, so a is forwarded
|
||||
as an rvalue[.](#forward-11.sentence-3)
|
||||
|
||||
This binds to the constructor A(A&&),
|
||||
which moves the value from a[.](#forward-11.sentence-4)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[ð](#lib:move_if_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;
|
||||
`
|
||||
|
||||
[12](#forward-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L488)
|
||||
|
||||
*Returns*: std::move(x)[.](#forward-12.sentence-1)
|
||||
|
||||
### [22.2.5](#as.const) Function template as_const [[utility.as.const]](utility.as.const)
|
||||
|
||||
[ð](#lib:as_const)
|
||||
|
||||
`template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
|
||||
`
|
||||
|
||||
[1](#as.const-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L501)
|
||||
|
||||
*Returns*: t[.](#as.const-1.sentence-1)
|
||||
|
||||
### [22.2.6](#declval) Function template declval [[declval]](declval)
|
||||
|
||||
[1](#declval-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L508)
|
||||
|
||||
The library provides the function template declval to simplify the definition of
|
||||
expressions which occur as [unevaluated operands](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]")[.](#declval-1.sentence-1)
|
||||
|
||||
[ð](#lib:declval)
|
||||
|
||||
`template<class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
|
||||
`
|
||||
|
||||
[2](#declval-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L518)
|
||||
|
||||
*Mandates*: This function is not odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule"))[.](#declval-2.sentence-1)
|
||||
|
||||
[3](#declval-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L522)
|
||||
|
||||
*Remarks*: The template parameter T of declval may be an incomplete type[.](#declval-3.sentence-1)
|
||||
|
||||
[4](#declval-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L526)
|
||||
|
||||
[*Example [1](#declval-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[.](#declval-4.sentence-1)
|
||||
|
||||
For another example see class
|
||||
template common_type ([[meta.trans.other]](meta.trans.other "21.3.9.7 Other transformations"))[.](#declval-4.sentence-2)
|
||||
|
||||
â *end example*]
|
||||
|
||||
### [22.2.7](#intcmp) Integer comparison functions [[utility.intcmp]](utility.intcmp)
|
||||
|
||||
[ð](#lib:cmp_equal)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_equal(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[1](#intcmp-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L546)
|
||||
|
||||
*Mandates*: Both T and U are standard integer types or
|
||||
extended integer types ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#intcmp-1.sentence-1)
|
||||
|
||||
[2](#intcmp-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L551)
|
||||
|
||||
*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;elsereturn u < 0 ? false : t == UU(u);
|
||||
|
||||
[ð](#lib:cmp_not_equal)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_not_equal(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[3](#intcmp-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L573)
|
||||
|
||||
*Effects*: Equivalent to: return !cmp_equal(t, u);
|
||||
|
||||
[ð](#lib:cmp_less)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_less(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[4](#intcmp-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L585)
|
||||
|
||||
*Mandates*: Both T and U are standard integer types or
|
||||
extended integer types ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#intcmp-4.sentence-1)
|
||||
|
||||
[5](#intcmp-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L590)
|
||||
|
||||
*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;elsereturn u < 0 ? false : t < UU(u);
|
||||
|
||||
[ð](#lib:cmp_greater)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_greater(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[6](#intcmp-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L612)
|
||||
|
||||
*Effects*: Equivalent to: return cmp_less(u, t);
|
||||
|
||||
[ð](#lib:cmp_less_equal)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_less_equal(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[7](#intcmp-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L624)
|
||||
|
||||
*Effects*: Equivalent to: return !cmp_greater(t, u);
|
||||
|
||||
[ð](#lib:cmp_greater_equal)
|
||||
|
||||
`template<class T, class U>
|
||||
constexpr bool cmp_greater_equal(T t, U u) noexcept;
|
||||
`
|
||||
|
||||
[8](#intcmp-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L636)
|
||||
|
||||
*Effects*: Equivalent to: return !cmp_less(t, u);
|
||||
|
||||
[ð](#lib:in_range)
|
||||
|
||||
`template<class R, class T>
|
||||
constexpr bool in_range(T t) noexcept;
|
||||
`
|
||||
|
||||
[9](#intcmp-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L648)
|
||||
|
||||
*Mandates*: Both T and R are standard integer types or
|
||||
extended integer types ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#intcmp-9.sentence-1)
|
||||
|
||||
[10](#intcmp-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L653)
|
||||
|
||||
*Effects*: Equivalent to:return cmp_greater_equal(t, numeric_limits<R>::min()) && cmp_less_equal(t, numeric_limits<R>::max());
|
||||
|
||||
[11](#intcmp-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L662)
|
||||
|
||||
[*Note [1](#intcmp-note-1)*:
|
||||
|
||||
These function templates cannot be used to comparebyte,char,char8_t,char16_t,char32_t,wchar_t, andbool[.](#intcmp-11.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
### [22.2.8](#underlying) Function template to_underlying [[utility.underlying]](utility.underlying)
|
||||
|
||||
[ð](#lib:to_underlying)
|
||||
|
||||
`template<class T>
|
||||
constexpr underlying_type_t<T> to_underlying(T value) noexcept;
|
||||
`
|
||||
|
||||
[1](#underlying-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L683)
|
||||
|
||||
*Returns*: static_cast<underlying_type_t<T>>(value)[.](#underlying-1.sentence-1)
|
||||
|
||||
### [22.2.9](#undefined) Undefined behavior [[utility.undefined]](utility.undefined)
|
||||
|
||||
[ð](#lib:unreachable)
|
||||
|
||||
`[[noreturn]] void unreachable();
|
||||
`
|
||||
|
||||
[1](#undefined-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L696)
|
||||
|
||||
*Preconditions*: false is true[.](#undefined-1.sentence-1)
|
||||
|
||||
[*Note [1](#undefined-note-1)*:
|
||||
|
||||
This precondition cannot be satisfied, thus the behavior
|
||||
of calling unreachable is undefined[.](#undefined-1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#undefined-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L704)
|
||||
|
||||
[*Example [1](#undefined-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 1int b = f(3); // undefined behavior â *end example*]
|
||||
|
||||
[ð](#lib:observable_checkpoint)
|
||||
|
||||
`void observable_checkpoint() noexcept;
|
||||
`
|
||||
|
||||
[3](#undefined-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L728)
|
||||
|
||||
*Effects*: Establishes an observable checkpoint ([[intro.abstract]](intro.abstract "4.1.2 Abstract machine"))[.](#undefined-3.sentence-1)
|
||||
Reference in New Issue
Block a user