Merge from vendor branch GCC:
[dragonfly.git] / contrib / gcc-4.1 / libstdc++-v3 / include / ext / pb_assoc / detail / type_utils.hpp
1 // -*- C++ -*-
2
3 // Copyright (C) 2005 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
31
32 // Permission to use, copy, modify, sell, and distribute this software
33 // is hereby granted without fee, provided that the above copyright
34 // notice appears in all copies, and that both that copyright notice and
35 // this permission notice appear in supporting documentation. None of
36 // the above authors, nor IBM Haifa Research Laboratories, make any
37 // representation about the suitability of this software for any
38 // purpose. It is provided "as is" without express or implied warranty.
39
40 /**
41  * @file type_utils.hpp
42  * Contains utilities for handnling types. All of these classes are based on
43  *      "Modern C++" by Andrei Alxandrescu.
44  */
45
46 #ifndef TYPE_UTILS_HPP
47 #define TYPE_UTILS_HPP
48
49 #include <cstddef>
50 #include <utility>
51
52 namespace pb_assoc
53 {
54
55   namespace detail
56   {
57
58     template<bool>
59     struct static_assert;
60
61     template<>
62     struct static_assert<true>
63     { };
64
65     template<int>
66     struct static_assert_dummy_class
67     {
68       enum
69         {
70           v = 1
71         };
72     };
73
74     template<class T, class U>
75     class is_same_type
76     {
77     public:
78       enum
79         {
80           value = false
81         };
82     };
83
84     template<class T>
85     class is_same_type<
86       T,
87       T>
88     {
89     public:
90       enum
91         {
92           value = true
93         };
94     };
95
96     template<int n>
97     struct int_to_type
98     {
99       enum
100         {
101           value = n
102         };
103     };
104
105     template<typename Type>
106     struct type_to_type
107     {
108       typedef Type type;
109     };
110
111     template<typename T>
112     class unconst
113     {
114     private:
115       template<class U>
116       struct unconst_imp
117       {
118         typedef U type;
119       };
120
121       template<class U>
122       struct unconst_imp<
123         const U>
124       {
125         typedef U type;
126       };
127     public:
128       typedef typename unconst_imp<T>::type type;
129     };
130
131     template<typename T>
132     class unreference
133     {
134     private:
135       template<class U>
136       struct unreference_imp
137       {
138         typedef U type;
139       };
140
141       template<class U>
142       struct unreference_imp<U&>
143       {
144         typedef U type;
145       };
146     public:
147       typedef typename unreference_imp<T>::type type;
148     };
149
150     /* is_const_type
151      * Idea by Andrei Alecsandrescu
152      *  (Modern C++ Design: Generic Programming and Design Patterns Applied)
153      **/
154     template<typename T>
155     class is_const_type
156     {
157     private:
158       template<class U>
159       struct is_const_type_imp
160       {
161         enum
162           {
163             value = 0
164           };
165       };
166
167       template<class U>
168       struct is_const_type_imp<const U>
169       {
170         enum
171           {
172             value = 1
173           };
174       };
175
176     public:
177       enum
178         {
179           value = is_const_type_imp<T>::value
180         };
181     };
182
183     /* is_pointer_type
184     **/
185     template<typename T>
186     class is_pointer_type
187     {
188     private:
189       template<class U>
190       struct is_pointer_type_imp
191       {
192         enum
193           {
194             value = 0
195           };
196       };
197
198       template<class U>
199       struct is_pointer_type_imp
200       <U* >
201       {
202         enum
203           {
204             value = 1
205           };
206       };
207
208     public:
209       enum
210         {
211           value = is_pointer_type_imp<T>::value
212         };
213     };
214
215     /* is_pointer_type
216     **/
217     template<typename T>
218     class is_const_pointer_type
219     {
220     private:
221       template<class U>
222       struct is_const_pointer_type_imp
223       {
224         enum
225           {
226             value = 0
227           };
228       };
229
230       template<class U>
231       struct is_const_pointer_type_imp
232       <const U* >
233       {
234         enum
235           {
236             value = 1
237           };
238       };
239
240     public:
241       enum
242         {
243           value = is_const_pointer_type_imp<T>::value
244         };
245     };
246
247     template<typename T>
248     class is_reference_type
249     {
250     private:
251       template<class U>
252       struct is_reference_type_imp
253       {
254         enum
255           {
256             value = 0
257           };
258       };
259
260       template<class U>
261       struct is_reference_type_imp<U& >
262       {
263         enum
264           {
265             value = 1
266           };
267       };
268
269     public:
270       enum
271         {
272           value = is_reference_type_imp<T>::value
273         };
274     };
275
276     template<typename T>
277     class is_const_reference_type
278     {
279     private:
280       template<class U>
281       struct is_const_reference_type_imp
282       {
283         enum
284           {
285             value = 0
286           };
287       };
288
289       template<class U>
290       struct is_const_reference_type_imp<U& >
291       {
292         enum
293           {
294             value = 1
295           };
296       };
297
298     public:
299       enum
300         {
301           value = is_const_reference_type_imp<T>::value
302         };
303     };
304
305     template<typename T>
306     class is_member_pointer_type
307     {
308     private:
309       template<typename U>
310       struct is_member_pointer_type_imp
311       {
312         enum
313           {
314             value = 0
315           };
316       };
317
318       template<typename U, typename V>
319       struct is_member_pointer_type_imp<
320         U V::*>
321       {
322         enum
323           {
324             value = 1
325           };
326       };
327
328     public:
329       enum
330         {
331           value = is_member_pointer_type_imp<T>::value
332         };
333     };
334
335 #define PB_ASSOC_IS_SAME_TYPE(TYPE) is_same_type<T, TYPE>::value
336
337     template<class T>
338     class is_simple_type
339     {
340       template<class U>
341       struct is_simple_type_imp
342       {
343         enum
344           {
345             value = 0
346           };
347       };
348
349       template<class U, size_t M>
350       struct is_simple_type_imp<
351         U[M]>
352       {
353         enum
354           {
355             value = is_simple_type<U>::value
356           };
357       };
358
359       template<class U>
360       struct is_simple_type_imp<
361         U[]>
362       {
363         enum
364           {
365             value = is_simple_type<U>::value
366           };
367       };
368
369       template<typename T0, typename T1>
370       struct is_simple_type_imp<
371         std::pair<
372         T0,
373         T1> >
374       {
375         enum
376           {
377             value = is_simple_type<T0>::value&& 
378             is_simple_type<T1>::value
379           };
380       };
381
382     public:
383       enum
384         {
385           value =
386           PB_ASSOC_IS_SAME_TYPE(void) ||
387           PB_ASSOC_IS_SAME_TYPE(size_t) ||
388           PB_ASSOC_IS_SAME_TYPE(const void)     ||
389           PB_ASSOC_IS_SAME_TYPE(unsigned char) ||
390           PB_ASSOC_IS_SAME_TYPE(unsigned short int) ||
391           PB_ASSOC_IS_SAME_TYPE(unsigned int) ||
392           PB_ASSOC_IS_SAME_TYPE(unsigned long int) ||
393           PB_ASSOC_IS_SAME_TYPE(signed char) ||
394           PB_ASSOC_IS_SAME_TYPE(signed short int) ||
395           PB_ASSOC_IS_SAME_TYPE(int) ||
396           PB_ASSOC_IS_SAME_TYPE(long int) ||
397           PB_ASSOC_IS_SAME_TYPE(bool) ||
398           PB_ASSOC_IS_SAME_TYPE(char) ||
399           PB_ASSOC_IS_SAME_TYPE(float) ||
400           PB_ASSOC_IS_SAME_TYPE(double) ||
401           PB_ASSOC_IS_SAME_TYPE(long double) ||
402           PB_ASSOC_IS_SAME_TYPE(const unsigned char) ||
403           PB_ASSOC_IS_SAME_TYPE(const unsigned short int) ||
404           PB_ASSOC_IS_SAME_TYPE(const unsigned int) ||
405           PB_ASSOC_IS_SAME_TYPE(const unsigned long int) ||
406           PB_ASSOC_IS_SAME_TYPE(const signed char) ||
407           PB_ASSOC_IS_SAME_TYPE(const signed short int) ||
408           PB_ASSOC_IS_SAME_TYPE(const int) ||
409           PB_ASSOC_IS_SAME_TYPE(const long int) ||
410           PB_ASSOC_IS_SAME_TYPE(const bool) ||
411           PB_ASSOC_IS_SAME_TYPE(const char) ||
412           PB_ASSOC_IS_SAME_TYPE(const float) ||
413           PB_ASSOC_IS_SAME_TYPE(const double) ||
414           PB_ASSOC_IS_SAME_TYPE(const long double) ||
415           is_pointer_type<T>::value ||
416           is_const_pointer_type<T>::value ||
417           is_member_pointer_type<T>::value ||
418           is_simple_type_imp<T>::value
419         };
420     };
421
422 #undef PB_ASSOC_IS_SAME_TYPE
423
424     template<bool Cond, class A, class B>
425     struct cond_type;
426
427     template<class A, class B>
428     struct cond_type<
429       true,
430       A,
431       B>
432     {
433       typedef A type;
434     };
435
436     template<class A, class B>
437     struct cond_type<
438       false,
439       A,
440       B>
441     {
442       typedef B type;
443     };
444
445   } // namespace detail
446
447 } // namespace pb_assoc
448
449 #endif // #ifndef TYPE_UTILS_HPP