Init
This commit is contained in:
73
cppdraft/concept/assignable.md
Normal file
73
cppdraft/concept/assignable.md
Normal 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.8 Concept assignable_from [concept.assignable]") =
|
||||
is_lvalue_reference_v<LHS> &&
|
||||
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept 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.2 Concept 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.8 Concept 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.17 Moved-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.3 Requirements"));
|
||||
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*]
|
||||
152
cppdraft/concept/booleantestable.md
Normal file
152
cppdraft/concept/booleantestable.md
Normal 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.2 Boolean 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.14 Logical AND operator"), [[expr.log.or]](expr.log.or "7.6.15 Logical OR operator"), [[expr.unary.op]](expr.unary.op "7.6.2.2 Unary 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.2 Boolean testability [concept.booleantestable]") = [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept 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.2 Boolean 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.4 Argument-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.2 Boolean 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.2 Implicit 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.6 Deducing 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.2 Deducing 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.2 Boolean 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.2 Boolean 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.4 Meaning 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.2 Boolean 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.2 Boolean testability [concept.booleantestable]") = // exposition only
|
||||
[boolean-testable-impl](#concept:boolean-testable-impl "18.5.2 Boolean testability [concept.booleantestable]")<T> && requires(T&& t) {
|
||||
{ !std::forward<T>(t) } -> [boolean-testable-impl](#concept:boolean-testable-impl "18.5.2 Boolean 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.2 Boolean 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.3 Header <type_traits> synopsis")),int*, andbitset<N>::reference ([[template.bitset]](template.bitset "22.9.2 Class template bitset"))
|
||||
model [*boolean-testable*](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]")[.](#8.sentence-1)
|
||||
|
||||
â *end example*]
|
||||
71
cppdraft/concept/common.md
Normal file
71
cppdraft/concept/common.md
Normal 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.6 Concept common_with [concept.common]") =
|
||||
[same_as](concept.same#concept:same_as "18.4.2 Concept 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.5 Concept 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.5 Concept 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.2 Equality 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.6 Concept 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.6 Concept common_with [concept.common]") by specializing thecommon_type class template ([[meta.trans.other]](meta.trans.other "21.3.9.7 Other transformations"))[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
62
cppdraft/concept/commonref.md
Normal file
62
cppdraft/concept/commonref.md
Normal 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.4 Concept convertible_to [concept.convertible]")<T, C> and[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept 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.5 Concept common_reference_with [concept.commonref]") =
|
||||
[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<common_reference_t<T, U>, common_reference_t<U, T>> &&
|
||||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<T, common_reference_t<T, U>> &&
|
||||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept 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.2 Equality 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.5 Concept 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.5 Concept common_reference_with [concept.commonref]") by specializing
|
||||
the basic_common_reference class template ([[meta.trans.other]](meta.trans.other "21.3.9.7 Other transformations"))[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
44
cppdraft/concept/comparisoncommontype.md
Normal file
44
cppdraft/concept/comparisoncommontype.md
Normal 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.3 Comparison common types [concept.comparisoncommontype]") = // exposition only
|
||||
[same_as](concept.same#concept:same_as "18.4.2 Concept 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.4 Concept convertible_to [concept.convertible]")<const T&, const C&> || [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<T, const C&>;
|
||||
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const U&, const C&> || [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<U, const C&>;
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
concept [comparison-common-type-with](#concept:comparison-common-type-with "18.5.3 Comparison common types [concept.comparisoncommontype]") = // exposition only
|
||||
[comparison-common-type-with-impl](#concept:comparison-common-type-with-impl "18.5.3 Comparison 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.3 Comparison 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
|
||||
20
cppdraft/concept/constructible.md
Normal file
20
cppdraft/concept/constructible.md
Normal 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.11 Concept 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.11 Concept constructible_from [concept.constructible]") = [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<T> && [is_constructible_v](meta.type.synop#lib:is_constructible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T, Args...>;
|
||||
`
|
||||
53
cppdraft/concept/convertible.md
Normal file
53
cppdraft/concept/convertible.md
Normal 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.4 Concept 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.4 Concept 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.4 Concept 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.17 Moved-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)
|
||||
33
cppdraft/concept/copyconstructible.md
Normal file
33
cppdraft/concept/copyconstructible.md
Normal 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.14 Concept copy_constructible [concept.copyconstructible]") =
|
||||
[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<T> &&
|
||||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<T, T&> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<T&, T> &&
|
||||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<T, const T&> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const T&, T> &&
|
||||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<T, const T> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept 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.14 Concept 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.2 Equality 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)
|
||||
29
cppdraft/concept/default/init.md
Normal file
29
cppdraft/concept/default/init.md
Normal 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.12 Concept default_initializable [concept.default.init]") = [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept 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)
|
||||
25
cppdraft/concept/derived.md
Normal file
25
cppdraft/concept/derived.md
Normal 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.3 Concept 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.3 Concept 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*]
|
||||
33
cppdraft/concept/destructible.md
Normal file
33
cppdraft/concept/destructible.md
Normal 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.10 Concept 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.10 Concept destructible [concept.destructible]") = [is_nothrow_destructible_v](meta.type.synop#lib:is_nothrow_destructible_v "21.3.3 Header <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.2 Template 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*]
|
||||
94
cppdraft/concept/equalitycomparable.md
Normal file
94
cppdraft/concept/equalitycomparable.md
Normal 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.4 Concept 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.2 Boolean testability [concept.booleantestable]");
|
||||
{ t != u } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");
|
||||
{ u == t } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");
|
||||
{ u != t } -> [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean 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.4 Concept 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.4 Concept equality_comparable [concept.equalitycomparable]") = [weakly-equality-comparable-with](#concept:weakly-equality-comparable-with "18.5.4 Concept 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.4 Concept equality_comparable [concept.equalitycomparable]") only ifbool(a == b) is true when a is equal tob ([[concepts.equality]](concepts.equality "18.2 Equality 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.4 Concept equality_comparable [concept.equalitycomparable]") =
|
||||
[equality_comparable](#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<T> && [equality_comparable](#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<U> &&
|
||||
[comparison-common-type-with](concept.comparisoncommontype#concept:comparison-common-type-with "18.5.3 Comparison common types [concept.comparisoncommontype]")<T, U> &&
|
||||
[equality_comparable](#concept:equality_comparable "18.5.4 Concept 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.4 Concept 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.4 Concept 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
20
cppdraft/concept/equiv.md
Normal 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.6 Concept equivalence_relation [concept.equiv]") = [relation](concept.relation#concept:relation "18.7.5 Concept 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.5 Concept relation [concept.relation]") models [equivalence_relation](#concept:equivalence_relation "18.7.6 Concept equivalence_relation [concept.equiv]") only if
|
||||
it imposes an equivalence relation on its arguments[.](#1.sentence-1)
|
||||
35
cppdraft/concept/invocable.md
Normal file
35
cppdraft/concept/invocable.md
Normal 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.2 Concept invocable [concept.invocable]") concept specifies a relationship between a callable
|
||||
type ([[func.def]](func.def "22.10.3 Definitions")) F and a set of argument types Args... which
|
||||
can be evaluated by the library function invoke ([[func.invoke]](func.invoke "22.10.5 invoke functions"))[.](#1.sentence-1)
|
||||
|
||||
[ð](#concept:invocable)
|
||||
|
||||
`template<class F, class... Args>
|
||||
concept [invocable](#concept:invocable "18.7.2 Concept 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.2 Concept invocable [concept.invocable]"),
|
||||
since the invoke function call expression is not required to be
|
||||
equality-preserving ([[concepts.equality]](concepts.equality "18.2 Equality preservation"))[.](#2.sentence-1)
|
||||
|
||||
â *end example*]
|
||||
34
cppdraft/concept/moveconstructible.md
Normal file
34
cppdraft/concept/moveconstructible.md
Normal 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.13 Concept move_constructible [concept.moveconstructible]") = [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<T, T> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept 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.13 Concept 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.17 Moved-from state of library types")); otherwise, it is unchanged[.](#1.3.sentence-1)
|
||||
14
cppdraft/concept/predicate.md
Normal file
14
cppdraft/concept/predicate.md
Normal 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.4 Concept predicate [concept.predicate]") =
|
||||
[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F, Args...> && [boolean-testable](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]")<invoke_result_t<F, Args...>>;
|
||||
`
|
||||
47
cppdraft/concept/regularinvocable.md
Normal file
47
cppdraft/concept/regularinvocable.md
Normal 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.3 Concept regular_invocable [concept.regularinvocable]") = [invocable](concept.invocable#concept:invocable "18.7.2 Concept 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.2 Equality 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.2 Concept 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.3 Concept 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.2 Concept invocable [concept.invocable]") and [regular_invocable](#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]") is purely semantic[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
15
cppdraft/concept/relation.md
Normal file
15
cppdraft/concept/relation.md
Normal 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.5 Concept relation [concept.relation]") =
|
||||
[predicate](concept.predicate#concept:predicate "18.7.4 Concept predicate [concept.predicate]")<R, T, T> && [predicate](concept.predicate#concept:predicate "18.7.4 Concept predicate [concept.predicate]")<R, U, U> &&
|
||||
[predicate](concept.predicate#concept:predicate "18.7.4 Concept predicate [concept.predicate]")<R, T, U> && [predicate](concept.predicate#concept:predicate "18.7.4 Concept predicate [concept.predicate]")<R, U, T>;
|
||||
`
|
||||
27
cppdraft/concept/same.md
Normal file
27
cppdraft/concept/same.md
Normal 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.2 Concept same_as [concept.same]") = [is_same_v](meta.type.synop#lib:is_same_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T, U>; // exposition only
|
||||
|
||||
template<class T, class U>
|
||||
concept [same_as](#concept:same_as "18.4.2 Concept same_as [concept.same]") = [same-as-impl](#concept:same-as-impl "18.4.2 Concept same_as [concept.same]")<T, U> && [same-as-impl](#concept:same-as-impl "18.4.2 Concept 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.2 Concept same_as [concept.same]")<T, U> subsumes [same_as](#concept:same_as "18.4.2 Concept same_as [concept.same]")<U, T> and
|
||||
vice versa[.](#1.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
65
cppdraft/concept/strictweakorder.md
Normal file
65
cppdraft/concept/strictweakorder.md
Normal 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.7 Concept strict_weak_order [concept.strictweakorder]") = [relation](concept.relation#concept:relation "18.7.5 Concept 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.5 Concept relation [concept.relation]") models [strict_weak_order](#concept:strict_weak_order "18.7.7 Concept 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*]
|
||||
155
cppdraft/concept/swappable.md
Normal file
155
cppdraft/concept/swappable.md
Normal 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.5 Concept 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.5 Customization 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.4 Compound 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.3 Partial 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.4 Compound 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.13 Concept move_constructible [concept.moveconstructible]")<T> and [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept 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.1 General")),
|
||||
|
||||
* [(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.15 constant 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.9 Concept 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.9 Concept swappable [concept.swappable]") =
|
||||
[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept 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.9 Concept swappable [concept.swappable]") and [swappable_with](#concept:swappable_with "18.4.9 Concept 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.9 Concept 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.9 Concept 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)
|
||||
95
cppdraft/concept/totallyordered.md
Normal file
95
cppdraft/concept/totallyordered.md
Normal 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.5 Concept totally_ordered [concept.totallyordered]") =
|
||||
[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<T> && [partially-ordered-with](cmp.concept#concept:partially-ordered-with "17.12.4 Concept 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.5 Concept 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.5 Concept totally_ordered [concept.totallyordered]") =
|
||||
[totally_ordered](#concept:totally_ordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<T> && [totally_ordered](#concept:totally_ordered "18.5.5 Concept totally_ordered [concept.totallyordered]")<U> &&
|
||||
[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<T, U> &&
|
||||
[totally_ordered](#concept:totally_ordered "18.5.5 Concept 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.4 Concept 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.5 Concept 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)
|
||||
Reference in New Issue
Block a user