source: branches/alilink/TEMPLATES/ttypes.h

Last change on this file was 11002, checked in by westram, 11 years ago
  • 'class { public' → struct
File size: 8.0 KB
Line 
1// ============================================================== //
2//                                                                //
3//   File      : ttypes.h                                         //
4//   Purpose   : template type inspection                         //
5//                                                                //
6//   Coded by Ralf Westram (coder@reallysoft.de) in August 2011   //
7//   Institute of Microbiology (Technical University Munich)      //
8//   http://www.arb-home.de/                                      //
9//                                                                //
10// ============================================================== //
11
12#ifndef TTYPES_H
13#define TTYPES_H
14
15// according to C++ templates by Vandevoorde/Josuttis
16// thank you for that great book
17
18#ifndef _GLIBCXX_CSTDLIB
19#include <cstdlib>
20#endif
21
22#define NOisnotYES() enum { No = !Yes }
23
24// --------------------------
25//      fundamental types
26
27template<typename T> class IsFundaT { public: enum { Yes = 0,  No = 1 }; };
28#define DECL_FUNDA_TYPE(t) template<> class IsFundaT<t> { public: enum { Yes = 1,  No = 0 }; };
29#define DECL_FUNDA_TYPE_SIGNED(t) DECL_FUNDA_TYPE(signed t); DECL_FUNDA_TYPE(unsigned t)
30
31DECL_FUNDA_TYPE(bool);
32DECL_FUNDA_TYPE(char);
33DECL_FUNDA_TYPE_SIGNED(char);
34DECL_FUNDA_TYPE_SIGNED(int);
35DECL_FUNDA_TYPE_SIGNED(long);
36DECL_FUNDA_TYPE_SIGNED(long long);
37DECL_FUNDA_TYPE(float);
38DECL_FUNDA_TYPE(double);
39DECL_FUNDA_TYPE(long double);
40
41#undef DECL_FUNDA_TYPE_SIGNED
42#undef DECL_FUNDA_TYPE
43
44// -----------------------
45//      function types
46
47template<typename T>
48class IsFunctionT {
49private:
50    typedef char yes;
51    typedef struct { char a[2]; } no;
52public:
53    template<typename U> static yes test(...);
54    template<typename U> static no  test(U (*)[1]);
55    enum { Yes = sizeof(test<T>(0)) == sizeof(yes) };
56    NOisnotYES();
57};
58
59#define NO_FUNCTION_TYPE(t) class IsFunctionT<t> { public: enum { Yes = 0 }; NOisnotYES(); }
60
61template<typename T> NO_FUNCTION_TYPE(T&);
62template<> NO_FUNCTION_TYPE(void);
63template<> NO_FUNCTION_TYPE(void const);
64template<> NO_FUNCTION_TYPE(void volatile);
65template<> NO_FUNCTION_TYPE(void const volatile);
66
67#undef NO_FUNCTION_TYPE
68
69// -----------------------
70//      compound types
71
72template<typename T>
73struct CompountT { // primary template
74    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = IsFunctionT<T>::Yes, IsPtrMemT = 0 };
75    typedef T BaseT;
76    typedef T BottomT;
77    typedef CompountT<void> ClassT;
78};
79template<typename T>
80struct CompountT<T*> { // specialization for pointers
81    enum { IsPtrT = 1, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 };
82    typedef T BaseT;
83    typedef typename CompountT<T>::BottomT BottomT;
84    typedef CompountT<void> ClassT;
85};
86template<typename T>
87struct CompountT<T&> { // specialization for references
88    enum { IsPtrT = 0, IsRefT = 1, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 };
89    typedef T BaseT;
90    typedef typename CompountT<T>::BottomT BottomT;
91    typedef CompountT<void> ClassT;
92};
93template<typename T, size_t N>
94struct CompountT<T[N]> { // specialization for arrays
95    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1, IsFuncT = 0, IsPtrMemT = 0 };
96    typedef T BaseT;
97    typedef typename CompountT<T>::BottomT BottomT;
98    typedef CompountT<void> ClassT;
99};
100template<typename T>
101struct CompountT<T[]> { // specialization for empty arrays
102    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1, IsFuncT = 0, IsPtrMemT = 0 };
103    typedef T BaseT;
104    typedef typename CompountT<T>::BottomT BottomT;
105    typedef CompountT<void> ClassT;
106};
107template<typename T, typename C>
108struct CompountT<T C::*> { // specialization for pointers to members
109    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 1 };
110    typedef T BaseT;
111    typedef typename CompountT<T>::BottomT BottomT;
112    typedef C ClassT;
113};
114
115template<typename R>
116struct CompountT<R()> { // specialization for functions ()
117    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 };
118    typedef R BaseT();
119    typedef R BottomT();
120    typedef CompountT<void> ClassT;
121};
122template<typename R, typename P1>
123struct CompountT<R(P1)> { // specialization for functions (P1)
124    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 };
125    typedef R BaseT(P1);
126    typedef R BottomT(P1);
127    typedef CompountT<void> ClassT;
128};
129template<typename R, typename P1>
130struct CompountT<R(P1, ...)> { // specialization for functions (P1, ...)
131    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 };
132    typedef R BaseT(P1);
133    typedef R BottomT(P1);
134    typedef CompountT<void> ClassT;
135};
136
137// -------------------
138//      enum types
139
140struct SizeOverOne { char c[2]; };
141
142template<typename T, bool convert_possible = !CompountT<T>::IsFuncT && !CompountT<T>::IsArrayT>
143class ConsumeUDC { public: operator T() const; };
144
145template<typename T> class ConsumeUDC<T, false> {}; // conversion to function types not possible
146template<bool convert_possible> class ConsumeUDC<void, convert_possible> {}; // conversion to void not possible
147
148#define enum_check_SIGNED(t) char enum_check(signed t); char enum_check(unsigned t)
149
150char enum_check(bool);
151enum_check_SIGNED(char);
152char enum_check(wchar_t);
153enum_check_SIGNED(short);
154enum_check_SIGNED(int);
155enum_check_SIGNED(long);
156char enum_check(float);
157char enum_check(double);
158char enum_check(long double);
159char enum_check(long long);
160
161#undef enum_check_SIGNED
162
163SizeOverOne enum_check(...); // catch all
164
165template<typename T>
166struct IsEnumT {
167    enum {
168        Yes = IsFundaT<T>::No    &&
169        !CompountT<T>::IsPtrT    &&
170        !CompountT<T>::IsRefT    &&
171        !CompountT<T>::IsPtrMemT &&
172        sizeof(enum_check(ConsumeUDC<T>())) == 1
173    };
174    NOisnotYES();
175};
176
177// --------------------
178//      class types
179
180template<typename T>
181struct IsClassT {
182    enum {
183        Yes = IsFundaT<T>::No    &&
184        IsEnumT<T>::No           &&
185        !CompountT<T>::IsPtrT    &&
186        !CompountT<T>::IsRefT    &&
187        !CompountT<T>::IsArrayT  &&
188        !CompountT<T>::IsPtrMemT &&
189        !CompountT<T>::IsFuncT
190    };
191    NOisnotYES();
192};
193
194// ---------------------------
195//      generic type check
196
197template<typename T>
198struct TypeT {
199    enum {
200        IsFundaT  = IsFundaT<T>::Yes,
201        IsPtrT    = CompountT<T>::IsPtrT,
202        IsRefT    = CompountT<T>::IsRefT,
203        IsArrayT  = CompountT<T>::IsArrayT,
204        IsFuncT   = CompountT<T>::IsFuncT,
205        IsPtrMemT = CompountT<T>::IsPtrMemT,
206        IsEnumT   = IsEnumT<T>::Yes,
207        IsClassT  = IsClassT<T>::Yes
208    };
209};
210
211
212// ----------------------
213//      modify types
214
215
216template<typename T>
217struct TypeOp  { // primary template
218    typedef T         ArgT;
219    typedef T         BareT;
220    typedef T const   ConstT;
221    typedef T &       RefT;
222    typedef T &       RefBareT;
223    typedef T const & RefConstT;
224};
225template<typename T>
226struct TypeOp<T const>  { // partial specialization for const types
227    typedef T const   ArgT;
228    typedef T         BareT;
229    typedef T const   ConstT;
230    typedef T const & RefT;
231    typedef T &       RefBareT;
232    typedef T const & RefConstT;
233};
234template<typename T>
235struct TypeOp<T&>  { // partial specialization for references
236    typedef T &                         ArgT;
237    typedef typename TypeOp<T>::BareT   BareT;
238    typedef T const                     ConstT;
239    typedef T &                         RefT;
240    typedef typename TypeOp<T>::BareT & RefBareT;
241    typedef T const &                   RefConstT;
242};
243template<>
244struct TypeOp<void>  { // full specialization for void
245    typedef void       ArgT;
246    typedef void       BareT;
247    typedef void const ConstT;
248    typedef void       RefT;
249    typedef void       RefBareT;
250    typedef void       RefConstT;
251};
252
253// -------------------------
254//      conditional type
255
256template<bool B, typename T, typename F> class IfThenElseType;
257template<typename T, typename F> class IfThenElseType<true, T, F> { public: typedef T ResultType; };
258template<typename T, typename F> class IfThenElseType<false, T, F> { public: typedef F ResultType; };
259
260#undef NOisnotYES
261
262#else
263#error ttypes.h included twice
264#endif // TTYPES_H
Note: See TracBrowser for help on using the repository browser.