most_refined_concept.h

Back to Concepts

pastel/sys/concept/

// 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