// Description: Checks whether a type models a concept
#ifndef PASTELSYS_MODELS_H
#define PASTELSYS_MODELS_H
#include "pastel/sys/concept/refines.h"
#include "pastel/sys/concept/models_directly.h"
#include "pastel/sys/type_traits/and.h"
#include <type_traits>
namespace Pastel
{
//! Checks whether a type models the given concepts.
template <
typename Type,
typename... ConceptSet>
struct Models;
//! Checks whether a type models base-concepts.
/*!
The direct requirements of the concept will
not be checked.
*/
template <
typename Type,
typename Concept>
struct Models_Base
{
private:
template <typename... ConceptSet>
static auto test(Refines<ConceptSet...>&&)
-> Models<Type, ConceptSet...>;
// The concept does not refine other concepts.
static std::true_type test(...);
public:
static constexpr bool value =
decltype(test(std::declval<Concept>()))::value;
};
}
namespace Pastel
{
template <
typename Type,
typename... ConceptSet>
struct Models
{
static constexpr bool value =
And<
Models_Directly<Type, ConceptSet>...,
Models_Base<Type, ConceptSet>...
>::value;
};
}
namespace Pastel
{
namespace Concept
{
template <
typename Concept_,
typename Type,
Requires<Models<Type, Concept_>> = 0
>
bool isModelOf(Type&& that);
}
}
#endif