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