$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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