cpp-concepts
cpp-concepts copied to clipboard
C++ Standard concepts diagrams
C++ Standard concepts diagrams
Concept same_as
https://timsong-cpp.github.io/cppwp/n4868/concept.same
graph TD
%% same-as-impl<T, U>
AC1["is_same_v<T, U>"] --> impl1(["<i>same-as-impl</i><T, U>"])
AC2["is_same_v<U, T>"] --> impl2(["<i>same-as-impl</i><U, T>"])
%% std::same_as<T, U>
impl1 --> same_as(["<b>same_as<T, U></b>"]);
impl2 --> same_as;
Note: same_as<T, U>
subsumes same_as<U, T>
, and same_as<U, T>
subsumes same_as<T, U>
for the symmetric subsumption.
Concept derived_from
https://timsong-cpp.github.io/cppwp/n4868/concept.derived
graph TD
%% std::derived_from<Derived, Base>
AC1["is_base_of_v<Derived, Base>"] --> derived_from(["<b>derived_from<Derived, Base></b>"]);
AC2["is_convertible_v<cv Derived*, cv Base*>"] --> derived_from;
Note: cv = const volatile
Concept convertible_to
https://timsong-cpp.github.io/cppwp/n4868/concept.convertible
graph TD
%% std::convertible_to<From, To>
is_convertible_v["is_convertible_v<From, To>"] --> convertible_to(["<b>convertible_to<From, To></b>"]);
AC["requires(...) {...}"] --> convertible_to;
Concept common_reference_with
https://timsong-cpp.github.io/cppwp/n4868/concept.commonref
graph TD
%% std::common_reference_with<T, U>
same_as(["same_as<COMREF(T,U), COMREF(U,T)>"]) --> common_reference_with(["<b>common_reference_with<T, U></b>"]);
convertible_to(["convertible_to<T, COMREF(U,T)><br>convertible_to<U, COMREF(U,T)>"]) --> common_reference_with;
Concept common_with
https://timsong-cpp.github.io/cppwp/n4868/concept.common
graph TD
%% std::common_with<T, U>
same_as(["same_as<CT(T,U), CT(U,T)>"]) --> common_with(["<b>common_with<T, U></b>"]);
AC["requires {...}"] --> common_with;
common_reference_with(["common_reference_with<CLREF(T), CLREF(U)><br>common_reference_with<CLREF(CT(T,U)), COMREF(CLREF(T),CLREF(U))>"]) --> common_with;
Arithmetic concepts
https://timsong-cpp.github.io/cppwp/n4868/concepts.arithmetic
graph TD
%% std::integral<T>
integral_v["integral_v<T>"] --> integral(["<b>integral<T></b>"]);
%% std::signed_integral<T>
integral --> signed_integral(["<b>signed_integral<T></b>"]);
is_signed_v["is_signed_v<T>"] --> signed_integral;
%% std::unsigned_integral<T>
not_signed_v["not is_signed_v<T>"] --> unsigned_integral(["<b>unsigned_integral<T></b>"]);
integral --> unsigned_integral;
%% std::floating_point<T>
floating_point_v["floating_point_v<T>"] --> floating_point(["<b>floating_point<T></b>"]);
Concept assignable_from
https://timsong-cpp.github.io/cppwp/n4868/concept.assignable
graph TD
%% std::assignable_from<LHS, RHS>
AC1["is_lvalue_reference_v<LHS>"] --> assignable_from(["<b>assignable_from<LHS, RHS></b>"]);
common_reference_with(["common_reference_with<CREF(LHS), CREF(RHS)>"]) --> assignable_from;
AC2["requires(LHS, RHS&&) {...}"] --> assignable_from;
Concept swappable
https://timsong-cpp.github.io/cppwp/n4868/concept.swappable
graph TD
%% std::swappable<T>
AC1["requires(T&, T&) {...}"] --> swappable(["<b>swappable<T></b>"]);
%% std::swappable_with<T, U>
common_reference_with(["common_reference_with<T, U>"]) --> swappable_with(["<b>swappable_with<T, U></b>"]);
AC2["requires(T&&, T&&) {...}"] --> swappable_with;
Concept destructible
https://timsong-cpp.github.io/cppwp/n4868/concept.destructible
graph TD
%% std::destructible<T>
is_nothrow_destructible_v["is_nothrow_destructible_v<T>"] --> destructible(["<b>destructible<T></b>"]);
Concept constructible_from
https://timsong-cpp.github.io/cppwp/n4868/concept.constructible
graph TD
%% std::constructible_from<T, Args...>
destructible(["destructible<T>"]) --> constructible_from(["<b>constructible_from<T, Args...></b>"]);
is_constructible_v["is_constructible_v<T, Args...>"] --> constructible_from;
Concept default_initializable
https://timsong-cpp.github.io/cppwp/n4868/concept.default.init
graph TD
%% std::default_initializable<T>
constructible_from(["constructible_from<T>"]) --> default_initializable(["<b>default_initializable<T></b>"]);
AC1["requires {...}"] --> default_initializable;
AC2["<i>is-default-initializable</i><T>"] --> default_initializable;
Concept move_constructible
https://timsong-cpp.github.io/cppwp/n4868/concept.moveconstructible
graph TD
%% std::move_constructible<T>
constructible_from(["constructible_from<T, T>"]) --> move_constructible(["<b>move_constructible<T></b>"]);
convertible_to(["convertible_to<T, T>"]) --> move_constructible;
Concept copy_constructible
https://timsong-cpp.github.io/cppwp/n4868/concept.copyconstructible
graph TD
%% std::copy_constructible<T>
move_constructible(["move_constructible<T>"]) --> copy_constructible(["<b>copy_constructible<T></b>"]);
constructible_from(["constructible_from<T, T&><br>constructible_from<T, const T&><br>constructible_from<T, const T>"]) --> copy_constructible;
convertible_to(["convertible_to<T&, T><br>convertible_to<const T&, T><br>convertible_to<const T, T>"]) --> copy_constructible;
Boolean testability
https://timsong-cpp.github.io/cppwp/n4868/concept.booleantestable
graph TD
%% boolean-testable<T>
convertible_to(["convertible_to<T, bool>"]) --> impl(["<i>boolean-testable-impl</i><T>"]);
impl --> boolean_testable(["<b><i>boolean-testable</i><T></b>"]);
AC["requires(T&&) {...}"] --> boolean_testable;
Concept equality_comparable
https://timsong-cpp.github.io/cppwp/n4868/concept.equalitycomparable
graph TD
%% weakly-equality-comparable-with<T, T>
AC["requires(CREF(T), CREF(T)) {...}"] --> weakly-equality-comparable-with(["<i>weakly-equality-comparable-with</i><T, T>"]);
%% std::equality_comparable<T>
weakly-equality-comparable-with --> equality_comparable(["<b>equality_comparable<T></b>"]);
graph TD
%% weakly-equality-comparable-with<T, U>
AC["requires(CREF(T), CREF(U)) {...}"] --> weakly-equality-comparable-with(["<i>weakly-equality-comparable-with</i><T, U>"]);
%% std::equality_comparable_with<T, U>
equality_comparable(["equality_comparable<T><br>equality_comparable<U><br>equality_comparable<COMREF(CREF(T), CREF(U))>"]) --> equality_comparable_with(["<b>equality_comparable_with<T, U></b>"]);
common_reference_with(["common_reference_with<CREF(T), CREF(U)>"]) --> equality_comparable_with;
weakly-equality-comparable-with --> equality_comparable_with;
Concept totally_ordered
https://timsong-cpp.github.io/cppwp/n4868/concept.totallyordered
graph TD
%% partially-ordered-with<T, T>
AC["requires(CREF(T), CREF(T)) {...}"] --> partially-ordered-with(["<i>partially-ordered-with</i><T, T>"]);
%% std::totally_ordered<T>
equality_comparable(["equality_comparable<T>"]) --> totally_ordered(["<b>totally_ordered<T></b>"]);
partially-ordered-with --> totally_ordered;
graph TD
%% partially-ordered-with<T, U>
AC["requires(CREF(T), CREF(U)) {...}"] --> partially-ordered-with(["<i>partially-ordered-with</i><T, U>"]);
%% std::totally_ordered_with<T, U>
totally_ordered(["totally_ordered<T><br>totally_ordered<U><br>totally_ordered<COMREF(CREF(T), CREF(U))>"]) --> totally_ordered_with(["<b>totally_ordered_with<T, U></b>"]);
equality_comparable_with(["equality_comparable_with<T, U>"]) --> totally_ordered_with;
partially-ordered-with --> totally_ordered_with;
Object concepts
https://timsong-cpp.github.io/cppwp/n4868/concepts.object
graph TD
%% std::movable<T>
is_object_v["is_object_v<T>"] --> movable(["<b>movable<T></b>"]);
move_constructible(["move_constructible<T>"]) --> movable;
assignable_from1(["assignable_from<T&, T>"]) --> movable;
swappable(["swappable<T>"]) --> movable;
%% std::copyable<T>
movable --> copyable(["<b>copyable<T></b>"]);
copy_constructible(["copy_constructible<T>"]) --> copyable;
assignable_from2(["assignable_from<T&, T&><br>assignable_from<T&, const T&><br>assignable_from<T&, const T>"]) --> copyable;
%% std::semiregular<T>
copyable --> semiregular(["<b>semiregular<T></b>"]);
default_initializable(["default_initializable<T>"]) --> semiregular;
%% std::regular<T>
semiregular --> regular(["<b>regular<T></b>"]);
equality_comparable(["equality_comparable<T>"]) --> regular;
Concept invocable
https://timsong-cpp.github.io/cppwp/n4868/concept.invocable
graph TD
%% std::invocable<F, Args...>
AC["requires(F&&, Args&&...) {...}"] --> invocable(["<b>invocable<F, Args...></b>"]);
Concept regular_invocable
https://timsong-cpp.github.io/cppwp/n4868/concept.regularinvocable
graph TD
%% std::regular_invocable<F, Args...>
invocable(["invocable<F, Args...>"]) --> regular_invocable(["<b>regular_invocable<F, Args...></b>"]);
Note: regular_invocable
semantically imposes an equality-preserving for std::invoke
expression.
Concept predicate
https://timsong-cpp.github.io/cppwp/n4868/concept.predicate
graph TD
%% std::predicate<F, Args...>
regular_invocable(["regular_invocable<F, Args...>"]) --> predicate(["<b>predicate<F, Args...></b>"]);
boolean-testable(["<i>boolean-testable</i><invoke_result_t<F, Args...>>"]) --> predicate;
Concept relation
https://timsong-cpp.github.io/cppwp/n4868/concept.relation
graph TD
%% std::relation<R, T, U>
predicate1(["predicate<R, T, T>"]) --> relation(["<b>relation<R, T, U></b>"]);
predicate2(["predicate<R, U, U>"]) --> relation;
predicate3(["predicate<R, T, U>"]) --> relation;
predicate4(["predicate<R, U, T>"]) --> relation;
Concept equivalence_relation
https://timsong-cpp.github.io/cppwp/n4868/concept.equiv
graph TD
%% std::equivalence_relation<R, T, U>
predicate(["predicate<R, T, U>"]) --> equivalence_relation(["<b>equivalence_relation<R, T, U></b>"]);
Note: equivalence_relation
semantically imposes an equivalence relation.
Concept strict_weak_order
https://timsong-cpp.github.io/cppwp/n4868/concept.strictweakorder
graph TD
%% std::strict_weak_order<R, T, U>
predicate(["predicate<R, T, U>"]) --> strict_weak_order(["<b>strict_weak_order<R, T, U></b>"]);
Note: strict_weak_order
semantically imposes a strict weak ordering.
Concept three_way_comparable
(<compare>
)
https://timsong-cpp.github.io/cppwp/n4868/cmp.concept
graph TD
%% partially-ordered-with<T, T>
AC1["requires(CREF(T), CREF(T)) {...}"] --> partially-ordered-with(["<i>partially-ordered-with</i><T, T>"]);
%% weakly-equality-comparable-with<T, T>
AC2["requires(CREF(T), CREF(T)) {...}"] --> weakly-equality-comparable-with(["<i>weakly-equality-comparable-with</i><T, T>"]);
%% std::three_way_comparable<T, Cat>
weakly-equality-comparable-with --> three_way_comparable(["<b>three_way_comparable<T, Cat></b>"])
partially-ordered-with --> three_way_comparable
AC3["requires(CREF(T), CREF(T)) {...}"] --> three_way_comparable
graph TD
%% partially-ordered-with<T, U>
AC1["requires(CREF(T), CREF(U)) {...}"] --> partially-ordered-with(["<i>partially-ordered-with</i><T, U>"]);
%% weakly-equality-comparable-with<T, U>
AC2["requires(CREF(T), CREF(U)) {...}"] --> weakly-equality-comparable-with(["<i>weakly-equality-comparable-with</i><T, U>"]);
%% std::three_way_comparable_with<T, U, Cat>
three_way_comparable(["three_way_comparable<T, Cat><br>three_way_comparable<U, Cat><br>three_way_comparable<COMREF(CREF(T), CREF(U)), Cat>"]) --> three_way_comparable_with(["<b>three_way_comparable_with<T, U, Cat></b>"])
common_reference_with(["common_reference_with<CREF(T), CREF(U)>"]) --> three_way_comparable_with
weakly-equality-comparable-with --> three_way_comparable_with
partially-ordered-with --> three_way_comparable_with
AC3["requires(CREF(T), CREF(U)) {...}"] --> three_way_comparable_with