00001
00002
00003 #ifndef WIBBLE_SFINAE_H
00004 #define WIBBLE_SFINAE_H
00005
00006 namespace wibble {
00007
00008 struct Unit {};
00009
00010 struct TTrue {
00011 static const bool value = true;
00012 };
00013
00014 struct TFalse {
00015 static const bool value = true;
00016 };
00017
00018
00019 template< typename A, typename B >
00020 struct TSame {
00021 static const bool value = false;
00022 };
00023
00024 template< typename A >
00025 struct TSame< A, A > {
00026 static const bool value = true;
00027 };
00028
00029 template< bool, bool >
00030 struct TAndC {
00031 static const bool value = false;
00032 };
00033
00034 template<>
00035 struct TAndC< true, true > {
00036 static const bool value = true;
00037 };
00038
00039 template< typename A, typename B >
00040 struct TAnd : TAndC< A::value, B::value > {};
00041
00042 template< bool, bool >
00043 struct TOrC {
00044 static const bool value = true;
00045 };
00046
00047 template<>
00048 struct TOrC< false, false > {
00049 static const bool value = false;
00050 };
00051
00052 template< typename A, typename B >
00053 struct TOr : TOrC< A::value, B::value > {};
00054
00055
00056
00057
00058
00059
00060 template< bool a > struct TNotC {
00061 static const bool value = !a;
00062 };
00063
00064 template< typename T > struct TNot : TNotC< T::value > {};
00065
00066 template< bool a, bool b >
00067 struct TImplyC : TNot< TAndC< a, TNotC< b >::value > > {};
00068
00069 template< typename A, typename B >
00070 struct TImply : TImplyC< A::value, B::value > {};
00071
00072 template< bool, typename T = Unit >
00073 struct EnableIfC {};
00074
00075 template< typename Type >
00076 struct EnableIfC< true, Type > { typedef Type T; };
00077
00078 template< typename X, typename T = Unit >
00079 struct EnableIf : EnableIfC< X::value, T > {};
00080
00081 template< typename A, typename B >
00082 struct TPair {
00083 typedef A First;
00084 typedef B Second;
00085 };
00086
00087 }
00088
00089 #endif