]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cxx/lib/tl/include/type_traits
update
[l4.git] / l4 / pkg / cxx / lib / tl / include / type_traits
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>,
4  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
5  *     economic rights: Technische Universität Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  *
11  * As a special exception, you may use this file as part of a free software
12  * library without restriction.  Specifically, if other files instantiate
13  * templates or use macros or inline functions from this file, or you compile
14  * this file and link it with other files to produce an executable, this
15  * file does not by itself cause the resulting executable to be covered by
16  * the GNU General Public License.  This exception does not however
17  * invalidate any other reasons why the executable file might be covered by
18  * the GNU General Public License.
19  */
20
21 #pragma once
22
23 namespace cxx {
24
25 class Null_type;
26
27 template< bool flag, typename T, typename F >
28 class Select 
29 {
30 public:
31   typedef T Type;
32 };
33
34 template< typename T, typename F >
35 class Select< false, T, F > 
36 {
37 public:
38   typedef F Type;
39 };
40   
41
42
43 template< typename T, typename U >
44 class Conversion
45 {
46   typedef char S;
47   class B { char dummy[2]; };
48   static S test(U);
49   static B test(...);
50   static T make_T();
51 public:
52   enum 
53   { 
54     exists = sizeof(test(make_T())) == sizeof(S),
55     two_way = exists && Conversion<U,T>::exists,
56     exists_2_way = two_way,
57     same_type = false
58   };
59 };
60
61 template< >
62 class Conversion<void, void>
63 {
64 public:
65   enum { exists = 1, two_way = 1, exists_2_way = two_way, same_type = 1 };
66 };
67
68 template< typename T >
69 class Conversion<T, T>
70 {
71 public:
72   enum { exists = 1, two_way = 1, exists_2_way = two_way, same_type = 1 };
73 };
74
75 template< typename T >
76 class Conversion<void, T>
77 {
78 public:
79   enum { exists = 0, two_way = 0, exists_2_way = two_way, same_type = 0 };
80 };
81
82 template< typename T >
83 class Conversion<T, void>
84 {
85 public:
86   enum { exists = 0, two_way = 0, exists_2_way = two_way, same_type = 0 };
87 };
88
89 template< int I >
90 class Int_to_type
91 {
92 public:
93   enum { i = I };
94 };
95
96 namespace TT
97 {
98   template< typename U > class Pointer_traits 
99   { 
100   public: 
101     typedef Null_type Pointee;
102     enum { value = false };
103   };
104
105   template< typename U > class Pointer_traits< U* > 
106   { 
107   public: 
108     typedef U Pointee;
109     enum { value = true };
110   };
111
112   template< typename U > struct Ref_traits 
113   { 
114     enum { value = false };
115     typedef U Referee;
116   };
117   
118   template< typename U > struct Ref_traits<U&> 
119   { 
120     enum { value = true };
121     typedef U Referee;
122   };
123
124
125   template< typename U > struct Add_ref { typedef U &Type; };
126   template< typename U > struct Add_ref<U&> { typedef U Type; };
127
128   template< typename U > struct PMF_traits { enum { value = false }; };
129   template< typename U, typename F > struct PMF_traits<U F::*> 
130   { enum { value = true }; };
131
132
133   template< typename U > class Is_unsigned { public: enum { value = false }; };
134   template<> class Is_unsigned<unsigned> { public: enum { value = true }; };
135   template<> class Is_unsigned<unsigned char> { 
136     public: enum { value = true }; 
137   };
138   template<> class Is_unsigned<unsigned short> { 
139     public: enum { value = true }; 
140   };
141   template<> class Is_unsigned<unsigned long> { 
142     public: enum { value = true }; 
143   };
144   template<> class Is_unsigned<unsigned long long> { 
145     public: enum { value = true }; 
146   };
147
148   template< typename U > class Is_signed { public: enum { value = false }; };
149   template<> class Is_signed<signed char> { public: enum { value = true }; };
150   template<> class Is_signed<signed short> { public: enum { value = true }; };
151   template<> class Is_signed<signed> { public: enum { value = true }; };
152   template<> class Is_signed<signed long> { public: enum { value = true }; };
153   template<> class Is_signed<signed long long> { 
154     public: enum { value = true }; 
155   };
156   
157   template< typename U > class Is_int { public: enum { value = false }; };
158   template<> class Is_int< char > { public: enum { value = true }; };
159   template<> class Is_int< bool > { public: enum { value = true }; };
160   template<> class Is_int< wchar_t > { public: enum { value = true }; };
161   
162   template< typename U > class Is_float { public: enum { value = false }; };
163   template<> class Is_float< float > { public: enum { value = true }; };
164   template<> class Is_float< double > { public: enum { value = true }; };
165   template<> class Is_float< long double > { public: enum { value = true }; };
166
167   template<typename T> class Const_traits
168   {
169   public:
170     enum { value = false };
171     typedef T Type;
172     typedef const T Const_type;
173   };
174
175   template<typename T> class Const_traits<const T>
176   {
177   public:
178     enum { value = true };
179     typedef T Type;
180     typedef const T Const_type;
181   };
182 };
183
184 template< typename T >
185 class Type_traits 
186 {
187 public:
188
189   enum
190   {
191     is_unsigned = TT::Is_unsigned<T>::value,
192     is_signed   = TT::Is_signed<T>::value,
193     is_int      = TT::Is_int<T>::value,
194     is_float    = TT::Is_float<T>::value,
195     is_pointer  = TT::Pointer_traits<T>::value,
196     is_pointer_to_member = TT::PMF_traits<T>::value,
197     is_reference = TT::Ref_traits<T>::value,
198     is_scalar = is_unsigned || is_signed || is_int || is_pointer 
199       || is_pointer_to_member || is_reference,
200     is_fundamental = is_unsigned || is_signed || is_float 
201       || Conversion<T, void>::same_type,
202     is_const    = TT::Const_traits<T>::value,
203
204     alignment = 
205         (sizeof(T) >= sizeof(unsigned long) 
206          ? sizeof(unsigned long)
207          : (sizeof(T) >= sizeof(unsigned)
208            ? sizeof(unsigned)
209            : (sizeof(T) >= sizeof(short)
210              ? sizeof(short)
211              : 1)))
212   };
213
214   typedef typename Select<is_scalar, T, typename TT::Add_ref<typename TT::Const_traits<T>::Const_type>::Type>::Type Param_type;
215   typedef typename TT::Pointer_traits<T>::Pointee Pointee_type;
216   typedef typename TT::Ref_traits<T>::Referee Referee_type;
217   typedef typename TT::Const_traits<T>::Type Non_const_type;
218   typedef typename TT::Const_traits<T>::Const_type Const_type;
219
220   static unsigned long align(unsigned long a)
221   { return (a + (unsigned long)alignment - 1UL) 
222     & ~((unsigned long)alignment - 1UL); }
223 };
224
225
226 };
227
228
229