00001
00002 #ifndef INSTIGATE_GENERIC_BASE
00003 #define INSTIGATE_GENERIC_BASE
00004
00027
00028
00029
00030
00031
00032
00033
00034
00040 namespace instigate {
00041 namespace generic {
00042 template <int> class require;
00043 template <> class require<1>;
00044 template <typename T, typename U> class conversion;
00045 template <typename T> class conversion<T, T>;
00046 template <typename T> struct type_to_type;
00047 template <int t> struct int_to_type;
00048 }
00049 }
00050
00057 #define CHECK(R) {R();}
00058
00064 #define CHECK_CONVERTIBILITY(T, U) {\
00065 instigate::generic::require<instigate::\
00066 generic::conversion<T, U>::exists>();}
00067
00071 #define CHECK_SAME_TYPE(T, U) {\
00072 instigate::generic::require<instigate::\
00073 generic::conversion<T, U>::same_type>();}
00074
00081 template <>
00082 class instigate::generic::require<1>
00083 {};
00084
00102 template <typename T, typename U>
00103 class instigate::generic::conversion
00104 {
00105 private:
00106 typedef char small;
00107 class big { char a[2]; };
00108 static T makeT();
00109 static small test(U);
00110 static big test(...);
00111 public:
00113 static const bool exists = (sizeof(small) == sizeof(test(makeT())));
00114 static const bool same_type = false;
00115 static const bool super_sub_class =
00116 conversion<const U*, const T*>::exists &&
00117 !conversion<const T*, const void*>::same_type;
00118 };
00119
00127 template <typename T>
00128 class instigate::generic::conversion<T, T>
00129 {
00130 public:
00132 static const bool exists = true;
00133 static const bool same_type = true;
00134 static const bool super_sub_class = false;
00135 };
00136
00165 template <int t>
00166 struct instigate::generic::int_to_type
00167 {
00168 enum { value = t };
00169 };
00170
00199 template <typename T>
00200 struct instigate::generic::type_to_type
00201 {
00203 typedef T original_type;
00204 };
00205
00209 template <typename U, typename F>
00210 static void require_same_type(U v1, F v2)
00211 {
00212 CHECK_SAME_TYPE(U, F);
00213 }
00214
00218 #define REQUIRE_SAME_TYPE(v1, v2){require_same_type(v1, v2);}
00219
00220
00221
00222 #endif // INSTIGATE_GENERIC_BASE
00223