lundi 29 février 2016

Check a type trait of every class in a nested mixin

I have a collection of mixins that each have a type trait defined. I want to check the value of the boolean AND of each of this trait for each of these mixins. For example, if I have a Mixin1<Mixin2<T> > and Mixin1<T> has is_nice == true while Mixin2<T> has is_nice == false, then the trait of the nested mixins should evaluate to "false".

This line:

static const bool value = is_nice_all< Outer<Inner> >::value && is_nice_all<Inner>::value;

is causing an infinite recursion (because I'm calling is_nice_all on exactly the same template argument that it was called with in the first half of the &&, but I think it shows what I'm trying to accomplish.

#include <iostream>

// A type trait to determine if a type is nice
template <typename T>
struct is_nice
{
  static const bool value = false;
};

// Base case
template <class T>
struct is_nice_all {
    static_assert(is_nice<typename T::FieldsType>::value, "Not nice!");

    static const bool value = is_nice<typename T::FieldsType>::value;
};

template <template <class> class Outer, class Inner>
struct is_nice_all<Outer<Inner> > {
    // AND the result of the niceness of the current mixin and the next mixin, recursively
    static const bool value = is_nice_all< Outer<Inner> >::value && is_nice_all<Inner>::value; // Compiler error - template instantiation depth exceeds maximum
};

// For a base case
class BaseClass
{
public:
    using FieldsType = BaseClass;
};

// For a base case
template <>
struct is_nice<BaseClass>
{
  static const bool value = true;
};

class Mixin1_Fields
{
public:
    int property1;
};

template<class MixinBase>
class Mixin1 : public MixinBase, public Mixin1_Fields
{
public:
    using FieldsType = Mixin1_Fields;
};

template <>
struct is_nice<Mixin1_Fields>
{
  static const bool value = true;
};

class Mixin2_Fields
{
public:
    int property2;
};

template<class MixinBase>
class Mixin2 : public MixinBase, public Mixin2_Fields
{
public:

    using FieldsType = Mixin2_Fields;
};

template <>
struct is_nice<Mixin2_Fields>
{
  static const bool value = true;
};

int main()
{
    std::cout << is_nice_all<Mixin1<Mixin2<BaseClass> > >::value << std::endl;
    return 0;
}

Is there a way to achieve this recursive AND operation on these types? Is there a name for this "do something to every type in a nested template type" pattern?

Aucun commentaire:

Enregistrer un commentaire