# Standard library header <concepts>

From cppreference.com
< cpp‎ | header

This header is part of the concepts library.

### Concepts
##### Core language concepts
Same (C++20) | specifies that a type is the same as another type (concept)
DerivedFrom (C++20) | specifies that a type is derived from another type (concept)
ConvertibleTo (C++20) | specifies that a type is implicitly convertible to another type (concept)
CommonReference (C++20) | specifies that two types share a common reference type (concept)
Common (C++20) | specifies that two types share a common type (concept)
Integral (C++20) | specifies that a type is an integral type (concept)
SignedIntegral (C++20) | specifies that a type is an integral type that is signed (concept)
UnsignedIntegral (C++20) | specifies that a type is an integral type that is unsigned (concept)
Assignable (C++20) | specifies that a type is assignable from another type (concept)
Swappable SwappableWith (C++20) | specifies that a type can be swapped or that two types can be swapped with each other (concept)
Destructible (C++20) | specifies that an object of the type can be destroyed (concept)
Constructible (C++20) | specifies that a variable of the type can be constructed from or bound to a set of argument types (concept)
DefaultConstructible (C++20) | specifies that an object of a type can be default constructed (concept)
MoveConstructible (C++20) | specifies that an object of a type can be move constructed (concept)
CopyConstructible (C++20) | specifies that an object of a type can be copy constructed and move constructed (concept)
##### Comparison concepts
Boolean (C++20) | specifies that a type can be used in Boolean contexts (concept)
EqualityComparable EqualityComparableWith (C++20) | specifies that operator == is an equivalence relation (concept)
StrictTotallyOrdered StrictTotallyOrderedWith (C++20) | specifies that the comparison operators on the type yield a total order (concept)
##### Object concepts
Movable (C++20) | specifies that an object of a type can be moved and swapped (concept)
Copyable (C++20) | specifies that an object of a type can be copied, moved, and swapped (concept)
Semiregular (C++20) | specifies that an object of a type can be copied, moved, swapped, and default constructed (concept)
Regular (C++20) | specifies that a type is regular, that is, it is both `Semiregular` and `EqualityComparable` (concept)
##### Callable concepts
Invocable RegularInvocable (C++20) | specifies that a callable type can be invoked with a given set of argument types (concept)
Predicate (C++20) | specifies that a callable type is a Boolean predicate (concept)
Relation (C++20) | specifies that a callable type is a binary relation (concept)
StrictWeakOrder (C++20) | specifies that a `Relation` imposes a strict weak ordering (concept)
### Customization point objects
ranges::swap (C++20) | swaps the values of two objects (customization point object)

### Synopsis

    namespace std {

        // Core language concepts

        template <class T, class U>
        concept Same = /* see description */;

        template <class Derived, class Base>
        concept DerivedFrom = /* see description */;

        template <class From, class To>
        concept ConvertibleTo = /* see description */;

        template <class T, class U>
        concept CommonReference = /* see description */;

        template <class T, class U>
        concept Common = /* see description */;

        template <class T>
        concept Integral = /* see description */;

        template <class T>
        concept SignedIntegral = /* see description */;

        template <class T>
        concept UnsignedIntegral = /* see description */;

        template <class LHS, class RHS>
        concept Assignable = /* see description */;

        namespace ranges {
            inline namespace /* unspecified */ {
                inline constexpr /* unspecified */ swap = /* unspecified */;
            }
        }

        template <class T>
        concept Swappable = /* see description */;

        template <class T, class U>
        concept SwappableWith = /* see description */;

        template <class T>
        concept Destructible = /* see description */;

        template <class T, class... Args>
        concept Constructible = /* see description */;

        template <class T>
        concept DefaultConstructible = /* see description */;

        template <class T>
        concept MoveConstructible = /* see description */;

        template <class T>
        concept CopyConstructible = /* see description */;

        // Comparison concepts

        template <class B>
        concept Boolean = /* see description */;

        template <class T>
        concept EqualityComparable = /* see description */;
        template <class T, class U>
        concept EqualityComparableWith = /* see description */;

        template <class T>
        concept StrictTotallyOrdered = /* see description */;
        template <class T, class U>
        concept StrictTotallyOrderedWith = /* see description */;

        // Object concepts

        template <class T>
        concept Movable = /* see description */;

        template <class T>
        concept Copyable = /* see description */;

        template <class T>
        concept Semiregular = /* see description */;

        template <class T>
        concept Regular = /* see description */;

        // Callable concepts

        template <class F, class... Args>
        concept Invocable = /* see description */;

        template <class F, class... Args>
        concept RegularInvocable = /* see description */;

        template <class F, class... Args>
        concept Predicate = /* see description */;

        template <class R, class T, class U>
        concept Relation = /* see description */;

        template <class R, class T, class U>
        concept StrictWeakOrder = /* see description */;
    }

#### Concept `Same`

    template<class T, class U>
        concept __SameImpl = is_same_v<T, U>;  // exposition only

    template<class T, class U>
        concept Same = __SameImpl<T, U> && __SameImpl<U, T>;

#### Concept `DerivedFrom`

    template<class Derived, class Base>
        concept DerivedFrom =
                is_base_of_v<Base, Derived> &&
                is_convertible_v<const volatile Derived*, const volatile Base*>;

#### Concept `ConvertibleTo`

    template<class From, class To>
        concept ConvertibleTo =
            is_convertible_v<From, To> &&
            requires(From (&f)()) {
                static_cast<To>(f());
            };

#### Concept `CommonReference`

    template<class T, class U>
        concept CommonReference =
            Same<common_reference_t<T, U>, common_reference_t<U, T>> &&
            ConvertibleTo<T, common_reference_t<T, U>> &&
            ConvertibleTo<U, common_reference_t<T, U>>;

#### Concept `Common`

    template<class T, class U>
        concept Common =
            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>());
            } &&
            CommonReference<
                add_lvalue_reference_t<const T>,
                add_lvalue_reference_t<const U>> &&
            CommonReference<
                add_lvalue_reference_t<common_type_t<T, U>>,
                common_reference_t<
                    add_lvalue_reference_t<const T>,
                    add_lvalue_reference_t<const U>>>;

#### Concept `Integral`

    template<class T>
        concept Integral = is_integral_v<T>;

#### Concept `SignedIntegral`

    template<class T>
        concept SignedIntegral = Integral<T> && is_signed_v<T>;

#### Concept `UnsignedIntegral`

    template<class T>
        concept UnsignedIntegral = Integral<T> && !SignedIntegral<T>;

#### Concept `Assignable`

    template<class LHS, class RHS>
        concept Assignable =
            is_lvalue_reference_v<LHS> &&
            CommonReference<const remove_reference_t<LHS>&, const remove_reference_t<RHS>&> &&
            requires(LHS lhs, RHS&& rhs) {
                { lhs = std::forward<RHS>(rhs) } -> Same<LHS>;
            };

#### Concept `Swappable`

    template<class T>
        concept Swappable = requires(T& a, T& b) { ranges::swap(a, b); };

#### Concept `SwappableWith`

    template<class T, class U>
        concept SwappableWith =
            CommonReference<const remove_reference_t<T>&, const remove_reference_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));
            };

#### Concept `Destructible`

    template<class T>
        concept Destructible = is_nothrow_destructible_v<T>;

#### Concept `Constructible`

    template<class T, class... Args>
        concept Constructible = Destructible<T> && is_constructible_v<T, Args>;

#### Concept `DefaultConstructible`

    template<class T>
        concept DefaultConstructible = Constructible<T>;

#### Concept `MoveConstructible`

    template<class T>
        concept MoveConstructible = Constructible<T, T> && ConvertibleTo<T, T>;

#### Concept `CopyConstructible`

    template<class T>
        concept CopyConstructible =
            MoveConstructible<T> &&
            Constructible<T, T&> && ConvertibleTo<T&, T> &&
            Constructible<T, const T&> && ConvertibleTo<const T&, T> &&
            Constructible<T, const T> && ConvertibleTo<const T, T>;

#### Concept `Boolean`

    template<class B>
        concept Boolean =
            Movable<remove_cvref_t<B>> &&
            requires(const remove_reference_t<B>& b1,
                     const remove_reference_t<B>& b2, const bool a) {
                requires ConvertibleTo<const remove_reference_t<B>&, bool>;
                { !b1 } -> ConvertibleTo<bool>;
                { b1 &&  a } -> Same<bool>;
                { b1 ||  a } -> Same<bool>;
                { b1 && b2 } -> Same<bool>;
                {  a && b2 } -> Same<bool>;
                { b1 || b2 } -> Same<bool>;
                {  a || b2 } -> Same<bool>;
                { b1 == b2 } -> ConvertibleTo<bool>;
                { b1 ==  a } -> ConvertibleTo<bool>;
                {  a == b2 } -> ConvertibleTo<bool>;
                { b1 != b2 } -> ConvertibleTo<bool>;
                { b1 !=  a } -> ConvertibleTo<bool>;
                {  a != b2 } -> ConvertibleTo<bool>;
            };

#### Concept `EqualityComparable`

    template<class T, class U>
        concept __WeaklyEqualityComparableWith = // exposition only
            requires(const remove_reference_t<T>& t,
                     const remove_reference_t<U>& u) {
                { t == u } -> Boolean;
                { t != u } -> Boolean;
                { u == t } -> Boolean;
                { u != t } -> Boolean;
            };

    template<class T>
        concept EqualityComparable = __WeaklyEqualityComparableWith<T, T>;

#### Concept `EqualityComparableWith`

    template<class T, class U>
        concept EqualityComparableWith =
            EqualityComparable<T> && EqualityComparable<U> &&
            CommonReference<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
            EqualityComparable<
                common_reference_t<
                    const remove_reference_t<T>&,
                    const remove_reference_t<U>&>> &&
            __WeaklyEqualityComparableWith<T, U>;

#### Concept `StrictTotallyOrdered`

    template<class T>
        concept StrictTotallyOrdered =
            EqualityComparable<T> &&
            requires(const remove_reference_t<T>& a,
                     const remove_reference_t<T>& b) {
                { a <  b } -> Boolean;
                { a >  b } -> Boolean;
                { a <= b } -> Boolean;
                { a >= b } -> Boolean;
            };

#### Concept `StrictTotallyOrderedWith`

    template<class T, class U>
        concept StrictTotallyOrderedWith =
            StrictTotallyOrdered<T> && StrictTotallyOrdered<U> &&
            CommonReference<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
            StrictTotallyOrdered<
                common_reference_t<
                    const remove_reference_t<T>&,
                    const remove_reference_t<U>&>> &&
            EqualityComparableWith<T, U> &&
            requires(const remove_reference_t<T>& t,
                     const remove_reference_t<U>& u) {
                { t <  u } -> Boolean;
                { t >  u } -> Boolean;
                { t <= u } -> Boolean;
                { t >= u } -> Boolean;
                { u <  t } -> Boolean;
                { u >  t } -> Boolean;
                { u <= t } -> Boolean;
                { u >= t } -> Boolean;
            };

#### Concept `Movable`

    template<class T>
        concept Movable =
            is_object_v<T> && MoveConstructible<T> && Assignable<T&, T> && Swappable<T>;

#### Concept `Copyable`

    template<class T>
        concept Copyable = CopyConstructible<T> && Movable<T> && Assignable<T&, const T&>;

#### Concept `Semiregular`

    template<class T>
        concept Semiregular = Copyable<T> && DefaultConstructible<T>;

#### Concept `Regular`

    template<class T>
        concept Regular = Semiregular<T> && EqualityComparable<T>;

#### Concept `Invocable`

    template<class F, class... Args>
        concept Invocable = requires(F&& f, Args&&... args) {
            invoke(std::forward<F>(f), std::forward<Args>(args)...);
            // not required to be equality-preserving
        };

#### Concept `RegularInvocable`

    template<class F, class... Args>
        concept RegularInvocable = Invocable<F, Args...>;

#### Concept `Predicate`

    template<class F, class... Args>
        concept Predicate =
            RegularInvocable<F, Args...> && Boolean<invoke_result_t<F, Args...>>;

#### Concept `Relation`

    template<class R, class T, class U>
        concept Relation =
            Predicate<R, T, T> && Predicate<R, U, U> &&
            Predicate<R, T, U> && Predicate<R, U, T>;

#### Concept `StrictWeakOrder`

    template<class R, class T, class U>
        concept StrictWeakOrder = Relation<R, T, U>;

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/header/concepts&oldid=110503"