]> git.tdb.fi Git - libs/core.git/blob - source/core/meta.h
6998c5d1b8a712d69176a556e7c677bb745b9ec2
[libs/core.git] / source / core / meta.h
1 #ifndef MSP_CORE_META_H_
2 #define MSP_CORE_META_H_
3
4 #include <cstddef>
5
6 namespace Msp {
7
8 template<typename T>
9 struct RemoveConst
10 { typedef T Type; };
11
12 template<typename T>
13 struct RemoveConst<const T>
14 { typedef T Type; };
15
16
17 template<typename T>
18 struct RemoveReference
19 { typedef T Type; };
20
21 template<typename T>
22 struct RemoveReference<T &>
23 { typedef T Type; };
24
25
26 template<typename T>
27 struct RemoveConstReference
28 { typedef typename RemoveConst<typename RemoveReference<T>::Type>::Type Type; };
29
30
31 template<bool c, typename R>
32 struct EnableIf;
33
34 template<typename R>
35 struct EnableIf<true, R>
36 { typedef R Yes; };
37
38 template<typename R>
39 struct EnableIf<false, R>
40 { typedef R No; };
41
42
43 /**
44 Common fragments used in SFINAE-based decider constructs.
45 */
46 struct Sfinae
47 {
48         struct Yes { char c[2]; };
49         struct No { char c; };
50
51         template<typename T>
52         static No f(...);
53
54         template<typename C, typename T>
55         struct Evaluate
56         {
57                 enum { value = (sizeof(C::template f<T>(0))==sizeof(Yes)) };
58         };
59 };
60
61
62 struct CheckEqualityComparable: Sfinae
63 {
64         static int &v;
65         template<typename T>
66         static Yes f(int (*)[sizeof(reinterpret_cast<const T &>(v)==reinterpret_cast<const T &>(v))]);
67         using Sfinae::f;
68 };
69
70 template<typename T>
71 struct IsEqualityComparable: Sfinae::Evaluate<CheckEqualityComparable, T> { };
72
73 } // namespace Msp
74
75 #endif