1
// -*- C++ -*- Time-stamp: <2012-04-20 17:23:24 ptr>
2
3
/*
4
 * Copyright (c) 2007, 2008, 2010-2011
5
 * Petr Ovtchenkov
6
 *
7
 * This material is provided "as is", with absolutely no warranty expressed
8
 * or implied. Any use is at your own risk.
9
 *
10
 * Permission to use or copy this software for any purpose is hereby granted
11
 * without fee, provided the above notices are retained on all copies.
12
 * Permission to modify the code and to distribute modified code is granted,
13
 * provided the above notices are retained, and a notice that the code was
14
 * modified is included with the above copyright notice.
15
 *
16
 * Derived from original <misc/type_traits.h> of 'complement' project
17
 * [http://complement.sourceforge.net]
18
 * to make it close to JTC1/SC22/WG21 C++ 0x working draft
19
 * [http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2010/n3126.pdf]
20
 */
21
22
#ifndef __STLP_TYPE_TRAITS
23
#define __STLP_TYPE_TRAITS
24
25
#ifndef _STLP_OUTERMOST_HEADER_ID
26
#  define _STLP_OUTERMOST_HEADER_ID 0x3
27
#  include <stl/_cprolog.h>
28
#endif
29
30
#ifndef _STLP_CSTDDEF
31
#  include <cstddef>
32
#endif
33
34
_STLP_BEGIN_NAMESPACE
35
36
template <class _Tp, _Tp __v>
37
struct integral_constant
38
{
39
    static const _Tp                    value = __v;
40
    // enum { value = __v }; ?
41
42
    typedef _Tp                         value_type;
43
    typedef integral_constant<_Tp, __v> type;
44
};
45
46
typedef integral_constant<bool, true>   true_type;
47
typedef integral_constant<bool, false>  false_type;
48
49
template <class _Tp1, class _Tp2>
50
struct is_same :
51
    public false_type
52
{ };
53
54
template <class _Tp>
55
struct is_same<_Tp, _Tp> :
56
    public true_type
57
{ };
58
59
namespace detail {
60
61
#ifndef _STLP_CPP_0X
62
63
struct __select_types
64
{
65
    typedef char __t1;
66
    struct __t2
67
    {
68
        char __two[2];
69
    };
70
};
71
72
#endif // _STLP_CPP_0X
73
74
template <class _Tp>
75
struct __instance
76
{
77
  private:
78
#ifdef _STLP_CPP_0X
79
    template <class _Up>
80
    static true_type __test(_Up(*)[1]);
81
82
    template <class>
83
    static false_type __test(...);
84
#else // _STLP_CPP_0X
85
    template <class _Up>
86
    static typename __select_types::__t1 __test(_Up(*)[1]);
87
88
    template <class>
89
    static typename __select_types::__t2 __test(...);
90
#endif // _STLP_CPP_0X
91
    
92
  public:
93
#ifdef _STLP_STATIC_CONST_INIT_BUG
94
    static const bool __value;
95
#else
96
#ifdef _STLP_CPP_0X
97
    static const bool __value = is_same<decltype(__test<_Tp>(0)),true_type>::value;
98
#else // _STLP_CPP_0X
99
    static const bool __value = sizeof(__test<_Tp>(0)) == sizeof(__select_types::__t1);
100
#endif // _STLP_CPP_0X
101
#endif
102
103
};
104
105
#ifdef _STLP_STATIC_CONST_INIT_BUG
106
template <class _Tp>
107
const bool __instance<_Tp>::__value = sizeof(__instance<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1);
108
#endif
109
110
template <class T>
111
struct __uoc_aux // union or class
112
{
113
  private:
114
#ifdef _STLP_CPP_0X
115
    template <class _Up>
116
    static true_type __test( int _Up::* );
117
118
    template <class>
119
    static false_type __test(...);
120
#else // _STLP_CPP_0X
121
    template <class _Up>
122
    static __select_types::__t1 __test( int _Up::* );
123
124
    template <class>
125
    static __select_types::__t2 __test(...);
126
#endif // _STLP_CPP_0X
127
    
128
  public:
129
#ifdef _STLP_STATIC_CONST_INIT_BUG
130
    static const bool __value;
131
#else
132
#ifdef _STLP_CPP_0X
133
    static const bool __value = is_same<decltype(__test<T>(0)),true_type>::value;
134
#else // _STLP_CPP_0X
135
    static const bool __value = sizeof(__test<T>(0)) == sizeof(__select_types::__t1);
136
#endif // _STLP_CPP_0X
137
#endif
138
};
139
140
#ifdef _STLP_STATIC_CONST_INIT_BUG
141
template <class T>
142
const bool __uoc_aux<T>::__value = sizeof(__uoc_aux<T>::__test<T>(0)) == sizeof(__select_types::__t1);
143
#endif
144
145
template <class T>
146
class __empty
147
{ };
148
149
template <class T, bool B>
150
class __inheritance_aux
151
{};
152
153
template <class T>
154
class __inheritance_aux<T,true> :
155
    public T
156
{
157
  public:
158
    virtual ~__inheritance_aux()
159
      { }
160
};
161
162
#if 0
163
template <class T, bool B>
164
struct __virtual_aux
165
{
166
  public:
167
#ifdef _STLP_STATIC_CONST_INIT_BUG
168
    static const bool __value;
169
#else
170
    static const bool __value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
171
#endif
172
};
173
174
#ifdef _STLP_STATIC_CONST_INIT_BUG
175
template <class T, bool B>
176
const bool __virtual_aux<T,B>::__value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
177
#endif
178
#endif
179
180
template <_STLP_STD_NAME::size_t L>
181
struct __aligned_aux
182
{
183
    union __type
184
    {
185
        unsigned char __data[L];
186
        struct __attribute__((__aligned__)) { } __align;
187
    };
188
};
189
190
template <typename _Tp>
191
struct __is_union_or_class :
192
    public integral_constant<bool, __uoc_aux<_Tp>::__value>
193
{ };
194
195
#if 0
196
template<typename _Tp>
197
struct __is_vtbl : // has virtual table?
198
    public integral_constant<bool, __virtual_aux<_Tp,__is_union_or_class<_Tp>::value >::__value>
199
{ };
200
#endif
201
202
template <typename _Tp>
203
struct __is_vtbl : // has virtual table?
204
    public integral_constant<bool, __is_union_or_class<_Tp>::value ? (sizeof(__inheritance_aux<_Tp,__is_union_or_class<_Tp>::value>) == sizeof(_Tp)) : false >
205
{ };
206
207
} // namespace detail
208
209
#define  __SPEC_(C,T,B)               \
210
template <>                           \
211
struct C<T> :                         \
212
    public integral_constant<bool, B> \
213
{ }
214
215
#define __CV_SPEC(C,T,B) \
216
__SPEC_(C,T,B);            \
217
__SPEC_(C,const T,B);      \
218
__SPEC_(C,volatile T,B);   \
219
__SPEC_(C,const volatile T,B)
220
221
#define  __SPEC_1(C,T,B)              \
222
template <class _Tp>                  \
223
struct C<T> :                         \
224
    public integral_constant<bool, B> \
225
{ }
226
227
#define __CV_SPEC_1(C,T,B) \
228
__SPEC_1(C,T,B);            \
229
__SPEC_1(C,T const,B);      \
230
__SPEC_1(C,T volatile,B);   \
231
__SPEC_1(C,T const volatile,B)
232
233
#define  __SPEC_2(C,T,B)              \
234
template <class _Tp1, class _Tp2>     \
235
struct C<T> :                         \
236
    public integral_constant<bool, B> \
237
{ }
238
239
#define __CV_SPEC_2(C,T,B) \
240
__SPEC_2(C,T,B);            \
241
__SPEC_2(C,T const,B);      \
242
__SPEC_2(C,T volatile,B);   \
243
__SPEC_2(C,T const volatile,B)
244
245
// [20.5.4.1] primary type categories:
246
247
template <class _Tp>
248
struct is_void :
249
    public false_type
250
{ };
251
252
template <>
253
struct is_void<void> :
254
    public true_type
255
{ };
256
257
template <class _Tp>
258
struct is_integral :
259
    public false_type
260
{ };
261
262
__CV_SPEC(is_integral,bool,true);
263
__CV_SPEC(is_integral,char,true);
264
__CV_SPEC(is_integral,signed char,true);
265
__CV_SPEC(is_integral,unsigned char,true);
266
__CV_SPEC(is_integral,wchar_t,true);
267
__CV_SPEC(is_integral,short,true);
268
__CV_SPEC(is_integral,unsigned short,true);
269
__CV_SPEC(is_integral,int,true);
270
__CV_SPEC(is_integral,unsigned int,true);
271
__CV_SPEC(is_integral,long,true);
272
__CV_SPEC(is_integral,unsigned long,true);
273
__CV_SPEC(is_integral,long long,true);
274
__CV_SPEC(is_integral,unsigned long long,true);
275
276
template <class _Tp>
277
struct is_floating_point :
278
    public false_type
279
{ };
280
281
__CV_SPEC(is_floating_point,float,true);
282
__CV_SPEC(is_floating_point,double,true);
283
__CV_SPEC(is_floating_point,long double,true);
284
285
template <class _Tp>
286
struct is_array :
287
    public false_type
288
{ };
289
290
template <class _Tp, _STLP_STD::size_t _Sz>
291
struct is_array<_Tp[_Sz]> :
292
    public true_type
293
{ };
294
295
template <class _Tp>
296
struct is_array<_Tp[]> :
297
    public true_type
298
{ };
299
300
template <class _Tp>
301
struct is_pointer :
302
    public false_type
303
{ };
304
305
__CV_SPEC_1(is_pointer,_Tp *,true);
306
307
template <class _Tp>
308
struct is_lvalue_reference :
309
    public false_type
310
{ };
311
312
template <class _Tp>
313
struct is_lvalue_reference<_Tp&> :
314
    public true_type
315
{ };
316
317
template <class _Tp>
318
struct is_rvalue_reference :
319
    public false_type
320
{ };
321
322
#ifdef _STLP_CPP_0X
323
template <class _Tp>
324
struct is_rvalue_reference<_Tp&&> :
325
    public true_type
326
{ };
327
#endif
328
329
template <class _Tp>
330
struct is_reference :
331
    public integral_constant<bool, is_lvalue_reference<_Tp>::value || is_rvalue_reference<_Tp>::value>
332
{ };
333
334
template <class _Tp>
335
struct is_function :
336
    public integral_constant<bool, !(detail::__instance<_Tp>::__value
337
                                     || detail::__is_union_or_class<_Tp>::value
338
                                     || is_lvalue_reference<_Tp>::value
339
                                     || is_void<_Tp>::value)>
340
{ };
341
342
template <class _Tp>
343
struct is_member_object_pointer :
344
    public false_type
345
{ };
346
347
// _SPEC_FULL2(is_member_object_pointer, _Tp1 _Tp2::*,!is_function<_Tp1>::value);
348
349
template <class _Tp1, class _Tp2>
350
struct is_member_object_pointer<_Tp1 _Tp2::*> :
351
    public integral_constant<bool, !is_function<_Tp1>::value>
352
{ };
353
354
template <class _Tp1, class _Tp2>
355
struct is_member_object_pointer<_Tp1 _Tp2::* const> :
356
    public integral_constant<bool, !is_function<_Tp1>::value>
357
{ };
358
359
template <class _Tp1, class _Tp2>
360
struct is_member_object_pointer<_Tp1 _Tp2::* volatile> :
361
    public integral_constant<bool, !is_function<_Tp1>::value>
362
{ };
363
364
template <class _Tp1, class _Tp2>
365
struct is_member_object_pointer<_Tp1 _Tp2::* const volatile> :
366
    public integral_constant<bool, !is_function<_Tp1>::value>
367
{ };
368
369
template <class _Tp>
370
struct is_member_function_pointer :
371
    public false_type
372
{ };
373
374
// _SPEC_FULL2(is_member_function_pointer,_Tp1 _Tp2::*,is_function<_Tp1>::value);
375
376
template <class _Tp1, class _Tp2>
377
struct is_member_function_pointer<_Tp1 _Tp2::*> :                         
378
    public integral_constant<bool, is_function<_Tp1>::value> 
379
{ };
380
381
template <class _Tp1, class _Tp2>
382
struct is_member_function_pointer<_Tp1 _Tp2::* const> :
383
    public integral_constant<bool, is_function<_Tp1>::value>
384
{ };
385
386
template <class _Tp1, class _Tp2>
387
struct is_member_function_pointer<_Tp1 _Tp2::* volatile> :
388
    public integral_constant<bool, is_function<_Tp1>::value>
389
{ };
390
391
template <class _Tp1, class _Tp2>
392
struct is_member_function_pointer<_Tp1 _Tp2::* const volatile> :
393
    public integral_constant<bool, is_function<_Tp1>::value>
394
{ };
395
396
template <class _Tp>
397
struct is_member_pointer :
398
    public integral_constant<bool, (is_member_object_pointer<_Tp>::value || is_member_function_pointer<_Tp>::value)>
399
{ };
400
401
// [20.5.4.2] composite type categories
402
403
// is_reference see above
404
405
template <class _Tp>
406
struct is_arithmetic :
407
    public integral_constant<bool, (is_integral<_Tp>::value || is_floating_point<_Tp>::value)>
408
{ };
409
410
template <class _Tp>
411
struct is_fundamental :
412
    public integral_constant<bool, (is_arithmetic<_Tp>::value || is_void<_Tp>::value)>
413
{ };
414
415
// [20.5.4.1] primary type categories (continued):
416
417
template <class _Tp>
418
struct is_enum :
419
    public integral_constant<bool,
420
#ifndef _STLP_IS_ENUM
421
                             !(is_fundamental<_Tp>::value
422
                               || is_array<_Tp>::value
423
                               || is_pointer<_Tp>::value
424
                               || is_lvalue_reference<_Tp>::value
425
                               || is_member_pointer<_Tp>::value
426
                               || is_function<_Tp>::value
427
                               || detail::__is_union_or_class<_Tp>::value)
428
#else
429
                             _STLP_IS_ENUM(_Tp)
430
#endif
431
                             >
432
{ };
433
434
template <class _Tp>
435
struct is_union :
436
    public integral_constant<bool,
437
#ifndef _STLP_IS_UNION
438
                             detail::__is_union_or_class<_Tp>::value
439
#else
440
                             _STLP_IS_UNION(_Tp)
441
#endif
442
                             >
443
{ };
444
445
template <class _Tp>
446
struct is_class :
447
    public integral_constant<bool,
448
#ifndef _STLP_IS_CLASS
449
                             detail::__is_union_or_class<_Tp>::value
450
#else
451
                             _STLP_IS_CLASS(_Tp)
452
#endif
453
                             >
454
{ };
455
456
// is_function (above)
457
458
// [20.5.4.2] composite type categories (continued)
459
460
// is_arithmetic (above)
461
// is_fundamental (above)
462
463
template <class _Tp>
464
struct is_object :
465
    public integral_constant<bool, (is_arithmetic<_Tp>::value ||
466
                                    is_enum<_Tp>::value ||
467
                                    is_array<_Tp>::value ||
468
                                    is_pointer<_Tp>::value ||
469
                                    is_member_pointer<_Tp>::value ||
470
                                    detail::__is_union_or_class<_Tp>::value)>
471
{ };
472
473
template <class _Tp>
474
struct is_scalar :
475
    public integral_constant<bool, (is_arithmetic<_Tp>::value
476
                                    || is_enum<_Tp>::value
477
                                    || is_pointer<_Tp>::value
478
                                    || is_member_pointer<_Tp>::value)>
479
{ };
480
481
template <class _Tp>
482
struct is_compound :
483
    public integral_constant<bool, !is_fundamental<_Tp>::value>
484
{ };
485
486
// is_member_pointer
487
488
// [20.5.4.3] type properties:
489
490
template <class _Tp>
491
struct is_const :
492
    public false_type
493
{ };
494
495
template <class _Tp>
496
struct is_const<_Tp const> :
497
    public true_type
498
{ };
499
500
template <class _Tp>
501
struct is_volatile :
502
    public false_type
503
{ };
504
505
template <class _Tp>
506
struct is_volatile<_Tp volatile> :
507
    public true_type
508
{ };
509
510
// [20.5.6.4] array modifications:
511
512
template <class _Tp>
513
struct remove_extent
514
{
515
    typedef _Tp type;
516
};
517
518
template <class _Tp, _STLP_STD::size_t _Sz>
519
struct remove_extent<_Tp[_Sz]>
520
{
521
    typedef _Tp type;
522
};
523
524
template <class _Tp>
525
struct remove_extent<_Tp[]>
526
{
527
    typedef _Tp type;
528
};
529
530
template <class _Tp>
531
struct remove_all_extents
532
{
533
    typedef _Tp type;
534
};
535
536
template <class _Tp, _STLP_STD::size_t _Size>
537
struct remove_all_extents<_Tp[_Size]>
538
{
539
    typedef typename remove_all_extents<_Tp>::type type;
540
};
541
542
template<typename _Tp>
543
struct remove_all_extents<_Tp[]>
544
{
545
    typedef typename remove_all_extents<_Tp>::type type;
546
};
547
548
// [20.5.4.3] type properties (continued):
549
550
template <class _Tp>
551
struct is_trivial :
552
    public integral_constant<bool,
553
#if !defined(_STLP_IS_TRIVIAL)
554
                             (is_void<_Tp>::value || is_scalar<typename remove_all_extents<_Tp>::type>::value)
555
#else
556
                             _STLP_IS_TRIVIAL(_Tp)
557
#endif
558
                             >
559
{ };
560
561
template <class _Tp>
562
struct is_trivially_copyable :
563
    public integral_constant<bool,
564
#if !defined(_STLP_HAS_TRIVIAL_COPY) || !defined(_STLP_HAS_TRIVIAL_DESTRUCTOR) || !defined(_STLP_HAS_TRIVIAL_ASSIGN)
565
                             (is_void<_Tp>::value || is_scalar<typename remove_all_extents<_Tp>::type>::value)
566
#else
567
                             _STLP_HAS_TRIVIAL_COPY(_Tp) &&
568
                             /* _STLP_HAS_TRIVIAL_MOVE(_Tp) && */
569
                             _STLP_HAS_TRIVIAL_DESTRUCTOR(_Tp) &&
570
                             _STLP_HAS_TRIVIAL_ASSIGN(_Tp)
571
                             /* && _STLP_HAS_TRIVIAL_MOVE_ASSIGN(_Tp) */
572
#endif
573
                             >
574
{ };
575
576
template <class _Tp>
577
struct is_standard_layout :
578
    public integral_constant<bool,
579
#if !defined(_STLP_IS_STANDARD_LAYOUT)
580
                             (is_void<_Tp>::value || is_scalar<typename remove_all_extents<_Tp>::type>::value)
581
#else
582
                             _STLP_IS_STANDARD_LAYOUT(_Tp)
583
#endif
584
                             >
585
{ };
586
587
template <class _Tp>
588
struct is_pod :
589
    public integral_constant<bool,
590
#if !defined(_STLP_IS_POD)
591
                             (is_void<_Tp>::value || is_scalar<typename remove_all_extents<_Tp>::type>::value)
592
#else
593
                             _STLP_IS_POD(_Tp)
594
#endif
595
                             >
596
{ };
597
598
template<typename _Tp>
599
struct is_empty
600
    : public integral_constant<bool,
601
#if !defined(_STLP_IS_EMPTY)
602
                               (detail::__is_union_or_class<_Tp>::value && (sizeof(detail::__empty<_Tp>) == sizeof(_Tp)))
603
#else
604
                               _STLP_IS_EMPTY(_Tp)
605
#endif
606
                               >
607
{ };
608
609
template <class _Tp>
610
struct is_polymorphic :
611
    public integral_constant<bool,
612
#if !defined(_STLP_IS_POLYMORPHIC)
613
                             false_type::value // no way to detect
614
#else
615
                             _STLP_IS_POLYMORPHIC(_Tp)
616
#endif
617
                             >
618
{ };
619
620
template <class _Tp>
621
struct is_abstract :
622
    public integral_constant<bool,
623
#if !defined(_STLP_IS_ABSTRACT)
624
                             false_type::value // no way to detect
625
#else
626
                             _STLP_IS_ABSTRACT(_Tp)
627
#endif
628
                             >
629
{ };
630
631
632
template <class _Tp>
633
struct is_signed :
634
    public false_type
635
{ };
636
637
__CV_SPEC(is_signed,signed char,true);
638
__CV_SPEC(is_signed,short,true);
639
__CV_SPEC(is_signed,int,true);
640
__CV_SPEC(is_signed,long,true);
641
__CV_SPEC(is_signed,long long,true);
642
643
template <class _Tp>
644
struct is_unsigned :
645
    public false_type
646
{ };
647
648
__CV_SPEC(is_unsigned,unsigned char,true);
649
__CV_SPEC(is_unsigned,unsigned short,true);
650
__CV_SPEC(is_unsigned,unsigned int,true);
651
__CV_SPEC(is_unsigned,unsigned long,true);
652
__CV_SPEC(is_unsigned,unsigned long long,true);
653
654
// alignment_of
655
// rank
656
// extent
657
658
// [20.5.5] type relations:
659
660
template <class _Base, class _Derived>
661
struct is_base_of :
662
    public
663
#ifndef _STLP_IS_BASE_OF
664
            false_type
665
#else
666
            integral_constant<bool, _STLP_IS_BASE_OF(_Base,_Derived)>
667
#endif
668
{ };
669
670
// [20.5.6.1] const-volatile modifications
671
672
template <class _Tp>
673
struct remove_const
674
{
675
    typedef _Tp type;
676
};
677
678
template <class _Tp>
679
struct remove_const<_Tp const>
680
{
681
    typedef _Tp type;
682
};
683
  
684
template <class _Tp>
685
struct remove_volatile
686
{
687
    typedef _Tp type;
688
};
689
690
template <class _Tp>
691
struct remove_volatile<_Tp volatile>
692
{
693
    typedef _Tp type;
694
};
695
696
template <class _Tp>
697
struct remove_cv
698
{
699
    typedef typename remove_const<typename remove_volatile<_Tp>::type>::type type;
700
};
701
  
702
template <class _Tp>
703
struct add_const
704
{
705
    typedef _Tp const type;
706
};
707
708
template <class _Tp>
709
struct add_const<_Tp const>
710
{
711
    typedef _Tp const type;
712
};
713
 
714
template <class _Tp>
715
struct add_volatile
716
{
717
    typedef _Tp volatile type;
718
};
719
720
template <class _Tp>
721
struct add_volatile<_Tp volatile>
722
{
723
    typedef _Tp volatile type;
724
};
725
 
726
template <class _Tp>
727
struct add_cv
728
{
729
    typedef typename add_const<typename add_volatile<_Tp>::type>::type type;
730
};
731
732
// [20.5.6.2] reference modifications:
733
734
template <class _Tp>
735
struct remove_reference
736
{
737
    typedef _Tp type;
738
};
739
740
template <class _Tp>
741
struct remove_reference<_Tp&>
742
{
743
    typedef _Tp type;
744
};
745
746
#if 0
747
template <class Fn, class ... Args> struct remove_reference<Fn&(Args...)>;
748
749
template <class T, class D>
750
struct remove_reference<D T::*>
751
{
752
    typedef D T::*type;
753
};
754
755
template <class T, class D>
756
struct remove_reference<D T::*&>
757
{
758
    typedef D T::*type;
759
};
760
761
#endif
762
763
template <class _Tp>
764
struct remove_reference<_Tp&&>
765
{
766
    typedef _Tp type;
767
};
768
769
#if 0
770
template <class T, class D>
771
struct remove_reference<D T::*&&>
772
{
773
    typedef D T::*type;
774
};
775
776
template <class Fn, class ... Args> struct remove_reference<Fn&&(Args...)>;
777
#endif
778
 
779
template <class _Tp>
780
struct add_lvalue_reference
781
{
782
    typedef typename remove_reference<_Tp>::type& type;
783
};
784
785
#ifdef _STLP_CPP_0X
786
787
template <class _Tp>
788
struct add_rvalue_reference
789
{
790
    typedef typename remove_reference<_Tp>::type&& type;
791
};
792
793
template <class _Tp>
794
typename add_rvalue_reference<_Tp>::type declval() _STLP_NOEXCEPT;
795
796
namespace detail {
797
798
template <class _Tp>
799
_Tp&& __declval_transparent() _STLP_NOEXCEPT;
800
801
} // detail
802
803
#if 0
804
template <class Fn, class ... Args>
805
struct remove_reference<Fn&(Args...)>
806
{
807
    typedef decltype(Fn(declval<Args>()...)) (*type)(Args...);
808
};
809
810
template <class Fn, class ... Args>
811
struct remove_reference<Fn&&(Args...)>
812
{
813
    typedef decltype(Fn(declval<Args>()...)) (*type)(Args...);
814
};
815
#endif
816
817
//template <class T, class Fn, class ... Args>
818
//struct remove_reference<T::Fn&(Args...)>
819
//{
820
    // typedef decltype((declval<T>()).*Fn(declval<Args>()...)) (T::*type)(Args...);
821
//    typedef void (T::*type)();
822
//};
823
824
#ifdef _STLP_VARIADIC_TEMPLATES
825
826
namespace detail {
827
828
template <class _Tp, class... _Args>
829
struct __is_constructible
830
{
831
  private:
832
    template <class _Up, class... _UpArgs>
833
    static typename remove_reference<decltype(_Up( declval<_UpArgs>()... ), declval<true_type>())>::type __test(int);
834
835
    template <class, class...>
836
    static false_type __test(...);    
837
  public:
838
#ifdef _STLP_STATIC_CONST_INIT_BUG
839
    static const bool __value;
840
#else
841
    static const bool __value = is_same<decltype(__test<_Tp, _Args...>(0)),true_type>::value;
842
#endif
843
};
844
845
#ifdef _STLP_STATIC_CONST_INIT_BUG
846
template <class _Tp, class... _Args>
847
const bool __is_constructible<_Tp,_Args...>::__value = sizeof(__is_constructible<_Tp,_Args...>::__test<_Tp,_Args...>(0)) == sizeof(__select_types::__t1);
848
#endif
849
850
} // detail
851
852
template <class _Tp, class... _Args>
853
struct is_constructible :
854
    public integral_constant<bool, detail::__is_constructible<_Tp,_Args...>::__value>
855
{ };
856
857
template <class _Tp>
858
struct is_default_constructible :
859
    public is_constructible<_Tp>
860
{ };
861
862
template <class _Tp>
863
struct is_copy_constructible :
864
    public is_constructible<_Tp,const _Tp&>
865
{ };
866
867
template <class _Tp>
868
struct is_move_constructible :
869
    public is_constructible<_Tp,_Tp&&>
870
{ };
871
872
#endif
873
874
#endif // _STLP_CPP_0X
875
876
namespace detail {
877
878
template <class _T1, class _T2>
879
struct __is_assignable
880
{
881
  private:
882
#ifdef _STLP_CPP_0X
883
    template <class _U1, class _U2>
884
    static typename remove_reference<decltype((detail::__declval_transparent<_U1>() = detail::__declval_transparent<_U2>()), declval<true_type>())>::type __test(int);
885
886
    template <class, class>
887
    static false_type __test(...);
888
#else // _STLP_CPP_0X
889
    template <class _U1, class _U2>
890
    static typename remove_reference<decltype((declval<_U1>() = declval<_U2>()), __select_types::__t1())>::type __test(int);
891
892
    template <class, class>
893
    static typename __select_types::__t2 __test(...);
894
#endif // _STLP_CPP_0X
895
    
896
  public:
897
#ifdef _STLP_STATIC_CONST_INIT_BUG
898
    static const bool __value;
899
#else
900
# ifdef _STLP_CPP_0X
901
    static const bool __value = is_same<decltype(__test<_T1,_T2>(0)),true_type>::value;
902
# else // _STLP_CPP_0X
903
    static const bool __value = sizeof(__test<_T1,_T2>(0)) == sizeof(__select_types::__t1);
904
# endif // _STLP_CPP_0X
905
#endif
906
};
907
908
#ifdef _STLP_STATIC_CONST_INIT_BUG
909
template <class _T1, class _T2>
910
  const bool __is_assignable<_T1,_T2>::__value = sizeof(__is_assignable<_T1,_T2>::__test<_T1,_T2>(0)) == sizeof(__select_types::__t1);
911
#endif
912
913
} // detail
914
915
template <class _Tp, class _Up>
916
struct is_assignable :
917
    public integral_constant<bool, detail::__is_assignable<_Tp,_Up>::__value>
918
{ };
919
920
template <class _Tp>
921
struct is_copy_assignable :
922
    public is_assignable<_Tp&, const _Tp&>
923
{ };
924
925
#ifdef _STLP_CPP_0X
926
927
template <class _Tp>
928
struct is_move_assignable :
929
    public is_assignable<_Tp&, _Tp&&>
930
{ };
931
932
#endif
933
934
namespace detail {
935
936
template <class _Tp>
937
struct __is_destructible
938
{
939
  private:
940
    template <class _Up>
941
    struct test_
942
    {
943
        _Up u;
944
    };
945
946
#ifdef _STLP_CPP_0X
947
    // template <class _Up>
948
    // static decltype( declval<test_<_Up> >().~test_<_Up>(), declval<true_type>() ) __test(int);
949
    template <class _Up>
950
    static typename _STLP_STD::remove_reference<decltype( declval<_Up>().~_Up(), declval<true_type>() )>::type __test(int);
951
952
    template <class>
953
    static false_type __test(...);
954
#else // _STLP_CPP_0X
955
    template <class _Up>
956
    static decltype( reinterpret_cast<test_<_Up>*>(0)->~test_<_Up>(), __select_types::__t1()) __test(int);
957
958
    template <class>
959
    static __select_types::__t2 __test(...);
960
#endif // _STLP_CPP_0X
961
    
962
  public:
963
#ifdef _STLP_STATIC_CONST_INIT_BUG
964
    static const bool __value;
965
#else
966
#ifdef _STLP_CPP_0X
967
    static const bool __value = is_same<decltype(__test<_Tp>(0)),true_type>::value;
968
#else // _STLP_CPP_0X
969
    static const bool __value = sizeof(__test<_Tp>(0)) == sizeof(__select_types::__t1);
970
#endif // _STLP_CPP_0X
971
#endif
972
};
973
974
#ifdef _STLP_STATIC_CONST_INIT_BUG
975
template <class _Tp>
976
const bool __is_destructible<_Tp>::__value = sizeof(__is_destructible<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1);
977
#endif
978
979
} // namespace detail
980
981
template <class _Tp>
982
struct is_destructible :
983
    public integral_constant<bool, detail::__is_destructible<_Tp>::__value>
984
{ };
985
986
#ifdef _STLP_VARIADIC_TEMPLATES
987
988
// Fix it: how to check that only trivial functions was used during construction?
989
template <class _Tp, class... _Args>
990
struct is_trivially_constructible :
991
    public integral_constant<bool, (is_constructible<_Tp,_Args...>::value &&
992
                                    !detail::__is_vtbl<_Tp>::value)>
993
{ };
994
995
// Fix it
996
template <class _Tp>
997
struct is_trivially_default_constructible :
998
    public integral_constant<bool, is_trivially_constructible<_Tp>::value &&
999
#ifndef _STLP_HAS_TRIVIAL_CONSTRUCTOR
1000
                             is_pod<_Tp>::value
1001
#else
1002
                             _STLP_HAS_TRIVIAL_CONSTRUCTOR(_Tp)
1003
#endif
1004
                             >
1005
{ };
1006
1007
// Fix it
1008
template <class _Tp>
1009
struct is_trivially_copy_constructible :
1010
    public integral_constant<bool, is_trivially_constructible<_Tp,const _Tp&>::value &&
1011
#ifndef _STLP_HAS_TRIVIAL_COPY
1012
                             is_pod<_Tp>::value
1013
#else
1014
                             _STLP_HAS_TRIVIAL_COPY(_Tp)
1015
#endif
1016
                             >
1017
{ };
1018
1019
// Fix it
1020
template <class _Tp>
1021
struct is_trivially_move_constructible :
1022
    public integral_constant<bool, is_trivially_constructible<_Tp,_Tp&&>::value &&
1023
// #ifndef _STLP_HAS_TRIVIAL_COPY
1024
                             is_pod<_Tp>::value
1025
// #else
1026
//                             _STLP_HAS_TRIVIAL_COPY(_Tp)
1027
// #endif
1028
                             >
1029
{ };
1030
1031
// Fix it
1032
template <class _Tp, class _Up>
1033
struct is_trivially_assignable :
1034
    public integral_constant<bool,is_assignable<_Tp,_Up>::value &&
1035
#ifndef _STLP_HAS_TRIVIAL_ASSIGN
1036
                             is_pod<T>::value
1037
#else
1038
                             _STLP_HAS_TRIVIAL_ASSIGN(_Tp)
1039
#endif
1040
                             >
1041
{ };
1042
1043
template <class T>
1044
struct is_trivially_copy_assignable :
1045
    public integral_constant<bool, is_trivially_assignable<T&,const T&>::value>
1046
{ };
1047
1048
1049
template <class T>
1050
struct is_trivially_move_assignable :
1051
    public integral_constant<bool, is_trivially_assignable<T&,T&&>::value>
1052
{ };
1053
1054
template <class T>
1055
struct is_trivially_destructible :
1056
    public integral_constant<bool, is_destructible<T>::value &&
1057
#ifndef _STLP_HAS_TRIVIAL_DESTRUCTOR
1058
                             is_pod<T>::value
1059
#else
1060
                             _STLP_HAS_TRIVIAL_DESTRUCTOR(T)
1061
#endif
1062
                             >
1063
{ };
1064
1065
template <class _Tp, class ... Args>
1066
struct is_nothrow_constructible :
1067
    public integral_constant<bool, is_constructible<_Tp,Args...>::value &&
1068
#ifndef _STLP_HAS_NOTHROW_CONSTRUCTOR
1069
                             is_pod<_Tp>::value
1070
#else
1071
                             _STLP_HAS_NOTHROW_CONSTRUCTOR(_Tp)
1072
#endif
1073
                             >
1074
{ };
1075
1076
template <class T>
1077
struct is_nothrow_default_constructible :
1078
    public integral_constant<bool, is_nothrow_constructible<T>::value>
1079
{ };
1080
1081
template <class T>
1082
struct is_nothrow_copy_constructible :
1083
    public integral_constant<bool,
1084
//#ifndef _STLP_HAS_NOTHROW_COPY
1085
                             is_nothrow_constructible<T,const T&>::value
1086
//#else
1087
//                             _STLP_HAS_NOTHROW_COPY(_Tp)
1088
//#endif
1089
                             >
1090
{ };
1091
1092
template <class T>
1093
struct is_nothrow_move_constructible :
1094
    public integral_constant<bool, is_nothrow_constructible<T,T&&>::value>
1095
{ };
1096
1097
template <class _Tp, class _Up>
1098
struct is_nothrow_assignable :
1099
    public integral_constant<bool, is_assignable<_Tp,_Up>::value &&
1100
#ifndef _STLP_HAS_NOTHROW_ASSIGN
1101
                             is_pod<_Tp>::value
1102
#else
1103
                             _STLP_HAS_NOTHROW_ASSIGN(_Tp)
1104
#endif
1105
                             >
1106
{ };
1107
1108
template <class T>
1109
struct is_nothrow_copy_assignable :
1110
    public integral_constant<bool, is_nothrow_assignable<T&,const T&>::value>
1111
{ };
1112
1113
template <class T>
1114
struct is_nothrow_move_assignable :
1115
    public integral_constant<bool, is_nothrow_assignable<T&,T&&>::value>
1116
{ };
1117
1118
template <class T>
1119
struct is_nothrow_destructible :
1120
    public integral_constant<bool, is_destructible<T>::value /* &&  is_pod<T>::value */ >
1121
{ };
1122
1123
template <class _Tp>
1124
struct has_virtual_destructor :
1125
    public
1126
#ifndef _STLP_HAS_VIRTUAL_DESTRUCTOR
1127
           false_type
1128
#else
1129
           integral_constant<bool, _STLP_HAS_VIRTUAL_DESTRUCTOR(_Tp)>
1130
#endif
1131
{ };
1132
1133
1134
/*
1135
10 A type is a literal type if it is:
1136
  - a scalar type; or
1137
  - a class type (Clause 9) with
1138
        - a trivial copy constructor,
1139
        - no non-trivial move constructor,
1140
        - a trivial destructor,
1141
        - a trivial default constructor or at least one constexpr
1142
          constructor other than the copy or move constructor, and
1143
        - all non-static data members and base classes of literal types; or
1144
  - an array of literal type.
1145
*/
1146
1147
template <class _Tp>
1148
struct is_literal_type :
1149
    public integral_constant<bool,
1150
#ifndef _STLP_IS_LITERAL_TYPE
1151
                                   (is_scalar<_Tp>::value ||
1152
                                    (is_class<_Tp>::value && 
1153
                                     is_trivially_copy_constructible<_Tp>::value &&
1154
                                     is_trivially_destructible<_Tp>::value &&
1155
                                     is_trivially_default_constructible<_Tp>::value) ||
1156
                                    (is_array<_Tp>::value && is_literal_type<typename remove_all_extents<_Tp>::type>::value)
1157
                                    )
1158
#else
1159
                             _STLP_IS_LITERAL_TYPE(_Tp)
1160
#endif
1161
                             >
1162
{ };
1163
1164
#else // _STLP_VARIADIC_TEMPLATES
1165
1166
template <class _Tp>
1167
struct is_trivially_default_constructible :
1168
    public integral_constant<bool,
1169
#ifndef _STLP_HAS_TRIVIAL_CONSTRUCTOR
1170
                             is_pod<_Tp>::value
1171
#else
1172
                             _STLP_HAS_TRIVIAL_CONSTRUCTOR(_Tp)
1173
#endif
1174
                             >
1175
{ };
1176
1177
template <class _Tp>
1178
struct is_trivially_copy_constructible :
1179
    public integral_constant<bool,
1180
#ifndef _STLP_HAS_TRIVIAL_COPY
1181
                             is_pod<_Tp>::value
1182
#else
1183
                             _STLP_HAS_TRIVIAL_COPY(_Tp)
1184
#endif
1185
                             >
1186
{ };
1187
1188
template <class _Tp>
1189
struct is_trivially_move_constructible :
1190
    public integral_constant<bool,
1191
// #ifndef _STLP_HAS_TRIVIAL_COPY
1192
                             is_pod<_Tp>::value
1193
// #else
1194
//                             _STLP_HAS_TRIVIAL_COPY(_Tp)
1195
// #endif
1196
                             >
1197
{ };
1198
1199
#endif // _STLP_VARIADIC_TEMPLATES
1200
1201
// [20.5.6.3] sign modifications
1202
1203
template <class _Tp>
1204
struct make_signed
1205
{
1206
};
1207
1208
template <>
1209
struct make_signed<char>
1210
{
1211
    typedef signed char type;
1212
};
1213
1214
template <>
1215
struct make_signed<signed char>
1216
{
1217
    typedef signed char type;
1218
};
1219
1220
template <>
1221
struct make_signed<unsigned char>
1222
{
1223
    typedef signed char type;
1224
};
1225
1226
template <>
1227
struct make_signed<short>
1228
{
1229
    typedef short type;
1230
};
1231
1232
template <>
1233
struct make_signed<unsigned short>
1234
{
1235
    typedef short type;
1236
};
1237
1238
template <>
1239
struct make_signed<int>
1240
{
1241
    typedef int type;
1242
};
1243
1244
template <>
1245
struct make_signed<unsigned int>
1246
{
1247
    typedef int type;
1248
};
1249
1250
template <>
1251
struct make_signed<long>
1252
{
1253
    typedef long type;
1254
};
1255
1256
template <>
1257
struct make_signed<unsigned long>
1258
{
1259
    typedef long type;
1260
};
1261
1262
template <>
1263
struct make_signed<long long>
1264
{
1265
    typedef long long type;
1266
};
1267
1268
template <>
1269
struct make_signed<unsigned long long>
1270
{
1271
    typedef long long type;
1272
};
1273
1274
template <class _Tp>
1275
struct make_unsigned
1276
{
1277
};
1278
1279
template <>
1280
struct make_unsigned<char>
1281
{
1282
    typedef unsigned char type;
1283
};
1284
1285
template <>
1286
struct make_unsigned<signed char>
1287
{
1288
    typedef unsigned char type;
1289
};
1290
1291
template <>
1292
struct make_unsigned<unsigned char>
1293
{
1294
    typedef unsigned char type;
1295
};
1296
1297
template <>
1298
struct make_unsigned<short>
1299
{
1300
    typedef unsigned short type;
1301
};
1302
1303
template <>
1304
struct make_unsigned<unsigned short>
1305
{
1306
    typedef unsigned short type;
1307
};
1308
1309
template <>
1310
struct make_unsigned<int>
1311
{
1312
    typedef unsigned int type;
1313
};
1314
1315
template <>
1316
struct make_unsigned<unsigned int>
1317
{
1318
    typedef unsigned int type;
1319
};
1320
1321
template <>
1322
struct make_unsigned<long>
1323
{
1324
    typedef unsigned long type;
1325
};
1326
1327
template <>
1328
struct make_unsigned<unsigned long>
1329
{
1330
    typedef unsigned long type;
1331
};
1332
1333
template <>
1334
struct make_unsigned<long long>
1335
{
1336
    typedef unsigned long long type;
1337
};
1338
1339
template <>
1340
struct make_unsigned<unsigned long long>
1341
{
1342
    typedef unsigned long long type;
1343
};
1344
1345
// [20.5.6.4] array modifications (see above)
1346
1347
// [20.5.6.5] pointer modifications:
1348
1349
template <class _Tp>
1350
struct remove_pointer
1351
{
1352
    typedef _Tp type;
1353
};
1354
1355
template <class _Tp>
1356
struct remove_pointer<_Tp *>
1357
{
1358
    typedef _Tp type;
1359
};
1360
1361
template <class _Tp>
1362
struct remove_pointer<_Tp * const>
1363
{
1364
    typedef _Tp type;
1365
};
1366
1367
template <class _Tp>
1368
struct remove_pointer<_Tp * volatile>
1369
{
1370
    typedef _Tp type;
1371
};
1372
1373
template <class _Tp>
1374
struct remove_pointer<_Tp * const volatile>
1375
{
1376
    typedef _Tp type;
1377
};
1378
1379
template <class _Tp>
1380
struct add_pointer
1381
{
1382
    typedef typename remove_reference<_Tp>::type * type;
1383
};
1384
1385
// [20.5.7] other transformations:
1386
1387
template <_STLP_STD_NAME::size_t L, _STLP_STD_NAME::size_t Align = __alignof__(typename detail::__aligned_aux<L>::__type)>
1388
struct aligned_storage
1389
{
1390
    union type
1391
    {
1392
        unsigned char __data[L];
1393
        struct __attribute__((__aligned__((Align))))
1394
        { } __align;
1395
    };
1396
};
1397
1398
// template <std::size_t Len, class... Types> struct aligned_union;
1399
1400
namespace detail {
1401
1402
template <class _From, class _To, bool>
1403
struct __is_convertible_aux
1404
{ };
1405
1406
template <class _From, class _To>
1407
struct __is_convertible_aux<_From,_To,true> :
1408
    public integral_constant<bool, is_void<_From>::value && is_void<_To>::value>
1409
{ };
1410
1411
template <class _From, class _To>
1412
struct __is_convertible_aux<_From,_To,false>
1413
{
1414
  private:
1415
#ifdef _STLP_CPP_0X
1416
    static true_type __test(_To);
1417
    static false_type __test(...);
1418
#else // _STLP_CPP_0X
1419
    static __select_types::__t1 __test(_To);
1420
    static __select_types::__t2 __test(...);
1421
#endif // _STLP_CPP_0X
1422
1423
  public:
1424
#ifdef _STLP_STATIC_CONST_INIT_BUG
1425
    static const bool value;
1426
#else
1427
# ifdef _STLP_CPP_0X
1428
    static const bool value = is_same<decltype(__test(declval<_From>())),true_type>::value;
1429
# else // _STLP_CPP_0X
1430
    static const bool value = sizeof(__test(_From())) == sizeof(__select_types::__t1);
1431
# endif // _STLP_CPP_0X
1432
#endif
1433
};
1434
1435
#ifdef _STLP_STATIC_CONST_INIT_BUG
1436
template <class _From, class _To>
1437
const bool __is_convertible_aux<_From,_To,false>::__value = sizeof(__is_convertible_aux<_From,_To,false>::__test<_From>(0)) == sizeof(__select_types::__t1);
1438
#endif
1439
1440
} // namespace detail
1441
1442
template <class _From, class _To>
1443
struct is_convertible :
1444
    public
1445
#ifndef _STLP_IS_CONVERTIBLE
1446
           integral_constant<bool, detail::__is_convertible_aux<_From,_To,
1447
                 is_void<_From>::value ||
1448
                 is_void<_To>::value ||
1449
                 is_function<_To>::value ||
1450
                 is_array<_To>::value>::value>
1451
#else
1452
            integral_constant<bool, _STLP_IS_CONVERTIBLE(_From,_To)>
1453
#endif
1454
{ };
1455
1456
namespace detail {
1457
1458
template <bool,class _U1>
1459
struct _decay_aux2
1460
{
1461
    typedef typename remove_cv<_U1>::type type;
1462
};
1463
1464
template <class _U1>
1465
struct _decay_aux2<true,_U1>
1466
{
1467
    typedef typename add_pointer<_U1>::type type;
1468
};
1469
1470
template <bool, class _U1>
1471
struct _decay_aux1
1472
{
1473
    typedef typename _decay_aux2<is_function<_U1>::value,_U1>::type type; 
1474
};
1475
1476
template <class _U1>
1477
struct _decay_aux1<true,_U1>
1478
{
1479
    typedef typename remove_extent<_U1>::type* type;
1480
};
1481
1482
} // namespace detail
1483
1484
template <class _Tp>
1485
class decay
1486
{
1487
  private:
1488
    typedef typename remove_reference<_Tp>::type _U1;
1489
1490
  public:
1491
    typedef typename detail::_decay_aux1<is_array<_U1>::value,_U1>::type type;
1492
};
1493
1494
template <bool, class _Tp = void>
1495
struct enable_if
1496
{
1497
};
1498
1499
template <class _Tp>
1500
struct enable_if<true,_Tp>
1501
{
1502
    typedef _Tp type;
1503
};
1504
1505
template <bool, class _Tp1, class _Tp2>
1506
struct conditional
1507
{
1508
    typedef _Tp2 type;
1509
};
1510
1511
template <class _Tp1, class _Tp2>
1512
struct conditional<true,_Tp1,_Tp2>
1513
{
1514
    typedef _Tp1 type;
1515
};
1516
1517
#ifdef _STLP_VARIADIC_TEMPLATES
1518
1519
template <class... _Tp>
1520
struct common_type;
1521
1522
template <class _Tp>
1523
struct common_type<_Tp>
1524
{
1525
    typedef _Tp type;
1526
};
1527
1528
template <class _T1, class _T2>
1529
struct common_type<_T1,_T2>
1530
{
1531
    typedef typename remove_reference<decltype( true ? declval<_T1>() : declval<_T2>() )>::type type;
1532
};
1533
1534
template <class _T1, class _T2, class... _T3>
1535
struct common_type<_T1,_T2,_T3...>
1536
{
1537
    typedef typename common_type<typename common_type<_T1,_T2>::type,_T3...>::type type;
1538
};
1539
1540
#endif
1541
1542
template <class T, class = typename enable_if<is_enum<T>::value>::type>
1543
struct underlying_type
1544
{
1545
#ifdef _STLP_UNDERLYING_TYPE
1546
    typedef _STLP_UNDERLYING_TYPE(T) type;
1547
#else
1548
    typedef int type;
1549
#endif
1550
};
1551
1552
template <class Fn, class ... ArgTypes> struct result_of;
1553
1554
namespace detail {
1555
1556
template <bool, class Fn, class ... ArgTypes>
1557
struct result_of_mem_function
1558
{
1559
};
1560
1561
// pointer on member data
1562
1563
template <class R, class T, class A, class ... ArgTypes>
1564
struct result_of_mem_function<false,R T::*,A,ArgTypes...>
1565
{
1566
  private:
1567
    static R&& __test( const T& );
1568
1569
    static const R& __test( const T* );
1570
1571
  public:
1572
    typedef decltype(__test(declval<A>())) type;
1573
};
1574
1575
// pointer on member function
1576
1577
template <class R, class T, class A, class ... ArgTypes>
1578
class result_of_mem_function<true,R T::*,A,ArgTypes...>
1579
{
1580
  private:
1581
    typedef R T::* _Fn;
1582
1583
    template <class U>
1584
    static U __test( const T& );
1585
1586
    template <class U>
1587
    static decltype(*declval<U>()) __test( ... );
1588
1589
  public:
1590
    typedef decltype( (__test<A>(declval<A>()).*declval<_Fn>())(declval<ArgTypes>()...) ) type;
1591
};
1592
1593
#if 0
1594
template <bool, class Fn, class ... ArgTypes>
1595
struct result_of_function
1596
{
1597
    typedef decltype( declval<Fn>()(declval<ArgTypes>()...) ) type;
1598
    // typedef Fn type;
1599
};
1600
1601
template <class Fn, class ... ArgTypes>
1602
struct result_of_function<true,Fn,ArgTypes...>
1603
{
1604
    typedef decltype( declval<Fn>()(declval<ArgTypes>()...) ) type;
1605
};
1606
#endif
1607
1608
template <bool, class Fn, class ... ArgTypes>
1609
struct result_of_functor
1610
{
1611
    typedef typename result_of_mem_function<is_member_function_pointer<Fn>::value,Fn,ArgTypes...>::type type;
1612
};
1613
1614
template <class Fn, class ... ArgTypes>
1615
struct result_of_functor<true,Fn,ArgTypes...>
1616
{
1617
    // typedef decltype( declval<typename remove_reference<Fn>::type>()(declval<ArgTypes>()...) ) type;
1618
    // Note: we can't (?) accept non-const reference as arguments, due to declval,
1619
    // that remove reference...
1620
    typedef decltype( declval<Fn>()(declval<ArgTypes>()...) ) type;
1621
};
1622
1623
} // namespace detail
1624
1625
template <class Fn, class ... ArgTypes>
1626
struct result_of<Fn(ArgTypes...)>
1627
{
1628
    typedef typename detail::result_of_functor</* is_function<typename remove_reference<Fn>::type>::value || */ !is_member_pointer<Fn>::value,Fn,ArgTypes...>::type type;
1629
};
1630
1631
// template <class T, class Fn, class ... ArgTypes>
1632
// struct result_of<(T::*Fn)(ArgTypes...)>
1633
// {
1634
    // typedef decltype( declval<Fn>()(declval<ArgTypes>()...) ) type;
1635
// };
1636
1637
#undef __CV_SPEC
1638
#undef __SPEC_
1639
#undef __CV_SPEC_1
1640
#undef __SPEC_1
1641
#undef __CV_SPEC_2
1642
#undef __SPEC_2
1643
1644
_STLP_END_NAMESPACE
1645
1646
// # else // __GLIBCXX__ && (__GNUC__ >= 4) && !STLPORT
1647
// #  include <tr1/type_traits>
1648
// # endif
1649
1650
#if (_STLP_OUTERMOST_HEADER_ID == 0x3)
1651
#  include <stl/_epilog.h>
1652
#  undef _STLP_OUTERMOST_HEADER_ID
1653
#endif
1654
1655
#endif // __STLP_TYPE_TRAITS