Concepts
Concepts
Identifiers should be written in CamelCase.
template<typename T, typename U>
concept ConvertibleTo = std::convertible_to<std::decay_t<T>,std::decay_t<U>>;
Requirements
Do not indent multiline requires
clauses.
template<typename T>
concept Referenceable =
requires
{
typename Reference<T>;
typename ConstReference<T>;
};
For
conjunctions
,disjunctions
andatomic constrains
follow the models below:
Do not use traits directly, alias them as concepts
template<typename T>
concept Integral = std::is_integral_v<T>;
template<typename T>
concept Floating = std::is_floating_point_v<T>;
One line disjunctions (can be also applied to conjunctions)
template<typename T>
concept Arithmetic = Integral<T> || Floating<T>;
Multiline disjunctions (can be also applied to conjunctions)
template<typename T>
concept Arithmetic =
Integral<T>
|| Floating<T>
|| requires(T t)
{
{ t+t } -> std::same_as<T>;
{ t-t } -> std::same_as<T>;
{ t*t } -> std::same_as<T>;
{ t/t } -> std::same_as<T>;
};
One level of indentation is allowed in this scenario.
Parameter packs with fold expressions
// Is U pairs of a type T?
template<typename T, typename... U>
concept IsPairsOf =
requires(U... u)
{
{ ((u.first),...) } -> std::convertible_to<std::decay_t<T>>;
{ ((u.second),...) } -> std::convertible_to<std::decay_t<T>>;
};