1. Revision History
1.1. Revision 0
Initial Release. 🥳
2. Motivation
Within the standard library, there are multiple instances of phrases such as
"If T is the same type as U, the program is ill-formed", or This function
does not participate in overload resolution unless the following contrainsts
are true, followed by something like . It
would, honestly, be easier to express these with concepts. Furthermore, the
inversion of the concept is much more common than itself when trying to constrain signatures of template types. Additionally, in
the realm of ranges, users tend to need to express that similar types are ok
in some instances, while distinct (or different, see § 3 Request for Feedback regarding
this phrase) are fairly common. In the author’s work codebase, the inversion of appears about 20 times for each time where is
used. While it is still early days regarding concepts, it would not be
surprising if other code bases had similar ratios, though most likely they are
not as extreme.
In the interest of symmetry with and , this paper
provides both and , although the wording found
below only redefines wording in terms of , and .
3. Request for Feedback
Currently, there is some ambiguity with the naming of and . When something is distinct, it typically implies that it is
set apart and completely dissimilar to something else. However, the direct
antonym of same in english is different. The author is fine with swapping
the definition of and , but will defer to
any consensus from LEWG or LWG if it is deemed necessary to swap their
definitions.
4. Wording
The following wording is based off of the text found at https://eel.is/c++draft as of 2020-07-11.
The following is to be modified (according to a value as decided by LWG) in
17.3.2 Header synopsis [version.syn], statement 2
#define __cpp_lib_concepts 20����L202002L
The following is to be added to 18.3 Header synopsis [concepts.syn]
// [concept.different], concept different_from
template < class T , class U >
see belowconcept different_from = ;
// [concept.similar], concept similar_to
template < class T , class U >
see belowconcept similar_to = ;
// [concept.distinct], concept distinct_from
template < class T , class U >
see belowconcept distinct_from = ;
The following is to be added to 18.4 Language-related concepts [concepts.lang]
18.4.� Concept [concept.different]different_from template < class T , class U >
concept different_from = not same_as < T , U > ;
18.4.� Concept [concept.similar]similar template < class T , class U >
concept similar_to = same_as < remove_cvref_t < T > , remove_cvref_t < U >> ;
18.4.� Concept [concept.distinct]distinct_from template < class T , class U >
concept distinct_from = not similar_to < T , U > ;
The following is to be modified in 20.6.3.1 Constructors [optional.ctor], statement 22
Constraints:isis_constructible_ v < T , U > true,,is_same_v < remove_ cvref_t < U > in_place_ t > isdistinct_from < U , in_place_t > falsetrue, andis_same_v < remove_ cvref_t < U > , optional > isdistinct_from < U , optional > .falsetrue
The following is to be modified in 20.6.3.3 Assignment [optional.assign], statement 14
Constraints:is_same_v < remove_cvref_t < U > , optional > isdistinct_from < U , optional > falsetrue
The following is to be modified in 20.7.3.3 Assignment [variant.assign], statement 12.1
—is_same_v < remove_cvref_t < T > , variant > isdistinct_from < T , variant > falsetrue.
The following is to be modified in 20.8.3.1 Construction and destruction [any.cons], statement 6
Constraints:is not the same type asVT any isdistinct_from < T , any > true
The following is to be modified in 20.14.5.1 Constructors and destructor [refwrap.const], statement 2
Constraints: The expression FUNis well-formed and( declval < U > ()) is_same_v < remove_cvref_t < U > , reference_wrapper > isdistinct_from < U , reference_wrapper > falsetrue
The following is to be modified from 21.2 Character traits [char.traits], statement 3
To specialize those templates to generate a string, string view, or iostream class to handle a particular character container type ([defns.character.container]), that and its related character traits classC are passed as a pair of parameters to the string, string view, or iostream template as parametersX andcharT .traits IfIfis not the same type asX :: char_type , the program is ill-formed.C isdifferent_from < X :: char_type , C > true, the program is ill-formed
The following is to be modified from 21.3.2.1 General requirements [string.require], statement 3
In every specialization, the typebasic_string < charT , traits , Allocator > shall name the same type asallocator_traits < Allocator >:: value_type . Every object of typecharT uses an object of typebasic_string < charT , traits , Allocator > to allocate and free storage for the containedAllocator objects as needed. ThecharT object used is obtained as described in [container.requirements.general]. In every specializationAllocator , the typebasic_string < charT , traits , Allocator > shall mee the character traits requirements ([char.traits]). [Note: The program is ill-formed iftraits is not the same type astraits :: char_type charT isdifferent_from < traits :: char_type , charT > true—end note]
The following is to be modified from 21.4.2 Class template [string.view.template], statement 1
In every specialization, the typebasic_string_view < charT , traits > shall mee the character traits requirements ([char.traits]). [Note: The program is ill-formed iftraits is not the same type astraits :: char_type charT isdifferent_from < traits :: char_type , charT > true—end note]
The following is to be removed from 24.5.1 Helper concepts [range.utility.helpers]
template < class T , class U >
concept not - same - as = // exposition only
! same_as < remove_cvref_t < T > , remove_cvref_t < U >> ;
The following is to be modified in 24.5.3 Sub-ranges [range.subrange]
template < class From , class To >
concept convertible - to - non - slicing = // exposition only
convertible_to < From , To > &&
! ( is_pointer_v < decay_t < From >> &&
is_pointer_v < decay_t < To >> &&
not - same - as < remove_pointer_t < decay_t < From >> , remove_pointer_t < decay_t < To >>> );
distinct_from < remove_pointer_t < decay_t < From >> , remove_pointer_t < decay_t < To >>> );
The following is to be modified in 24.5.3.1 Constructors and conversions [range.subrange.ctor]
template < not - same - as < subrange > R >
template < distinct_from < subrange > R >
requires borrowed_range < R > &&
convertible - to - non - slicing < iterator_t < R > , I > &&
convertible_ to < sentinel_t < R > , S >
constexpr subrange ( R && r ) requires ( ! StoreSize || sized_ range < R > );
template < not - same - as < subrange > PairLike >
template < distinct_from < subrange > PairLike >
requires pair - like - convertible - from < PairLike , const I & , const S &>
constexpr operator PairLike () const ;
The following is to be modified in 24.7.3.1 Class template ref_view [range.ref.view]
Inside of statement 1
template < not - same - as < ref_view > T >
template < distinct_from < ref_view > T >
requires /* see below */
constexpr ref_view ( T && t );
At the definition preceeding statement 2
template < not - same - as < ref_view > T >
template < distinct_from < ref_view > T >
requires /* see below */
constexpr ref_view ( T && t );
The following is to be modified in 29.3.2 Overview [iostream.forward.overview], statement 6
[Note: For each of the class tempaltes above, the program is ill-formed ifis not the same type astraits :: char_type charT isdifferent_from < traits :: char_type , charT > true([char.traits]) —end note]
The following is to be modified in 32.4.2.2 Constructors [thread.thread.constr], statement 3
Constraints:is not the same type asremove_cvref_t < F > thread isdistinct_from < F , thread > true
The following is to be modified in 32.4.3.1 Constructors, move, and assignment, statement 3
Constraints:is not the same type asremove_cvref_t < F > jthread isdistinct_from < F , jthread > true
The following is to be modified in 32.9.10.1 Member functions [futures.task.members], statement 2
Constraints:is not the same type asremove_cvref_t < F > packaged_task < R ( ArgTypes ...) > isdistinct_from < F , packaged_task > true
The following is to be removed from the Index of library concepts
not-same-as[range.utility.helpers]
The following is to be added to the Index of library concepts
[concept.different]
,
[concept.similar]
,
[concept.distinct]