I want to define an operator<< for all enums, to cout the value and print that it is an enum like this:
code:
enum AnyEnum{A,B,C};
AnyEnum enm
Determining class types you could use the fact that member pointers exist
template
struct issame { };
template
struct issame { typedef void type; };
template struct tovoid { typedef void type; };
template
struct isclass { static bool const value = false; };
template
struct isclass::type> {
static bool const value = true;
};
You cannot detect the difference of an union and a non-union class. At least I don't know how, and boost doesn't know either.
I think detecting enums could work by making sure T
isn't a class, function or integral type, and then trying to assign to an integral type. You could
template
struct isenum {
struct No { char x; };
struct Yes { No n1; No n2; };
struct nullsink {};
static No checkI(nullsink*); // accept null pointer constants
static Yes checkI(...);
static Yes checkE(int);
static No checkE(...);
static bool const value = (sizeof(checkI(E())) == sizeof(Yes)) &&
(sizeof(checkE(E())) == sizeof(Yes));
};
// class
template
struct isenum::type> {
static bool const value = false;
};
// reference
template
struct isenum {
static bool const value = false;
};
// function (FuntionType() will error out).
template
struct isenum::type> {
static bool const value = false;
};
// array (ArrayType() will error out)
template
struct isenum {
static bool const value = false;
};
template
struct isenum {
static bool const value = false;
};
Quick & dirty test (works on GCC/clang/comeau):
enum A { };
struct B { };
typedef int &C;
typedef void D();
typedef int E;
typedef long F;
typedef int const G;
typedef int H[1];
template
struct confirm { typedef char x[(T::value == E) ? 1 : -1]; };
int main() {
confirm< isenum, true >();
confirm< isenum, false >();
confirm< isenum, false >();
confirm< isenum, false >();
confirm< isenum, false >();
confirm< isenum, false >();
confirm< isenum, false >();
confirm< isenum, false >();
}