# Standard library header <concepts> (C++20)

From cppreference.com
< cpp‎ | header

This header is part of the concepts library.

### Concepts
##### Core language concepts
same_as (C++20) | specifies that a type is the same as another type (concept)
derived_from (C++20) | specifies that a type is derived from another type (concept)
convertible_to (C++20) | specifies that a type is implicitly convertible to another type (concept)
common_reference_with (C++20) | specifies that two types share a common reference type (concept)
common_with (C++20) | specifies that two types share a common type (concept)
integral (C++20) | specifies that a type is an integral type (concept)
signed_integral (C++20) | specifies that a type is an integral type that is signed (concept)
unsigned_integral (C++20) | specifies that a type is an integral type that is unsigned (concept)
floating_point (C++20) | specifies that a type is a floating-point type (concept)
assignable_from (C++20) | specifies that a type is assignable from another type (concept)
swappable swappable_with (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_from (C++20) | specifies that a variable of the type can be constructed from or bound to a set of argument types (concept)
default_initializable (C++20) | specifies that an object of a type can be default constructed (concept)
move_constructible (C++20) | specifies that an object of a type can be move constructed (concept)
copy_constructible (C++20) | specifies that an object of a type can be copy constructed and move constructed (concept)
##### Comparison concepts
equality_comparable equality_comparable_with (C++20) | specifies that operator == is an equivalence relation (concept)
totally_ordered totally_ordered_with (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 `equality_comparable` (concept)
##### Callable concepts
invocable regular_invocable (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)
equivalence_relation (C++20) | specifies that a `relation` imposes an equivalence relation (concept)
strict_weak_order (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 {
      // language-related concepts
      // concept same_as
      template<class T, class U>
        concept same_as = /* see description */;

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

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

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

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

      // arithmetic concepts
      template<class T>
        concept integral = /* see description */;
      template<class T>
        concept signed_integral = /* see description */;
      template<class T>
        concept unsigned_integral = /* see description */;
      template<class T>
        concept floating_point = /* see description */;

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

      // concept swappable
      namespace ranges {
        inline namespace /* unspecified */ {
          inline constexpr /* unspecified */ swap = /* unspecified */;
        }
      }
      template<class T>
        concept swappable = /* see description */;
      template<class T, class U>
        concept swappable_with = /* see description */;

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

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

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

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

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

      // comparison concepts
      // concept equality_comparable
      template<class T>
        concept equality_comparable = /* see description */;
      template<class T, class U>
        concept equality_comparable_with = /* see description */;

      // concept totally_ordered
      template<class T>
        concept totally_ordered = /* see description */;
      template<class T, class U>
        concept totally_ordered_with = /* 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
      // concept invocable
      template<class F, class... Args>
        concept invocable = /* see description */;

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

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

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

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

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

#### Concept `same_as`

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

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

#### Concept `derived_from`

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

#### Concept `convertible_to`

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

#### Concept `common_reference_with`

    template<class T, class U>
      concept common_reference_with =
        same_as<common_reference_t<T, U>, common_reference_t<U, T>> &&
        convertible_to<T, common_reference_t<T, U>> &&
        convertible_to<U, common_reference_t<T, U>>;

#### Concept `common_with`

    template<class T, class U>
      concept common_with =
        same_as<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<
          add_lvalue_reference_t<const T>,
          add_lvalue_reference_t<const U>> &&
        common_reference_with<
          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 `signed_integral`

    template<class T>
      concept signed_integral = integral<T> && is_signed_v<T>;

#### Concept `unsigned_integral`

    template<class T>
      concept unsigned_integral = integral<T> && !signed_integral<T>;

#### Concept `floating_point`

    template<class T>
      concept floating_point = is_floating_point_v<T>;

#### Concept `assignable_from`

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

#### Concept `swappable`

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

#### Concept `swappable_with`

    template<class T, class U>
      concept swappable_with =
        common_reference_with<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_from`

    template<class T, class... Args>
      concept constructible_from = destructible<T> && is_constructible_v<T, Args...>;

#### Concept `default_initializable`

    template<class T>
      inline constexpr bool __is_default_initializable =
        /* see description */;  // exposition only

    template<class T>
      concept default_initializable = constructible_from<T> &&
                                      requires{ T{}; } &&
                                      __is_default_initializable<T>;

#### Concept `move_constructible`

    template<class T>
      concept move_constructible = constructible_from<T, T> && convertible_to<T, T>;

#### Concept `copy_constructible`

    template<class T>
      concept copy_constructible =
        move_constructible<T> &&
        constructible_from<T, T&> && convertible_to<T&, T> &&
        constructible_from<T, const T&> && convertible_to<const T&, T> &&
        constructible_from<T, const T> && convertible_to<const T, T>;

#### Concept `equality_comparable`

    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-testable;
          { t != u } -> boolean-testable;
          { u == t } -> boolean-testable;
          { u != t } -> boolean-testable;
        };

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

#### Concept `equality_comparable_with`

    template<class T, class U>
      concept equality_comparable_with =
        equality_comparable<T> && equality_comparable<U> &&
        common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
        equality_comparable<
          common_reference_t<
            const remove_reference_t<T>&,
            const remove_reference_t<U>&>> &&
        __WeaklyEqualityComparableWith<T, U>;

#### Concept `totally_ordered`

    template<class T>
      concept totally_ordered =
        equality_comparable<T> &&
        requires(const remove_reference_t<T>& a,
                 const remove_reference_t<T>& b) {
          { a <  b } -> boolean-testable;
          { a >  b } -> boolean-testable;
          { a <= b } -> boolean-testable;
          { a >= b } -> boolean-testable;
        };

#### Concept `totally_ordered_with`

    template<class T, class U>
      concept totally_ordered_with =
        totally_ordered<T> && totally_ordered<U> &&
        common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> &&
        totally_ordered<
          common_reference_t<
            const remove_reference_t<T>&,
            const remove_reference_t<U>&>> &&
        equality_comparable_with<T, U> &&
        requires(const remove_reference_t<T>& t,
                 const remove_reference_t<U>& u) {
          { t <  u } -> boolean-testable;
          { t >  u } -> boolean-testable;
          { t <= u } -> boolean-testable;
          { t >= u } -> boolean-testable;
          { u <  t } -> boolean-testable;
          { u >  t } -> boolean-testable;
          { u <= t } -> boolean-testable;
          { u >= t } -> boolean-testable;
        };

#### Concept `movable`

    template<class T>
      concept movable = is_object_v<T> && move_constructible<T> &&
                        assignable_from<T&, T> && swappable<T>;

#### Concept `copyable`

    template<class T>
      concept copyable = copy_constructible<T> && movable<T> && assignable_from<T&, T&> &&
                         assignable_from<T&, const T&> && assignable_from<T&, const T>;

#### Concept `semiregular`

    template<class T>
      concept semiregular = copyable<T> && default_initializable<T>;

#### Concept `regular`

    template<class T>
      concept regular = semiregular<T> && equality_comparable<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 `regular_invocable`

    template<class F, class... Args>
      concept regular_invocable = invocable<F, Args...>;

#### Concept `predicate`

    template<class F, class... Args>
      concept predicate =
        regular_invocable<F, Args...> && boolean-testable<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 `equivalence_relation`

    template<class R, class T, class U>
      concept equivalence_relation = relation<R, T, U>;

#### Concept `strict_weak_order`

    template<class R, class T, class U>
      concept strict_weak_order = relation<R, T, U>;

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