Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type decision based on existence of nested typedef

I need to define a template struct such that:

element<T>::type

is of type:

T::element_type 

if T contains a (public) typedef named element_type, otherwise (if it does not contain such typedef)

element<T>::type

is of type

T::value_type 

if T is mutable and of type

const T::value_type

if T is constant.

I am really struggling with this, any suggestion is very appreciated! :)

Thank you very much for your help in advance!

like image 487
StephQ Avatar asked Oct 20 '10 18:10

StephQ


1 Answers

Maybe something like:

template <typename T>
struct has_element_type
{
    typedef char yes[1];
    typedef char no[2];

    template <typename C>
    static yes& test(typename C::element_type*);

    template <typename>
    static no& test(...);

    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

template <typename T>
struct is_const
{
    static const bool value = false;
};


template <typename T>
struct is_const<const T>
{
    static const bool value = true;
};

template <typename, bool> // true -> const
struct value_type_switch; 

template <typename T>
struct value_type_switch<T, true>
{
    typedef const typename T::value_type type;
};

template <typename T>
struct value_type_switch<T, false>
{
    typedef typename T::value_type type;
};

template <typename, bool> // true -> has element_type
struct element_type_switch;

template <typename T>
struct element_type_switch<T, true>
{
    typedef typename T::element_type type;
};


template <typename T>
struct element_type_switch<T, false>
{
    typedef typename value_type_switch<T, is_const<T>::value>::type type;
};

template <typename T>
struct element
{
    typedef typename element_type_switch<T,
                                    has_element_type<T>::value>::type type;
};

This should of course be split up and organized.

like image 54
GManNickG Avatar answered Sep 29 '22 06:09

GManNickG