This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
[concept.assignable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.assignable)
### 18.4.8 Concept assignable_from [concept.assignable]
[🔗](#concept:assignable_from)
`template<class LHS, class RHS>
concept [assignable_from](#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]") =
is_lvalue_reference_v<LHS> &&
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<const remove_reference_t<LHS>&, const remove_reference_t<RHS>&> &&
requires(LHS lhs, RHS&& rhs) {
{ lhs = std::forward<RHS>(rhs) } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<LHS>;
};
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L528)
Let:
- [(1.1)](#1.1)
lhs be an lvalue that refers to an object lcopy such that decltype((lhs)) is LHS,
- [(1.2)](#1.2)
rhs be an expression such that decltype((rhs)) is RHS, and
- [(1.3)](#1.3)
rcopy be a distinct object that is equal to rhs[.](#1.sentence-1)
LHS and RHS model[assignable_from](#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<LHS, RHS> only if
- [(1.4)](#1.4)
addressof(lhs = rhs) == addressof(lcopy)[.](#1.4.sentence-1)
- [(1.5)](#1.5)
After evaluating lhs = rhs:
* [(1.5.1)](#1.5.1)
lhs is equal to rcopy, unless rhs is a non-const
xvalue that refers to lcopy[.](#1.5.1.sentence-1)
* [(1.5.2)](#1.5.2)
If rhs is a non-const xvalue, the resulting state of the
object to which it refers is valid but unspecified ([[lib.types.movedfrom]](lib.types.movedfrom "16.4.6.17Moved-from state of library types"))[.](#1.5.2.sentence-1)
* [(1.5.3)](#1.5.3)
Otherwise, if rhs is a glvalue, the object to which it refers is
not modified[.](#1.5.3.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L555)
[*Note [1](#note-1)*:
Assignment need not be a total function ([[structure.requirements]](structure.requirements "16.3.2.3Requirements"));
in particular, if assignment to an object x can result in a modification
of some other object y, then x = y is likely not in the domain
of =[.](#2.sentence-1)
— *end note*]

View File

@@ -0,0 +1,152 @@
[concept.booleantestable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.5 Comparison concepts [[concepts.compare]](concepts.compare#concept.booleantestable)
### 18.5.2 Boolean testability [concept.booleantestable]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L859)
The exposition-only [*boolean-testable*](#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]") concept
specifies the requirements on expressions
that are convertible to bool and
for which the logical operators ([[expr.log.and]](expr.log.and "7.6.14Logical AND operator"), [[expr.log.or]](expr.log.or "7.6.15Logical OR operator"), [[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators"))
have the conventional semantics[.](#1.sentence-1)
[🔗](#concept:boolean-testable-impl)
`template<class T>
concept [boolean-testable-impl](#concept:boolean-testable-impl "18.5.2Boolean testability[concept.booleantestable]") = [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, bool>; // exposition only
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L871)
Let e be an expression such thatdecltype((e)) is T[.](#2.sentence-1)
T models [*boolean-testable-impl*](#concept:boolean-testable-impl "18.5.2Boolean testability[concept.booleantestable]") only if
- [(2.1)](#2.1)
either remove_cvref_t<T> is not a class type, or
a search for the names operator&& and operator|| in the scope of remove_cvref_t<T> finds nothing; and
- [(2.2)](#2.2)
argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup"))
for the names operator&& and operator|| with T as the only argument type
finds no disqualifying declaration (defined below)[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L889)
A [*disqualifying parameter*](#def:parameter,disqualifying "18.5.2Boolean testability[concept.booleantestable]") is a function parameter whose declared type P
- [(3.1)](#3.1)
is not dependent on a template parameter, and
there exists an implicit conversion sequence ([[over.best.ics]](over.best.ics "12.2.4.2Implicit conversion sequences"))
from e to P; or
- [(3.2)](#3.2)
is dependent on one or more template parameters, and either
* [(3.2.1)](#3.2.1)
P contains no template parameter that
participates in template argument deduction ([[temp.deduct.type]](temp.deduct.type "13.10.3.6Deducing template arguments from a type")), or
* [(3.2.2)](#3.2.2)
template argument deduction
using the rules for deducing template arguments
in a function call ([[temp.deduct.call]](temp.deduct.call "13.10.3.2Deducing template arguments from a function call")) ande as the argument succeeds[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L912)
A [*key parameter*](#def:parameter,key "18.5.2Boolean testability[concept.booleantestable]") of a function template D is a function parameter of type cv X or reference thereto,
where X names a specialization of a class template that
has the same innermost enclosing non-inline namespace as D, andX contains at least one template parameter that
participates in template argument deduction[.](#4.sentence-1)
[*Example [1](#example-1)*:
Innamespace Z {template<class> struct C {}; template<class T>void operator&&(C<T> x, T y); template<class T>void operator||(C<type_identity_t<T>> x, T y);} the declaration of Z::operator&& contains one key parameter, C<T> x, and
the declaration of Z::operator|| contains no key parameters[.](#4.sentence-2)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L937)
A [*disqualifying declaration*](#def:declaration,disqualifying "18.5.2Boolean testability[concept.booleantestable]") is
- [(5.1)](#5.1)
a (non-template) function declaration that
contains at least one disqualifying parameter; or
- [(5.2)](#5.2)
a function template declaration that
contains at least one disqualifying parameter, where
* [(5.2.1)](#5.2.1)
at least one disqualifying parameter is a key parameter; or
* [(5.2.2)](#5.2.2)
the declaration contains no key parameters; or
* [(5.2.3)](#5.2.3)
the declaration declares a function template
to which no name is bound ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators"))[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L955)
[*Note [1](#note-1)*:
The intention is to ensure that
given two types T1 and T2 that each model [*boolean-testable-impl*](#concept:boolean-testable-impl "18.5.2Boolean testability[concept.booleantestable]"),
the && and || operators within the expressionsdeclval<T1>() && declval<T2>() anddeclval<T1>() || declval<T2>() resolve to the corresponding built-in operators[.](#6.sentence-1)
— *end note*]
[🔗](#concept:boolean-testable)
`template<class T>
concept [boolean-testable](#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]") = // exposition only
[boolean-testable-impl](#concept:boolean-testable-impl "18.5.2Boolean testability[concept.booleantestable]")<T> && requires(T&& t) {
{ !std::forward<T>(t) } -> [boolean-testable-impl](#concept:boolean-testable-impl "18.5.2Boolean testability[concept.booleantestable]");
};
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L974)
Let e be an expression such thatdecltype((e)) is T[.](#7.sentence-1)
T models [*boolean-testable*](#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]") only ifbool(e) == !bool(!e)[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L980)
[*Example [2](#example-2)*:
The typesbool,true_type ([[meta.type.synop]](meta.type.synop "21.3.3Header <type_­traits> synopsis")),int*, andbitset<N>::reference ([[template.bitset]](template.bitset "22.9.2Class template bitset"))
model [*boolean-testable*](#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]")[.](#8.sentence-1)
— *end example*]

View File

@@ -0,0 +1,71 @@
[concept.common]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.common)
### 18.4.6 Concept common_with [concept.common]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L437)
If T and U can both be explicitly converted to some third type,C, then T and U share a [*common type*](#def:common_type),C[.](#1.sentence-1)
[*Note [1](#note-1)*:
C can be the same as T or U, or can be a
different type[.](#1.sentence-2)
C is not necessarily unique[.](#1.sentence-3)
— *end note*]
[🔗](#concept:common_with)
`template<class T, class U>
concept [common_with](#concept:common_with "18.4.6Concept common_­with[concept.common]") =
[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<common_type_t<T, U>, common_type_t<U, T>> &&
requires {
static_cast<common_type_t<T, U>>(declval<T>());
static_cast<common_type_t<T, U>>(declval<U>());
} &&
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<
add_lvalue_reference_t<const T>,
add_lvalue_reference_t<const U>> &&
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<
add_lvalue_reference_t<common_type_t<T, U>>,
common_reference_t<
add_lvalue_reference_t<const T>,
add_lvalue_reference_t<const U>>>;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L465)
Let C be common_type_t<T, U>[.](#2.sentence-1)
Let t1 and t2 be
equality-preserving expressions ([[concepts.equality]](concepts.equality "18.2Equality preservation")) such thatdecltype((t1)) and decltype((t2)) are each T, and
let u1 and u2 be equality-preserving expressions such thatdecltype((u1)) and decltype((u2)) are each U[.](#2.sentence-2)
T and U model [common_with](#concept:common_with "18.4.6Concept common_­with[concept.common]")<T, U> only if
- [(2.1)](#2.1)
C(t1) equals C(t2) if and only if t1 equals t2, and
- [(2.2)](#2.2)
C(u1) equals C(u2) if and only if u1 equals u2[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L481)
[*Note [2](#note-2)*:
Users can customize the behavior of [common_with](#concept:common_with "18.4.6Concept common_­with[concept.common]") by specializing thecommon_type class template ([[meta.trans.other]](meta.trans.other "21.3.9.7Other transformations"))[.](#3.sentence-1)
— *end note*]

View File

@@ -0,0 +1,62 @@
[concept.commonref]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.commonref)
### 18.4.5 Concept common_reference_with [concept.commonref]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L390)
For two types T and U, if common_reference_t<T, U> is well-formed and denotes a type C such that both[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, C> and[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<U, C> are modeled, then T and U share a[*common reference type*](#def:common_reference_type), C[.](#1.sentence-1)
[*Note [1](#note-1)*:
C can be the same as T or U, or can be a
different type[.](#1.sentence-2)
C can be a reference type[.](#1.sentence-3)
— *end note*]
[🔗](#concept:common_reference_with)
`template<class T, class U>
concept [common_reference_with](#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]") =
[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<common_reference_t<T, U>, common_reference_t<U, T>> &&
[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, common_reference_t<T, U>> &&
[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<U, common_reference_t<T, U>>;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L412)
Let C be common_reference_t<T, U>[.](#2.sentence-1)
Let t1 and t2 be equality-preserving
expressions ([[concepts.equality]](concepts.equality "18.2Equality preservation")) such thatdecltype((t1)) and decltype((t2)) are each T, and
let u1 and u2 be equality-preserving expressions such thatdecltype((u1)) and decltype((u2)) are each U[.](#2.sentence-2)
T and U model [common_reference_with](#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<T, U> only if
- [(2.1)](#2.1)
C(t1) equals C(t2) if and only if t1 equals t2, and
- [(2.2)](#2.2)
C(u1) equals C(u2) if and only if u1 equals u2[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L428)
[*Note [2](#note-2)*:
Users can customize the behavior of [common_reference_with](#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]") by specializing
the basic_common_reference class template ([[meta.trans.other]](meta.trans.other "21.3.9.7Other transformations"))[.](#3.sentence-1)
— *end note*]

View File

@@ -0,0 +1,44 @@
[concept.comparisoncommontype]
# 18 Concepts library [[concepts]](./#concepts)
## 18.5 Comparison concepts [[concepts.compare]](concepts.compare#concept.comparisoncommontype)
### 18.5.3 Comparison common types [concept.comparisoncommontype]
[🔗](#itemdecl:1)
`template<class T, class U, class C = common_reference_t<const T&, const U&>>
concept [comparison-common-type-with-impl](#concept:comparison-common-type-with-impl "18.5.3Comparison common types[concept.comparisoncommontype]") = // exposition only
[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<common_reference_t<const T&, const U&>,
common_reference_t<const U&, const T&>> &&
requires {
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const T&, const C&> || [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, const C&>;
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const U&, const C&> || [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<U, const C&>;
};
template<class T, class U>
concept [comparison-common-type-with](#concept:comparison-common-type-with "18.5.3Comparison common types[concept.comparisoncommontype]") = // exposition only
[comparison-common-type-with-impl](#concept:comparison-common-type-with-impl "18.5.3Comparison common types[concept.comparisoncommontype]")<remove_cvref_t<T>, remove_cvref_t<U>>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1007)
Let C be common_reference_t<const T&, const U&>[.](#1.sentence-1)
Let t1 and t2 be equality-preserving expressions
that are lvalues of type remove_cvref_t<T>, and
let u1 and u2 be equality-preserving expressions
that are lvalues of type remove_cvref_t<U>[.](#1.sentence-2)
T and U model[*comparison-common-type-with*](#concept:comparison-common-type-with "18.5.3Comparison common types[concept.comparisoncommontype]")<T, U> only if
- [(1.1)](#1.1)
*CONVERT_TO_LVALUE*<C>(t1) equals*CONVERT_TO_LVALUE*<C>(t2) if and only if t1 equals t2, and
- [(1.2)](#1.2)
*CONVERT_TO_LVALUE*<C>(u1) equals*CONVERT_TO_LVALUE*<C>(u2) if and only if u1 equals u2

View File

@@ -0,0 +1,20 @@
[concept.constructible]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.constructible)
### 18.4.11 Concept constructible_from [concept.constructible]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L758)
The [constructible_from](#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]") concept constrains the initialization of a
variable of a given type with a particular set of argument types[.](#1.sentence-1)
[🔗](#concept:constructible_from)
`template<class T, class... Args>
concept [constructible_from](#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]") = [destructible](concept.destructible#concept:destructible "18.4.10Concept destructible[concept.destructible]")<T> && [is_constructible_v](meta.type.synop#lib:is_constructible_v "21.3.3Header <type_­traits> synopsis[meta.type.synop]")<T, Args...>;
`

View File

@@ -0,0 +1,53 @@
[concept.convertible]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.convertible)
### 18.4.4 Concept convertible_to [concept.convertible]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L336)
Given types From and To and
an expression E whose type and value category are the same as those of declval<From>(),[convertible_to](#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<From, To> requires E to be both implicitly and explicitly convertible to type To[.](#1.sentence-1)
The implicit and explicit conversions are required to produce equal
results[.](#1.sentence-2)
[🔗](#concept:convertible_to)
`template<class From, class To>
concept [convertible_to](#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]") =
is_convertible_v<From, To> &&
requires {
static_cast<To>(declval<From>());
};
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L355)
Let FromR be add_rvalue_reference_t<From> andtest be the invented function:To test(FromR (&f)()) {return f();} and let f be a function with no arguments and return type FromR such that f() is equality-preserving[.](#2.sentence-1)
Types From and To model [convertible_to](#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<From, To> only if:
- [(2.1)](#2.1)
To is not an object or reference-to-object type, orstatic_cast<To>(f()) is equal to test(f)[.](#2.1.sentence-1)
- [(2.2)](#2.2)
FromR is not a reference-to-object type, or
* [(2.2.1)](#2.2.1)
If FromR is an rvalue reference to a non const-qualified type, the
resulting state of the object referenced by f() after either above
expression is valid but unspecified ([[lib.types.movedfrom]](lib.types.movedfrom "16.4.6.17Moved-from state of library types"))[.](#2.2.1.sentence-1)
* [(2.2.2)](#2.2.2)
Otherwise, the object referred to by f() is not modified by either above
expression[.](#2.2.2.sentence-1)

View File

@@ -0,0 +1,33 @@
[concept.copyconstructible]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.copyconstructible)
### 18.4.14 Concept copy_constructible [concept.copyconstructible]
[🔗](#concept:copy_constructible)
`template<class T>
concept [copy_constructible](#concept:copy_constructible "18.4.14Concept copy_­constructible[concept.copyconstructible]") =
[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]")<T> &&
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<T, T&> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T&, T> &&
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<T, const T&> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const T&, T> &&
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<T, const T> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<const T, T>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L826)
If T is an object type, then let v be an lvalue of typeT or const T or an rvalue of type const T[.](#1.sentence-1)
T models [copy_constructible](#concept:copy_constructible "18.4.14Concept copy_­constructible[concept.copyconstructible]") only if
- [(1.1)](#1.1)
After the definition T u = v;,u is equal to v ([[concepts.equality]](concepts.equality "18.2Equality preservation")) andv is not modified[.](#1.1.sentence-1)
- [(1.2)](#1.2)
T(v) is equal to v and does not modify v[.](#1.2.sentence-1)

View File

@@ -0,0 +1,29 @@
[concept.default.init]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.default.init)
### 18.4.12 Concept default_initializable [concept.default.init]
[🔗](#concept:default_initializable)
`template<class T>
constexpr bool is-default-initializable = see below; // exposition only
template<class T>
concept [default_initializable](#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]") = [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<T> &&
requires { T{}; } &&
is-default-initializable<T>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L780)
For a type T, *is-default-initializable*<T> is true if and only if the variable definitionT t; is well-formed for some invented variable t;
otherwise it is false[.](#1.sentence-1)
Access checking is performed as if in a context unrelated to T[.](#1.sentence-2)
Only the validity of the immediate context of the variable initialization is considered[.](#1.sentence-3)

View File

@@ -0,0 +1,25 @@
[concept.derived]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.derived)
### 18.4.3 Concept derived_from [concept.derived]
[🔗](#concept:derived_from)
`template<class Derived, class Base>
concept [derived_from](#concept:derived_from "18.4.3Concept derived_­from[concept.derived]") =
is_base_of_v<Base, Derived> &&
is_convertible_v<const volatile Derived*, const volatile Base*>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L326)
[*Note [1](#note-1)*:
[derived_from](#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<Derived, Base> is satisfied if and only ifDerived is publicly and unambiguously derived from Base, orDerived and Base are the same class type ignoring cv-qualifiers[.](#1.sentence-1)
— *end note*]

View File

@@ -0,0 +1,33 @@
[concept.destructible]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.destructible)
### 18.4.10 Concept destructible [concept.destructible]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L737)
The [destructible](#concept:destructible "18.4.10Concept destructible[concept.destructible]") concept specifies properties of all types,
instances of which can be destroyed at the end of their lifetime, or reference
types[.](#1.sentence-1)
[🔗](#concept:destructible)
`template<class T>
concept [destructible](#concept:destructible "18.4.10Concept destructible[concept.destructible]") = [is_nothrow_destructible_v](meta.type.synop#lib:is_nothrow_destructible_v "21.3.3Header <type_­traits> synopsis[meta.type.synop]")<T>;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L748)
[*Note [1](#note-1)*:
Unlike the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements")), this
concept forbids destructors that are potentially throwing, even if a particular
invocation of the destructor does not actually throw[.](#2.sentence-1)
— *end note*]

View File

@@ -0,0 +1,94 @@
[concept.equalitycomparable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.5 Comparison concepts [[concepts.compare]](concepts.compare#concept.equalitycomparable)
### 18.5.4 Concept equality_comparable [concept.equalitycomparable]
[🔗](#concept:weakly-equality-comparable-with)
`template<class T, class U>
concept [weakly-equality-comparable-with](#concept:weakly-equality-comparable-with "18.5.4Concept equality_­comparable[concept.equalitycomparable]") = // exposition only
requires(const remove_reference_t<T>& t,
const remove_reference_t<U>& u) {
{ t == u } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]");
{ t != u } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]");
{ u == t } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]");
{ u != t } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]");
};
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1041)
Given types T and U,
let t and u be lvalues of typesconst remove_reference_t<T> andconst remove_reference_t<U> respectively[.](#1.sentence-1)
T and U model[*weakly-equality-comparable-with*](#concept:weakly-equality-comparable-with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, U> only if
- [(1.1)](#1.1)
t == u, u == t, t != u, and u != t have the same domain[.](#1.1.sentence-1)
- [(1.2)](#1.2)
bool(u == t) == bool(t == u)[.](#1.2.sentence-1)
- [(1.3)](#1.3)
bool(t != u) == !bool(t == u)[.](#1.3.sentence-1)
- [(1.4)](#1.4)
bool(u != t) == bool(t != u)[.](#1.4.sentence-1)
[🔗](#concept:equality_comparable)
`template<class T>
concept [equality_comparable](#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]") = [weakly-equality-comparable-with](#concept:weakly-equality-comparable-with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, T>;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1063)
Let a and b be objects of type T[.](#2.sentence-1)
T models [equality_comparable](#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]") only ifbool(a == b) is true when a is equal tob ([[concepts.equality]](concepts.equality "18.2Equality preservation")), and false otherwise[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1069)
[*Note [1](#note-1)*:
The requirement that the expression a == b is equality-preserving
implies that == is transitive and symmetric[.](#3.sentence-1)
— *end note*]
[🔗](#concept:equality_comparable_with)
`template<class T, class U>
concept [equality_comparable_with](#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]") =
[equality_comparable](#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T> && [equality_comparable](#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<U> &&
[comparison-common-type-with](concept.comparisoncommontype#concept:comparison-common-type-with "18.5.3Comparison common types[concept.comparisoncommontype]")<T, U> &&
[equality_comparable](#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<
common_reference_t<
const remove_reference_t<T>&,
const remove_reference_t<U>&>> &&
[weakly-equality-comparable-with](#concept:weakly-equality-comparable-with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, U>;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1089)
Given types T and U,
let t and t2 be lvalues
denoting distinct equal objects of types const remove_reference_t<T> andremove_cvref_t<T>, respectively,
let u and u2 be lvalues
denoting distinct equal objects of types const remove_reference_t<U> andremove_cvref_t<U>, respectively, and
let C be:common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>T and U model[equality_comparable_with](#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, U> only ifbool(t == u) == bool(*CONVERT_TO_LVALUE*<C>(t2) == *CONVERT_TO_LVALUE*<C>(u2))

20
cppdraft/concept/equiv.md Normal file
View File

@@ -0,0 +1,20 @@
[concept.equiv]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.equiv)
### 18.7.6 Concept equivalence_relation [concept.equiv]
[🔗](#concept:equivalence_relation)
`template<class R, class T, class U>
concept [equivalence_relation](#concept:equivalence_relation "18.7.6Concept equivalence_­relation[concept.equiv]") = [relation](concept.relation#concept:relation "18.7.5Concept relation[concept.relation]")<R, T, U>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1290)
A [relation](concept.relation#concept:relation "18.7.5Concept relation[concept.relation]") models [equivalence_relation](#concept:equivalence_relation "18.7.6Concept equivalence_­relation[concept.equiv]") only if
it imposes an equivalence relation on its arguments[.](#1.sentence-1)

View File

@@ -0,0 +1,35 @@
[concept.invocable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.invocable)
### 18.7.2 Concept invocable [concept.invocable]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1215)
The [invocable](#concept:invocable "18.7.2Concept invocable[concept.invocable]") concept specifies a relationship between a callable
type ([[func.def]](func.def "22.10.3Definitions")) F and a set of argument types Args... which
can be evaluated by the library function invoke ([[func.invoke]](func.invoke "22.10.5invoke functions"))[.](#1.sentence-1)
[🔗](#concept:invocable)
`template<class F, class... Args>
concept [invocable](#concept:invocable "18.7.2Concept invocable[concept.invocable]") = requires(F&& f, Args&&... args) {
invoke(std::forward<F>(f), std::forward<Args>(args)...); // not required to be equality-preserving
};
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1228)
[*Example [1](#example-1)*:
A function that generates random numbers can model [invocable](#concept:invocable "18.7.2Concept invocable[concept.invocable]"),
since the invoke function call expression is not required to be
equality-preserving ([[concepts.equality]](concepts.equality "18.2Equality preservation"))[.](#2.sentence-1)
— *end example*]

View File

@@ -0,0 +1,34 @@
[concept.moveconstructible]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.moveconstructible)
### 18.4.13 Concept move_constructible [concept.moveconstructible]
[🔗](#concept:move_constructible)
`template<class T>
concept [move_constructible](#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]") = [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<T, T> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, T>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L800)
If T is an object type, then let rv be an rvalue of typeT and u2 a distinct object of type T equal torv[.](#1.sentence-1)
T models [move_constructible](#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]") only if
- [(1.1)](#1.1)
After the definition T u = rv;, u is equal to u2[.](#1.1.sentence-1)
- [(1.2)](#1.2)
T(rv) is equal to u2[.](#1.2.sentence-1)
- [(1.3)](#1.3)
If T is not const, rv's resulting state is valid
but unspecified ([[lib.types.movedfrom]](lib.types.movedfrom "16.4.6.17Moved-from state of library types")); otherwise, it is unchanged[.](#1.3.sentence-1)

View File

@@ -0,0 +1,14 @@
[concept.predicate]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.predicate)
### 18.7.4 Concept predicate [concept.predicate]
[🔗](#concept:predicate)
`template<class F, class... Args>
concept [predicate](#concept:predicate "18.7.4Concept predicate[concept.predicate]") =
[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3Concept regular_­invocable[concept.regularinvocable]")<F, Args...> && [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2Boolean testability[concept.booleantestable]")<invoke_result_t<F, Args...>>;
`

View File

@@ -0,0 +1,47 @@
[concept.regularinvocable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.regularinvocable)
### 18.7.3 Concept regular_invocable [concept.regularinvocable]
[🔗](#concept:regular_invocable)
`template<class F, class... Args>
concept [regular_invocable](#concept:regular_invocable "18.7.3Concept regular_­invocable[concept.regularinvocable]") = [invocable](concept.invocable#concept:invocable "18.7.2Concept invocable[concept.invocable]")<F, Args...>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1244)
The invoke function call expression shall be
equality-preserving ([[concepts.equality]](concepts.equality "18.2Equality preservation")) and
shall not modify the function object or the arguments[.](#1.sentence-1)
[*Note [1](#note-1)*:
This requirement supersedes the annotation in the definition of[invocable](concept.invocable#concept:invocable "18.7.2Concept invocable[concept.invocable]")[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1253)
[*Example [1](#example-1)*:
A random number generator does not model [regular_invocable](#concept:regular_invocable "18.7.3Concept regular_­invocable[concept.regularinvocable]")[.](#2.sentence-1)
— *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1258)
[*Note [2](#note-2)*:
The distinction between [invocable](concept.invocable#concept:invocable "18.7.2Concept invocable[concept.invocable]") and [regular_invocable](#concept:regular_invocable "18.7.3Concept regular_­invocable[concept.regularinvocable]") is purely semantic[.](#3.sentence-1)
— *end note*]

View File

@@ -0,0 +1,15 @@
[concept.relation]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.relation)
### 18.7.5 Concept relation [concept.relation]
[🔗](#concept:relation)
`template<class R, class T, class U>
concept [relation](#concept:relation "18.7.5Concept relation[concept.relation]") =
[predicate](concept.predicate#concept:predicate "18.7.4Concept predicate[concept.predicate]")<R, T, T> && [predicate](concept.predicate#concept:predicate "18.7.4Concept predicate[concept.predicate]")<R, U, U> &&
[predicate](concept.predicate#concept:predicate "18.7.4Concept predicate[concept.predicate]")<R, T, U> && [predicate](concept.predicate#concept:predicate "18.7.4Concept predicate[concept.predicate]")<R, U, T>;
`

27
cppdraft/concept/same.md Normal file
View File

@@ -0,0 +1,27 @@
[concept.same]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.same)
### 18.4.2 Concept same_as [concept.same]
[🔗](#itemdecl:1)
`template<class T, class U>
concept [same-as-impl](#concept:same-as-impl "18.4.2Concept same_­as[concept.same]") = [is_same_v](meta.type.synop#lib:is_same_v "21.3.3Header <type_­traits> synopsis[meta.type.synop]")<T, U>; // exposition only
template<class T, class U>
concept [same_as](#concept:same_as "18.4.2Concept same_­as[concept.same]") = [same-as-impl](#concept:same-as-impl "18.4.2Concept same_­as[concept.same]")<T, U> && [same-as-impl](#concept:same-as-impl "18.4.2Concept same_­as[concept.same]")<U, T>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L309)
[*Note [1](#note-1)*:
[same_as](#concept:same_as "18.4.2Concept same_­as[concept.same]")<T, U> subsumes [same_as](#concept:same_as "18.4.2Concept same_­as[concept.same]")<U, T> and
vice versa[.](#1.sentence-1)
— *end note*]

View File

@@ -0,0 +1,65 @@
[concept.strictweakorder]
# 18 Concepts library [[concepts]](./#concepts)
## 18.7 Callable concepts [[concepts.callable]](concepts.callable#concept.strictweakorder)
### 18.7.7 Concept strict_weak_order [concept.strictweakorder]
[🔗](#concept:strict_weak_order)
`template<class R, class T, class U>
concept [strict_weak_order](#concept:strict_weak_order "18.7.7Concept strict_­weak_­order[concept.strictweakorder]") = [relation](concept.relation#concept:relation "18.7.5Concept relation[concept.relation]")<R, T, U>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1303)
A [relation](concept.relation#concept:relation "18.7.5Concept relation[concept.relation]") models [strict_weak_order](#concept:strict_weak_order "18.7.7Concept strict_­weak_­order[concept.strictweakorder]") only if
it imposes a [*strict weak ordering*](#def:strict_weak_ordering) on its arguments[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1307)
The term[*strict*](#def:strict) refers to the
requirement of an irreflexive relation (!comp(x, x) for all x),
and the term[*weak*](#def:weak) to requirements that are not as strong as
those for a total ordering,
but stronger than those for a partial
ordering[.](#2.sentence-1)
If we defineequiv(a, b) as!comp(a, b) && !comp(b, a),
then the requirements are thatcomp andequiv both be transitive relations:
- [(2.1)](#2.1)
comp(a, b) && comp(b, c) impliescomp(a, c)
- [(2.2)](#2.2)
equiv(a, b) && equiv(b, c) impliesequiv(a, c)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1338)
[*Note [1](#note-1)*:
Under these conditions, it can be shown that
- [(3.1)](#3.1)
equiv is an equivalence relation,
- [(3.2)](#3.2)
comp induces a well-defined relation on the equivalence
classes determined byequiv, and
- [(3.3)](#3.3)
the induced relation is a strict total ordering[.](#3.sentence-1)
— *end note*]

View File

@@ -0,0 +1,155 @@
[concept.swappable]
# 18 Concepts library [[concepts]](./#concepts)
## 18.4 Language-related concepts [[concepts.lang]](concepts.lang#concept.swappable)
### 18.4.9 Concept swappable [concept.swappable]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L566)
Let t1 and t2 be equality-preserving expressions that denote
distinct equal objects of type T, and let u1 and u2 similarly denote distinct equal objects of type U[.](#1.sentence-1)
[*Note [1](#note-1)*:
t1 and u1 can denote distinct objects, or the same object[.](#1.sentence-2)
— *end note*]
An operation[*exchanges the values*](#def:exchanges_the_values) denoted by t1 and u1 if and only
if the operation modifies neither t2 nor u2 and:
- [(1.1)](#1.1)
If T and U are the same type, the result of the operation
is that t1 equals u2 and u1 equals t2[.](#1.1.sentence-1)
- [(1.2)](#1.2)
If T and U are different types and [common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<decltype((t1)), decltype((u1))> is modeled,
the result of the operation is that C(t1) equals C(u2) and C(u1) equals C(t2) where C is common_reference_t<decltype((t1)), decltype((u1))>[.](#1.2.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L590)
The name ranges::swap denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#2.sentence-1)
The expressionranges::swap(E1, E2) for subexpressions E1 and E2 is expression-equivalent to an expressionS determined as follows:
- [(2.1)](#2.1)
S is (void)swap(E1, E2)[192](#footnote-192 "The name swap is used here unqualified.") if E1 or E2 has class or enumeration type ([[basic.compound]](basic.compound "6.9.4Compound types")) and that expression is valid, with
overload resolution performed in a context that includes the declarationtemplate<class T>void swap(T&, T&) = delete; and does not include a declaration of ranges::swap[.](#2.1.sentence-1)
If the function selected by overload resolution does not
exchange the values denoted by E1 and E2,
the program is ill-formed, no diagnostic required[.](#2.1.sentence-2)
[*Note [2](#note-2)*:
This precludes calling unconstrained program-defined overloads of swap[.](#2.1.sentence-3)
When the deleted overload is viable, program-defined overloads
need to be more specialized ([[temp.func.order]](temp.func.order "13.7.7.3Partial ordering of function templates")) to be selected[.](#2.1.sentence-4)
— *end note*]
- [(2.2)](#2.2)
Otherwise, if E1 and E2 are lvalues of array types ([[basic.compound]](basic.compound "6.9.4Compound types"))
with equal extent and ranges::swap(*E1, *E2) is a valid expression, S is (void)ranges::swap_ranges(E1, E2),
except that noexcept(S) is equal to noexcept(ranges::swap(*E1, *E2))[.](#2.2.sentence-1)
- [(2.3)](#2.3)
Otherwise, if E1 and E2 are lvalues of the
same type T that models [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13Concept move_­constructible[concept.moveconstructible]")<T> and [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<T&, T>, S is an expression that exchanges the denoted values[.](#2.3.sentence-1)
S is a constant expression if
* [(2.3.1)](#2.3.1)
T is a literal type ([[basic.types.general]](basic.types.general#term.literal.type "6.9.1General")),
* [(2.3.2)](#2.3.2)
both E1 = std::move(E2) and E2 = std::move(E1) are
constant subexpressions ([[defns.const.subexpr]](defns.const.subexpr "3.15constant subexpression")), and
* [(2.3.3)](#2.3.3)
the full-expressions of the initializers in the declarationsT t1(std::move(E1));
T t2(std::move(E2)); are constant subexpressions.
noexcept(S) is equal to is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>[.](#2.3.sentence-2)
- [(2.4)](#2.4)
Otherwise, ranges::swap(E1, E2) is ill-formed[.](#2.4.sentence-1)
[*Note [3](#note-3)*:
This case can result in substitution failure when ranges::swap(E1, E2) appears in the immediate context of a template instantiation[.](#2.4.sentence-2)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L660)
[*Note [4](#note-4)*:
Whenever ranges::swap(E1, E2) is a valid expression, it
exchanges the values denoted byE1 and E2 and has type void[.](#3.sentence-1)
— *end note*]
[🔗](#concept:swappable)
`template<class T>
concept [swappable](#concept:swappable "18.4.9Concept swappable[concept.swappable]") = requires(T& a, T& b) { ranges::swap(a, b); };
`
[🔗](#concept:swappable_with)
`template<class T, class U>
concept [swappable_with](#concept:swappable_with "18.4.9Concept swappable[concept.swappable]") =
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<T, U> &&
requires(T&& t, U&& u) {
ranges::swap(std::forward<T>(t), std::forward<T>(t));
ranges::swap(std::forward<U>(u), std::forward<U>(u));
ranges::swap(std::forward<T>(t), std::forward<U>(u));
ranges::swap(std::forward<U>(u), std::forward<T>(t));
};
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L684)
[*Note [5](#note-5)*:
The semantics of the [swappable](#concept:swappable "18.4.9Concept swappable[concept.swappable]") and [swappable_with](#concept:swappable_with "18.4.9Concept swappable[concept.swappable]") concepts are fully defined by the ranges::swap customization point object[.](#4.sentence-1)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L690)
[*Example [1](#example-1)*:
User code can ensure that the evaluation of swap calls
is performed in an appropriate context under the various conditions as follows:#include <cassert>#include <concepts>#include <utility>namespace ranges = std::ranges;
template<class T, std::[swappable_with](#concept:swappable_with "18.4.9Concept swappable[concept.swappable]")<T> U>void value_swap(T&& t, U&& u) { ranges::swap(std::forward<T>(t), std::forward<U>(u));}template<std::[swappable](#concept:swappable "18.4.9Concept swappable[concept.swappable]") T>void lv_swap(T& t1, T& t2) { ranges::swap(t1, t2);}namespace N {struct A { int m; }; struct Proxy { A* a;
Proxy(A& a) : a{&a} {}friend void swap(Proxy x, Proxy y) { ranges::swap(*x.a, *y.a); }};
Proxy proxy(A& a) { return Proxy{ a }; }}int main() {int i = 1, j = 2;
lv_swap(i, j);
assert(i == 2 && j == 1);
N::A a1 = { 5 }, a2 = { -5 };
value_swap(a1, proxy(a2));
assert(a1.m == -5 && a2.m == 5);}
— *end example*]
[192)](#footnote-192)[192)](#footnoteref-192)
The name swap is used
here unqualified[.](#footnote-192.sentence-1)

View File

@@ -0,0 +1,95 @@
[concept.totallyordered]
# 18 Concepts library [[concepts]](./#concepts)
## 18.5 Comparison concepts [[concepts.compare]](concepts.compare#concept.totallyordered)
### 18.5.5 Concept totally_ordered [concept.totallyordered]
[🔗](#concept:totally_ordered)
`template<class T>
concept [totally_ordered](#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]") =
[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T> && [partially-ordered-with](cmp.concept#concept:partially-ordered-with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T, T>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1117)
Given a type T, let a, b, and c be
lvalues of type const remove_reference_t<T>[.](#1.sentence-1)
T models [totally_ordered](#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]") only if
- [(1.1)](#1.1)
Exactly one of bool(a < b), bool(a > b), or bool(a == b) is true[.](#1.1.sentence-1)
- [(1.2)](#1.2)
If bool(a < b) and bool(b < c), then bool(a < c)[.](#1.2.sentence-1)
- [(1.3)](#1.3)
bool(a <= b) == !bool(b < a)[.](#1.3.sentence-1)
- [(1.4)](#1.4)
bool(a >= b) == !bool(a < b)[.](#1.4.sentence-1)
[🔗](#concept:totally_ordered_with)
`template<class T, class U>
concept [totally_ordered_with](#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]") =
[totally_ordered](#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<T> && [totally_ordered](#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<U> &&
[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, U> &&
[totally_ordered](#concept:totally_ordered "18.5.5Concept totally_­ordered[concept.totallyordered]")<
common_reference_t<
const remove_reference_t<T>&,
const remove_reference_t<U>&>> &&
[partially-ordered-with](cmp.concept#concept:partially-ordered-with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T, U>;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/concepts.tex#L1144)
Given types T and U,
let t and t2 be lvalues
denoting distinct equal objects of types const remove_reference_t<T> andremove_cvref_t<T>, respectively,
let u and u2 be lvalues
denoting distinct equal objects of types const remove_reference_t<U> andremove_cvref_t<U>, respectively, and
let C be:common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>T and U model[totally_ordered_with](#concept:totally_ordered_with "18.5.5Concept totally_­ordered[concept.totallyordered]")<T, U> only if
- [(2.1)](#2.1)
bool(t < u) == bool(*CONVERT_TO_LVALUE*<C>(t2) < *CONVERT_TO_LVALUE*<C>(u2))[.](#2.1.sentence-1)
- [(2.2)](#2.2)
bool(t > u) == bool(*CONVERT_TO_LVALUE*<C>(t2) > *CONVERT_TO_LVALUE*<C>(u2))[.](#2.2.sentence-1)
- [(2.3)](#2.3)
bool(t <= u) == bool(*CONVERT_TO_LVALUE*<C>(t2) <= *CONVERT_TO_LVALUE*<C>(u2))[.](#2.3.sentence-1)
- [(2.4)](#2.4)
bool(t >= u) == bool(*CONVERT_TO_LVALUE*<C>(t2) >= *CONVERT_TO_LVALUE*<C>(u2))[.](#2.4.sentence-1)
- [(2.5)](#2.5)
bool(u < t) == bool(*CONVERT_TO_LVALUE*<C>(u2) < *CONVERT_TO_LVALUE*<C>(t2))[.](#2.5.sentence-1)
- [(2.6)](#2.6)
bool(u > t) == bool(*CONVERT_TO_LVALUE*<C>(u2) > *CONVERT_TO_LVALUE*<C>(t2))[.](#2.6.sentence-1)
- [(2.7)](#2.7)
bool(u <= t) == bool(*CONVERT_TO_LVALUE*<C>(u2) <= *CONVERT_TO_LVALUE*<C>(t2))[.](#2.7.sentence-1)
- [(2.8)](#2.8)
bool(u >= t) == bool(*CONVERT_TO_LVALUE*<C>(u2) >= *CONVERT_TO_LVALUE*<C>(t2))[.](#2.8.sentence-1)