Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-25 21:07:35


BTW, this is how I 'solved' the 'has_key_type' and 'has_template_type' on Comeau
C++ (beware, this is ugly!):
--------------------------------------------------
template<class> char binding(void);

template<template<class> class>
    char (& binding(void))[2];

template<template<class, class> class>
    char (& binding(void))[3];

// etc.

typedef char small_t;
typedef char (& large_t)[256];

template<bool, class A, class B> struct select {
    typedef B type;
};

template<class A, class B> struct select<true, A, B> {
    typedef A type;
};

template<int> struct scope;

template<> struct scope<1> {
    template<template<class> class T>
    struct helper {
        typedef typename
            select<
                sizeof(binding<T>()) - 1U == 1U,
                int,
                void
>::type type;
    };
};

template<> struct scope<2> {
    template<template<class, class> class T>
    struct helper {
        typedef typename
            select<
                sizeof(binding<T>()) - 1U == 2U,
                int,
                void
>::type type;
    };
};

template<> struct scope<3> {
    template<template<class, class, class> class T>
    struct helper {
        typedef typename
            select<
                sizeof(binding<T>()) - 1U == 3U,
                int,
                void
>::type type;
    };
};

// etc.

template<class T> class has_template_type {
    private:
        #define GEN(i) \
            template<class U> static small_t check( \
                typename scope<i>::helper<U::template type>::type (*)[1] \
            );
        GEN(1)
        GEN(2)
        GEN(3)
        // etc.
        #undef GEN
        template<class U> static large_t check(...);
    public:
        static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
};

template<class T> const bool has_template_type<T>::value;

template<class T, bool = has_template_type<T>::value> class has_key_type;

template<class T> class has_key_type<T, false> {
    private:
        template<class U> static small_t check( typename U::type* );
        template<class U> static large_t check( ... );
    public:
        static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
};

template<class T> const bool has_key_type<T, false>::value;

template<class T> class has_key_type<T, true> {
    public:
        static const bool value = false;
};

template<class T> const bool has_key_type<T, true>::value;

struct X { };

struct Y {
    struct type { };
};

struct Z {
    template<class> struct type { };
};

#include <iostream>
#include <typeinfo>

template<class T> void test() {
    std::cout
        << typeid(T).name() << " : "
        << has_key_type<T>::value << ' '
        << has_template_type<T>::value << &std::endl;
    return;
}

int main() {
    test<X>();
    test<Y>();
    test<Z>();
    return 0;
}
--------------------------------------------------
This program outputs:

X : 0 0
Y : 1 0
Z : 0 1

Phew! By the way, if I remove the 'select' test from 'scope', I get errors.
This way, it causes it to fail type deduction in another way (I guess.).

Paul Mensonides


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk