00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef METALIC_IS_A_HH
00029 # define METALIC_IS_A_HH
00030
00031 # include <mlc/type.hh>
00032 # include <mlc/bool.hh>
00033
00034
00035 # define is_a__check_result_ \
00036 sizeof(helper<T ,U >::check( (T *) helper<T,U >::makeT() )) \
00037 == sizeof(mlc::internal::yes_)
00038
00039
00040 namespace mlc
00041 {
00042
00043 namespace internal
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template <class T> struct wrap : public T {};
00055
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065 namespace form
00066 {
00067 enum {
00068 class_ = 1,
00069 template_l_class_g_class_ = 2,
00070 template_l_class_class_g_class_ = 3
00071
00072
00073 };
00074
00075 template<unsigned id>
00076 struct desc
00077 { char dummy[id]; };
00078
00079 template<class T>
00080 static desc< class_ > get();
00081
00082 template<template<class> class T>
00083 static desc< template_l_class_g_class_ > get();
00084
00085 template<template<class,class> class T>
00086 static desc< template_l_class_class_g_class_ > get();
00087
00088
00089
00090
00091
00092 }
00093
00094 namespace internal
00095 {
00096
00097 typedef char yes_;
00098 struct no_ { char dummy[2]; };
00099
00100
00101
00102
00103
00104 template<unsigned id>
00105 struct is_a_;
00106
00107
00108
00109
00110 template<>
00111 struct is_a_< form::class_ >
00112 {
00113 typedef is_a_< form::class_ > self;
00114
00115 template<class T, class U>
00116 struct helper
00117 {
00118 static yes_ check(U*);
00119 static no_ check(...);
00120 static T* makeT();
00121 };
00122
00123 template<class T, class U>
00124 struct check
00125 : public mlc::returns_bool_<( is_a__check_result_ )>
00126 {
00127 };
00128 };
00129
00130
00131
00132 template<>
00133 struct is_a_< form::template_l_class_g_class_ >
00134 {
00135 typedef is_a_< form::template_l_class_g_class_ > self;
00136
00137 template<class T, template<class> class U>
00138 struct helper
00139 {
00140 template<class V>
00141 static yes_ check(U<V>*);
00142 static no_ check(...);
00143 static T* makeT();
00144 };
00145
00146 template<class T, template<class> class U>
00147 struct check
00148 : public mlc::returns_bool_<( is_a__check_result_ )>
00149 {
00150 };
00151 };
00152
00153
00154
00155 template<>
00156 struct is_a_< form::template_l_class_class_g_class_ >
00157 {
00158 typedef is_a_< form::template_l_class_class_g_class_ > self;
00159
00160 template<class T, template<class,class> class U>
00161 struct helper
00162 {
00163 template<class V, class W>
00164 static yes_ check(U<V,W>*);
00165 static no_ check(...);
00166 static T* makeT();
00167 };
00168
00169 template<class T, template<class,class> class U>
00170 struct check
00171 : public mlc::returns_bool_<( is_a__check_result_ )>
00172 {};
00173 };
00174
00175 }
00176
00177 }
00178
00179
00180 # define is_a__2nd_is_meta(T,U) mlc::internal::is_a_< id_of_typeform(U) >::check<T, U >
00181
00182
00183
00184 # define id_of_typeform(T) sizeof(mlc::form::get<T >())
00185
00186 template <class T>
00187 struct id_ { typedef T ret; };
00188
00189
00190 # define mlc_is_a(T, U) mlc::internal::wrap<typename mlc::internal::is_a_< id_of_typeform(U) >::check<T, U > >
00191 # define mlc_is_a_(T, U) mlc::internal::wrap<mlc::internal::is_a_< id_of_typeform(U) >::check<T, U > >
00192
00193 #endif // ndef METALIC_IS_A_HH