wibble
0.1.28
|
00001 // -*- C++ -*- Substitution Failure Is Not An Error 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 = false; 00016 }; 00017 00018 // small SFINAE utilities, we probably prefer to avoid full weight of boost here 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, bool = true, bool = true, bool = true > 00030 struct TAndC { 00031 static const bool value = false; 00032 }; 00033 00034 template<> 00035 struct TAndC< true, true, true, true, true > { 00036 static const bool value = true; 00037 }; 00038 00039 template< typename A, typename B, 00040 typename C = TTrue, typename D = TTrue, typename E = TTrue > 00041 struct TAnd : TAndC< A::value, B::value, C::value, D::value, E::value > {}; 00042 00043 template< bool, bool, bool = false, bool = false, bool = false > 00044 struct TOrC { 00045 static const bool value = true; 00046 }; 00047 00048 template<> 00049 struct TOrC< false, false, false, false, false > { 00050 static const bool value = false; 00051 }; 00052 00053 template< typename A, typename B, 00054 typename C = TFalse, typename D = TFalse, typename E = TFalse > 00055 struct TOr : TOrC< A::value, B::value, C::value, D::value, E::value > {}; 00056 00057 /* template< typename T > 00058 struct IsT { 00059 static const bool value = true; 00060 }; */ 00061 00062 template< bool a > struct TNotC { 00063 static const bool value = !a; 00064 }; 00065 00066 template< typename T > struct TNot : TNotC< T::value > {}; 00067 00068 template< bool a, bool b > 00069 struct TImplyC : TNot< TAndC< a, TNotC< b >::value > > {}; 00070 00071 template< typename A, typename B > 00072 struct TImply : TImplyC< A::value, B::value > {}; 00073 00074 template< bool, typename T = Unit > 00075 struct EnableIfC {}; 00076 00077 template< typename Type > 00078 struct EnableIfC< true, Type > { typedef Type T; }; 00079 00080 template< typename X, typename T = Unit > 00081 struct EnableIf : EnableIfC< X::value, T > {}; 00082 00083 template< typename A, typename B > 00084 struct TPair { 00085 typedef A First; 00086 typedef B Second; 00087 }; 00088 00089 struct Preferred {}; 00090 struct NotPreferred { NotPreferred( Preferred ) {} }; 00091 00092 00093 } 00094 00095 #endif