// Description: Find the most refined concept modeled by a type
// Documentation: concept.txt
#ifndef PASTELSYS_MOST_REFINED_CONCEPT_H
#define PASTELSYS_MOST_REFINED_CONCEPT_H
#include "pastel/sys/concept/concept.h"
#include "pastel/sys/concept/first_modeled_concept.h"
#include "pastel/sys/concept/base_concepts.h"
namespace Pastel
{
namespace Concept_
{
template <
typename Type,
typename... ConceptSet>
struct MostRefinedConcept_F
{
private:
using ModeledConcept =
FirstModeledConcept<
Type, ConceptSet...
>;
public:
template <typename>
struct BreadthFirst;
template <typename... BaseSet>
struct BreadthFirst<Refines<BaseSet...>>
: MostRefinedConcept_F<Type, BaseSet...>
{};
using BaseSet =
BaseConcepts<ConceptSet...>;
using type =
typename std::conditional<
std::is_same<ModeledConcept, void>::value,
typename BreadthFirst<BaseSet>::type,
ModeledConcept
>::type;
};
template <typename Type>
struct MostRefinedConcept_F<Type>
{
using type = void;
};
}
//! Returns the most refined concept modeled by Type.
/*!
This is a breadth-first search over the Refines<...>
inheritance hierarchy. Sequences (i.e. arguments of
Refines<...>) are searched from first to last.
returns:
The first matching concept. If there is none,
then void.
*/
template <
typename Type,
typename Concept>
using MostRefinedConcept_F =
Concept_::MostRefinedConcept_F<Type, Concept>;
template <
typename Type,
typename Concept>
using MostRefinedConcept =
typename MostRefinedConcept_F<Type, Concept>::type;
}
#endif