basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | 4f51a55ccbbcc56f52cdc519108261e7a0f68027 |
parent | 40dceb5e125e80c527dd2f3c33eac6a2e0c36feb |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Wed, 26 Mar 2025 11:14:28 +0100 |
More concepts
Diffstat:M | example/type_traits.cpp | | | ++++++++++++++++- |
M | include/based/type_traits.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
2 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/example/type_traits.cpp b/example/type_traits.cpp
@@ -1,5 +1,8 @@
#include "based/type_traits.hpp"
namespace
{
struct irregular
{
irregular() = default;
@@ -13,6 +16,11 @@ struct irregular
~irregular() = default;
};
struct no_return
{
void operator()() {}
};
template<typename T>
struct identity
{
@@ -32,13 +40,20 @@ struct mutate
};
template<typename T, typename U>
T sub(T val1, U val2) // NOLINT
T sub(T val1, U val2)
{
return val1 - val2;
}
} // namespace
int main()
{
static_assert(based::arity_v<no_return> == 0);
static_assert(based::Procedure<no_return>);
static_assert(!based::RegularProcedure<no_return>);
static_assert(!based::FunctionalProcedure<no_return>);
using id = identity<double>;
using ii = identity<irregular>;
diff --git a/include/based/type_traits.hpp b/include/based/type_traits.hpp
@@ -7,6 +7,9 @@ namespace based
{
template<typename T>
concept Integer = std::integral<T>;
template<typename T>
concept Regular = std::regular<T>;
template<typename T>
@@ -45,17 +48,17 @@ struct is_regular_tuple<Tuple<Types...>> : std::true_type
{
};
template<class>
struct is_input_tuple : std::false_type
{
};
template<class T>
inline constexpr bool is_regular_tuple_v = is_regular_tuple<T>::value;
template<class T>
concept RegularTuple = is_regular_tuple_v<T>;
template<class>
struct is_input_tuple : std::false_type
{
};
template<template<class...> class Tuple, class... Types>
requires(Input<Types> && ...)
struct is_input_tuple<Tuple<Types...>> : std::true_type
@@ -68,6 +71,23 @@ inline constexpr bool is_input_tuple_v = is_input_tuple<T>::value;
template<class T>
concept InputTuple = is_input_tuple_v<T>;
template<class>
struct is_homogenous_tuple : std::false_type
{
};
template<template<class...> class Tuple, typename Head, typename... Tail>
requires(std::same_as<Head, Tail> && ...)
struct is_homogenous_tuple<Tuple<Head, Tail...>> : std::true_type
{
};
template<class T>
inline constexpr bool is_homogenous_tuple_v = is_homogenous_tuple<T>::value;
template<class T>
concept HomogenousTuple = is_input_tuple_v<T>;
template<typename>
struct signature;
@@ -201,4 +221,48 @@ concept FunctionalProcedure = requires {
requires(InputTuple<domain_t<P>>);
};
template<typename P>
concept UnaryFunction = requires {
requires(FunctorProcedure<P>);
requires(arity_v<P> == 1);
};
template<typename P>
concept HomogeneousFunction = requires {
requires(FunctorProcedure<P>);
requires(arity_v<P> > 0);
requires(HomogenousTuple<domain_t<P>>);
};
template<typename P>
concept Predicate = requires {
requires(FunctorProcedure<P>);
requires(std::same_as<bool, codomain_t<P>>);
};
template<typename P>
concept HomogenousPredicate = requires {
requires(Predicate<P>);
requires(HomogeneousFunction<P>);
};
template<typename P>
concept UnaryPredicate = requires {
requires(Predicate<P>);
requires(UnaryFunction<P>);
};
template<typename P>
concept Operation = requires {
requires(HomogeneousFunction<P>);
requires(std::same_as<std::remove_cvref_t<codomain_t<P>>,
std::remove_cvref_t<domain_elem_t<P, 0>>>);
};
template<typename P>
concept Transformation = requires {
requires(Operation<P>);
requires(UnaryFunction<P>);
};
} // namespace based