[ create a new paste ] login | about

Link: http://codepad.org/jrgatRaT    [ raw code | fork ]

aaronla - C++, pasted on Dec 22:
#include <type_traits>

using std::tr1::is_base_of;

// --- policy metaprogramming ---

// classes marked with (derived from) chaining_tag 
// must have template member 'with'
struct chaining_tag{};

// metafunction, returns type derived from all the items listed
//  usage example:  chain<X, Y>::type
template <class T, class U, 
    bool supports_chaining = is_base_of<chaining_tag, T>::value,
    bool reverse_chaining = is_base_of<chaining_tag, U>::value>
struct chain;

template <class T, class U, bool free_>
struct chain<T, U, true, free_>{
    typedef typename T::template with<U>::type type;
};
template <class T, class U>
struct chain<T, U, false, true>{
    typedef typename U::template with<T>::type type;
};
template <class T, class U>
struct chain<T, U, false, false>{
    struct with_ : T, U {};
    typedef with_ type;
};

// --- example class using policy chaining

template <class Allocator, class ThreadingPolicy, class KitchenSinkPolicy>
struct Something
{
    typedef 
        typename chain< 
            typename chain<
                Allocator, 
                ThreadingPolicy
            >::type,
            KitchenSinkPolicy
        >::type
        all_policies;

    all_policies policies_;
};

// --- some policies to instantiate with ---

struct myalloc{ 
    void alloc(){} 
};

template <class ChainedBase = chaining_tag>
struct mythreading_ : ChainedBase { 
    template <class T> 
    struct with{ typedef mythreading_<T> type; };
    void lock(){}
};
typedef mythreading_<> mythreading;

template <class ChainedBase = chaining_tag>
struct mykitchensink_ : ChainedBase { 
    template <class T> 
    struct with{ typedef mykitchensink_<T> type; };
    void water(){}
};
typedef mykitchensink_<> mykitchensink;

// -- example code accessing the all_policies chained object

int main(){
    Something<myalloc, mythreading, mykitchensink> something;
    something.policies_.alloc();
    something.policies_.lock();
    something.policies_.water();
}


Create a new paste based on this one


Comments: