wibble  0.1.28
sfinae.h
Go to the documentation of this file.
1 // -*- C++ -*- Substitution Failure Is Not An Error
2 
3 #ifndef WIBBLE_SFINAE_H
4 #define WIBBLE_SFINAE_H
5 
6 namespace wibble {
7 
8 struct Unit {};
9 
10 struct TTrue {
11  static const bool value = true;
12 };
13 
14 struct TFalse {
15  static const bool value = false;
16 };
17 
18 // small SFINAE utilities, we probably prefer to avoid full weight of boost here
19 template< typename A, typename B >
20 struct TSame {
21  static const bool value = false;
22 };
23 
24 template< typename A >
25 struct TSame< A, A > {
26  static const bool value = true;
27 };
28 
29 template< bool, bool, bool = true, bool = true, bool = true >
30 struct TAndC {
31  static const bool value = false;
32 };
33 
34 template<>
35 struct TAndC< true, true, true, true, true > {
36  static const bool value = true;
37 };
38 
39 template< typename A, typename B,
40  typename C = TTrue, typename D = TTrue, typename E = TTrue >
41 struct TAnd : TAndC< A::value, B::value, C::value, D::value, E::value > {};
42 
43 template< bool, bool, bool = false, bool = false, bool = false >
44 struct TOrC {
45  static const bool value = true;
46 };
47 
48 template<>
49 struct TOrC< false, false, false, false, false > {
50  static const bool value = false;
51 };
52 
53 template< typename A, typename B,
54  typename C = TFalse, typename D = TFalse, typename E = TFalse >
55 struct TOr : TOrC< A::value, B::value, C::value, D::value, E::value > {};
56 
57 /* template< typename T >
58 struct IsT {
59  static const bool value = true;
60  }; */
61 
62 template< bool a > struct TNotC {
63  static const bool value = !a;
64 };
65 
66 template< typename T > struct TNot : TNotC< T::value > {};
67 
68 template< bool a, bool b >
69 struct TImplyC : TNot< TAndC< a, TNotC< b >::value > > {};
70 
71 template< typename A, typename B >
72 struct TImply : TImplyC< A::value, B::value > {};
73 
74 template< bool, typename T = Unit >
75 struct EnableIfC {};
76 
77 template< typename Type >
78 struct EnableIfC< true, Type > { typedef Type T; };
79 
80 template< typename X, typename T = Unit >
81 struct EnableIf : EnableIfC< X::value, T > {};
82 
83 template< typename A, typename B >
84 struct TPair {
85  typedef A First;
86  typedef B Second;
87 };
88 
89 struct Preferred {};
91 
92 
93 }
94 
95 #endif