LibreOffice Module onlineupdate (master) 1
TypeTraits.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/* Template-based metaprogramming and type-testing facilities. */
8
9#ifndef mozilla_TypeTraits_h
10#define mozilla_TypeTraits_h
11
12#include "Types.h"
13
14/*
15 * These traits are approximate copies of the traits and semantics from C++11's
16 * <type_traits> header. Don't add traits not in that header! When all
17 * platforms provide that header, we can convert all users and remove this one.
18 */
19
20#include <wchar.h>
21
22namespace mozilla {
23
24/* Forward declarations. */
25
26template<typename> struct RemoveCV;
27
28/* 20.9.3 Helper classes [meta.help] */
29
34template<typename T, T Value>
36{
37 static const T value = Value;
38 typedef T ValueType;
40};
41
45
46/* 20.9.4 Unary type traits [meta.unary] */
47
48/* 20.9.4.1 Primary type categories [meta.unary.cat] */
49
50namespace detail {
51
52template<typename T>
54
55template<>
56struct IsVoidHelper<void> : TrueType {};
57
58} // namespace detail
59
68template<typename T>
69struct IsVoid : detail::IsVoidHelper<typename RemoveCV<T>::Type> {};
70
71namespace detail {
72
73template <typename T>
75
76template<> struct IsIntegralHelper<char> : TrueType {};
77template<> struct IsIntegralHelper<signed char> : TrueType {};
78template<> struct IsIntegralHelper<unsigned char> : TrueType {};
79template<> struct IsIntegralHelper<short> : TrueType {};
80template<> struct IsIntegralHelper<unsigned short> : TrueType {};
81template<> struct IsIntegralHelper<int> : TrueType {};
82template<> struct IsIntegralHelper<unsigned int> : TrueType {};
83template<> struct IsIntegralHelper<long> : TrueType {};
84template<> struct IsIntegralHelper<unsigned long> : TrueType {};
85template<> struct IsIntegralHelper<long long> : TrueType {};
86template<> struct IsIntegralHelper<unsigned long long> : TrueType {};
87template<> struct IsIntegralHelper<bool> : TrueType {};
88template<> struct IsIntegralHelper<wchar_t> : TrueType {};
89#ifdef MOZ_CHAR16_IS_NOT_WCHAR
90template<> struct IsIntegralHelper<char16_t> : TrueType {};
91#endif
92
93} /* namespace detail */
94
107template<typename T>
108struct IsIntegral : detail::IsIntegralHelper<typename RemoveCV<T>::Type>
109{};
110
111template<typename T, typename U>
112struct IsSame;
113
114namespace detail {
115
116template<typename T>
118 : IntegralConstant<bool,
119 IsSame<T, float>::value ||
120 IsSame<T, double>::value ||
121 IsSame<T, long double>::value>
122{};
123
124} // namespace detail
125
135template<typename T>
137 : detail::IsFloatingPointHelper<typename RemoveCV<T>::Type>
138{};
139
140namespace detail {
141
142template<typename T>
144
145template<typename T, decltype(sizeof(1)) N>
146struct IsArrayHelper<T[N]> : TrueType {};
147
148template<typename T>
149struct IsArrayHelper<T[]> : TrueType {};
150
151} // namespace detail
152
161template<typename T>
162struct IsArray : detail::IsArrayHelper<typename RemoveCV<T>::Type>
163{};
164
165namespace detail {
166
167template<typename T>
169
170template<typename T>
171struct IsPointerHelper<T*> : TrueType {};
172
173} // namespace detail
174
190template<typename T>
191struct IsPointer : detail::IsPointerHelper<typename RemoveCV<T>::Type>
192{};
193
205template<typename T>
207
208template<typename T>
210
222template<typename T>
224
225template<typename T>
227
228namespace detail {
229
230// __is_enum is a supported extension across all of our supported compilers.
231template<typename T>
233 : IntegralConstant<bool, __is_enum(T)>
234{};
235
236} // namespace detail
237
245template<typename T>
246struct IsEnum
247 : detail::IsEnumHelper<typename RemoveCV<T>::Type>
248{};
249
250namespace detail {
251
252// __is_class is a supported extension across all of our supported compilers:
253// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html
254// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits
255// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx
256template<typename T>
258 : IntegralConstant<bool, __is_class(T)>
259{};
260
261} // namespace detail
262
272template<typename T>
274 : detail::IsClassHelper<typename RemoveCV<T>::Type>
275{};
276
277/* 20.9.4.2 Composite type traits [meta.unary.comp] */
278
293template<typename T>
295 : IntegralConstant<bool,
296 IsLvalueReference<T>::value || IsRvalueReference<T>::value>
297{};
298
307template<typename T>
309 : IntegralConstant<bool, IsIntegral<T>::value || IsFloatingPoint<T>::value>
310{};
311
312/* 20.9.4.3 Type properties [meta.unary.prop] */
313
321template<typename T>
322struct IsConst : FalseType {};
323
324template<typename T>
325struct IsConst<const T> : TrueType {};
326
334template<typename T>
336
337template<typename T>
338struct IsVolatile<volatile T> : TrueType {};
339
348template<typename T>
349struct IsPod : public FalseType {};
350
351template<> struct IsPod<char> : TrueType {};
352template<> struct IsPod<signed char> : TrueType {};
353template<> struct IsPod<unsigned char> : TrueType {};
354template<> struct IsPod<short> : TrueType {};
355template<> struct IsPod<unsigned short> : TrueType {};
356template<> struct IsPod<int> : TrueType {};
357template<> struct IsPod<unsigned int> : TrueType {};
358template<> struct IsPod<long> : TrueType {};
359template<> struct IsPod<unsigned long> : TrueType {};
360template<> struct IsPod<long long> : TrueType {};
361template<> struct IsPod<unsigned long long> : TrueType {};
362template<> struct IsPod<bool> : TrueType {};
363template<> struct IsPod<float> : TrueType {};
364template<> struct IsPod<double> : TrueType {};
365template<> struct IsPod<wchar_t> : TrueType {};
366#ifdef MOZ_CHAR16_IS_NOT_WCHAR
367template<> struct IsPod<char16_t> : TrueType {};
368#endif
369template<typename T> struct IsPod<T*> : TrueType {};
370
371namespace detail {
372
373// __is_empty is a supported extension across all of our supported compilers:
374// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html
375// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits
376// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx
377template<typename T>
379 : IntegralConstant<bool, IsClass<T>::value && __is_empty(T)>
380{};
381
382} // namespace detail
383
424template<typename T>
425struct IsEmpty : detail::IsEmptyHelper<typename RemoveCV<T>::Type>
426{};
427
428
429namespace detail {
430
431template<typename T,
434 typename NoCV = typename RemoveCV<T>::Type>
436
437// Floating point is signed.
438template<typename T, typename NoCV>
439struct IsSignedHelper<T, true, false, NoCV> : TrueType {};
440
441// Integral is conditionally signed.
442template<typename T, typename NoCV>
443struct IsSignedHelper<T, false, true, NoCV>
444 : IntegralConstant<bool, bool(NoCV(-1) < NoCV(1))>
445{};
446
447// Non-floating point, non-integral is not signed.
448template<typename T, typename NoCV>
449struct IsSignedHelper<T, false, false, NoCV> : FalseType {};
450
451} // namespace detail
452
462template<typename T>
463struct IsSigned : detail::IsSignedHelper<T> {};
464
465namespace detail {
466
467template<typename T,
468 bool = IsFloatingPoint<T>::value,
469 bool = IsIntegral<T>::value,
470 typename NoCV = typename RemoveCV<T>::Type>
471struct IsUnsignedHelper;
472
473// Floating point is not unsigned.
474template<typename T, typename NoCV>
475struct IsUnsignedHelper<T, true, false, NoCV> : FalseType {};
476
477// Integral is conditionally unsigned.
478template<typename T, typename NoCV>
479struct IsUnsignedHelper<T, false, true, NoCV>
480 : IntegralConstant<bool,
481 (IsSame<NoCV, bool>::value || bool(NoCV(1) < NoCV(-1)))>
482{};
483
484// Non-floating point, non-integral is not unsigned.
485template<typename T, typename NoCV>
486struct IsUnsignedHelper<T, false, false, NoCV> : FalseType {};
487
488} // namespace detail
489
498template<typename T>
499struct IsUnsigned : detail::IsUnsignedHelper<T> {};
500
501/* 20.9.5 Type property queries [meta.unary.prop.query] */
502
503/* 20.9.6 Relationships between types [meta.rel] */
504
515template<typename T, typename U>
516struct IsSame : FalseType {};
517
518template<typename T>
519struct IsSame<T, T> : TrueType {};
520
521namespace detail {
522
523#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
524
525template<class Base, class Derived>
526struct BaseOfTester : IntegralConstant<bool, __is_base_of(Base, Derived)> {};
527
528#else
529
530// The trickery used to implement IsBaseOf here makes it possible to use it for
531// the cases of private and multiple inheritance. This code was inspired by the
532// sample code here:
533//
534// http://stackoverflow.com/questions/2910979/how-is-base-of-works
535template<class Base, class Derived>
536struct BaseOfHelper
537{
538public:
539 operator Base*() const;
540 operator Derived*();
541};
542
543template<class Base, class Derived>
544struct BaseOfTester
545{
546private:
547 template<class T>
548 static char test(Derived*, T);
549 static int test(Base*, int);
550
551public:
552 static const bool value =
553 sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
554};
555
556template<class Base, class Derived>
557struct BaseOfTester<Base, const Derived>
558{
559private:
560 template<class T>
561 static char test(Derived*, T);
562 static int test(Base*, int);
563
564public:
565 static const bool value =
566 sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
567};
568
569template<class Base, class Derived>
570struct BaseOfTester<Base&, Derived&> : FalseType {};
571
572template<class Type>
573struct BaseOfTester<Type, Type> : TrueType {};
574
575template<class Type>
576struct BaseOfTester<Type, const Type> : TrueType {};
577
578#endif
579
580} /* namespace detail */
581
582/*
583 * IsBaseOf allows to know whether a given class is derived from another.
584 *
585 * Consider the following class definitions:
586 *
587 * class A {};
588 * class B : public A {};
589 * class C {};
590 *
591 * mozilla::IsBaseOf<A, B>::value is true;
592 * mozilla::IsBaseOf<A, C>::value is false;
593 */
594template<class Base, class Derived>
595struct IsBaseOf
596 : IntegralConstant<bool, detail::BaseOfTester<Base, Derived>::value>
597{};
598
599namespace detail {
600
601template<typename From, typename To>
602struct ConvertibleTester
603{
604private:
605 static From create();
606
607 template<typename From1, typename To1>
608 static char test(To to);
609
610 template<typename From1, typename To1>
611 static int test(...);
612
613public:
614 static const bool value =
615 sizeof(test<From, To>(create())) == sizeof(char);
616};
617
618} // namespace detail
619
645template<typename From, typename To>
646struct IsConvertible
647 : IntegralConstant<bool, detail::ConvertibleTester<From, To>::value>
648{};
649
650template<typename B>
651struct IsConvertible<void, B>
652 : IntegralConstant<bool, IsVoid<B>::value>
653{};
654
655template<typename A>
656struct IsConvertible<A, void>
657 : IntegralConstant<bool, IsVoid<A>::value>
658{};
659
660template<>
661struct IsConvertible<void, void>
662 : TrueType
663{};
664
665/* 20.9.7 Transformations between types [meta.trans] */
666
667/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */
668
677template<typename T>
678struct RemoveConst
679{
680 typedef T Type;
681};
682
683template<typename T>
684struct RemoveConst<const T>
685{
686 typedef T Type;
687};
688
697template<typename T>
698struct RemoveVolatile
699{
700 typedef T Type;
701};
702
703template<typename T>
704struct RemoveVolatile<volatile T>
705{
706 typedef T Type;
707};
708
717template<typename T>
718struct RemoveCV
719{
720 typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type;
721};
722
723/* 20.9.7.2 Reference modifications [meta.trans.ref] */
724
733template<typename T>
734struct RemoveReference
735{
736 typedef T Type;
737};
738
739template<typename T>
740struct RemoveReference<T&>
741{
742 typedef T Type;
743};
744
745template<typename T>
746struct RemoveReference<T&&>
747{
748 typedef T Type;
749};
750
751template<bool Condition, typename A, typename B>
752struct Conditional;
753
754namespace detail {
755
756enum Voidness { TIsVoid, TIsNotVoid };
757
758template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid>
759struct AddLvalueReferenceHelper;
760
761template<typename T>
762struct AddLvalueReferenceHelper<T, TIsVoid>
763{
764 typedef void Type;
765};
766
767template<typename T>
768struct AddLvalueReferenceHelper<T, TIsNotVoid>
769{
770 typedef T& Type;
771};
772
773} // namespace detail
774
789template<typename T>
790struct AddLvalueReference
791 : detail::AddLvalueReferenceHelper<T>
792{};
793
794namespace detail {
795
796template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid>
797struct AddRvalueReferenceHelper;
798
799template<typename T>
800struct AddRvalueReferenceHelper<T, TIsVoid>
801{
802 typedef void Type;
803};
804
805template<typename T>
806struct AddRvalueReferenceHelper<T, TIsNotVoid>
807{
808 typedef T&& Type;
809};
810
811} // namespace detail
812
828template<typename T>
829struct AddRvalueReference
830 : detail::AddRvalueReferenceHelper<T>
831{};
832
833/* 20.2.4 Function template declval [declval] */
834
841template<typename T>
842typename AddRvalueReference<T>::Type DeclVal();
843
844/* 20.9.7.3 Sign modifications [meta.trans.sign] */
845
846template<bool B, typename T = void>
847struct EnableIf;
848
849namespace detail {
850
851template<bool MakeConst, typename T>
852struct WithC : Conditional<MakeConst, const T, T>
853{};
854
855template<bool MakeVolatile, typename T>
856struct WithV : Conditional<MakeVolatile, volatile T, T>
857{};
858
859
860template<bool MakeConst, bool MakeVolatile, typename T>
861struct WithCV : WithC<MakeConst, typename WithV<MakeVolatile, T>::Type>
862{};
863
864template<typename T>
865struct CorrespondingSigned;
866
867template<>
868struct CorrespondingSigned<char> { typedef signed char Type; };
869template<>
870struct CorrespondingSigned<unsigned char> { typedef signed char Type; };
871template<>
872struct CorrespondingSigned<unsigned short> { typedef short Type; };
873template<>
874struct CorrespondingSigned<unsigned int> { typedef int Type; };
875template<>
876struct CorrespondingSigned<unsigned long> { typedef long Type; };
877template<>
878struct CorrespondingSigned<unsigned long long> { typedef long long Type; };
879
880template<typename T,
881 typename CVRemoved = typename RemoveCV<T>::Type,
882 bool IsSignedIntegerType = IsSigned<CVRemoved>::value &&
883 !IsSame<char, CVRemoved>::value>
884struct MakeSigned;
885
886template<typename T, typename CVRemoved>
887struct MakeSigned<T, CVRemoved, true>
888{
889 typedef T Type;
890};
891
892template<typename T, typename CVRemoved>
893struct MakeSigned<T, CVRemoved, false>
894 : WithCV<IsConst<T>::value, IsVolatile<T>::value,
895 typename CorrespondingSigned<CVRemoved>::Type>
896{};
897
898} // namespace detail
899
922template<typename T>
923struct MakeSigned
924 : EnableIf<IsIntegral<T>::value &&
925 !IsSame<bool, typename RemoveCV<T>::Type>::value,
926 typename detail::MakeSigned<T>
927 >::Type
928{};
929
930namespace detail {
931
932template<typename T>
933struct CorrespondingUnsigned;
934
935template<>
936struct CorrespondingUnsigned<char> { typedef unsigned char Type; };
937template<>
938struct CorrespondingUnsigned<signed char> { typedef unsigned char Type; };
939template<>
940struct CorrespondingUnsigned<short> { typedef unsigned short Type; };
941template<>
942struct CorrespondingUnsigned<int> { typedef unsigned int Type; };
943template<>
944struct CorrespondingUnsigned<long> { typedef unsigned long Type; };
945template<>
946struct CorrespondingUnsigned<long long> { typedef unsigned long long Type; };
947
948
949template<typename T,
950 typename CVRemoved = typename RemoveCV<T>::Type,
951 bool IsUnsignedIntegerType = IsUnsigned<CVRemoved>::value &&
952 !IsSame<char, CVRemoved>::value>
953struct MakeUnsigned;
954
955template<typename T, typename CVRemoved>
956struct MakeUnsigned<T, CVRemoved, true>
957{
958 typedef T Type;
959};
960
961template<typename T, typename CVRemoved>
962struct MakeUnsigned<T, CVRemoved, false>
963 : WithCV<IsConst<T>::value, IsVolatile<T>::value,
964 typename CorrespondingUnsigned<CVRemoved>::Type>
965{};
966
967} // namespace detail
968
991template<typename T>
992struct MakeUnsigned
993 : EnableIf<IsIntegral<T>::value &&
994 !IsSame<bool, typename RemoveCV<T>::Type>::value,
995 typename detail::MakeUnsigned<T>
996 >::Type
997{};
998
999/* 20.9.7.4 Array modifications [meta.trans.arr] */
1000
1010template<typename T>
1011struct RemoveExtent
1012{
1013 typedef T Type;
1014};
1015
1016template<typename T>
1017struct RemoveExtent<T[]>
1018{
1019 typedef T Type;
1020};
1021
1022template<typename T, decltype(sizeof(1)) N>
1023struct RemoveExtent<T[N]>
1024{
1025 typedef T Type;
1026};
1027
1028/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */
1029
1030namespace detail {
1031
1032template<typename T, typename CVRemoved>
1033struct RemovePointerHelper
1034{
1035 typedef T Type;
1036};
1037
1038template<typename T, typename Pointee>
1039struct RemovePointerHelper<T, Pointee*>
1040{
1041 typedef Pointee Type;
1042};
1043
1044} // namespace detail
1045
1061template<typename T>
1062struct RemovePointer
1063 : detail::RemovePointerHelper<T, typename RemoveCV<T>::Type>
1064{};
1065
1066/* 20.9.7.6 Other transformations [meta.trans.other] */
1067
1086template<bool B, typename T>
1087struct EnableIf
1088{};
1089
1090template<typename T>
1091struct EnableIf<true, T>
1092{
1093 typedef T Type;
1094};
1095
1102template<bool Condition, typename A, typename B>
1103struct Conditional
1104{
1105 typedef A Type;
1106};
1107
1108template<class A, class B>
1109struct Conditional<false, A, B>
1110{
1111 typedef B Type;
1112};
1113
1114} /* namespace mozilla */
1115
1116#endif /* mozilla_TypeTraits_h */
Value
Compares two VersionParts.
IntegralConstant< bool, true > TrueType
Convenient aliases.
Definition: TypeTraits.h:43
IntegralConstant< bool, false > FalseType
Definition: TypeTraits.h:44
#define N
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
Helper class used as a base for various type traits, exposed publicly because <type_traits> exposes i...
Definition: TypeTraits.h:36
IntegralConstant< T, Value > Type
Definition: TypeTraits.h:39
static const T value
Definition: TypeTraits.h:37
IsArithmetic determines whether a type is arithmetic.
Definition: TypeTraits.h:310
IsArray determines whether a type is an array type, of known or unknown length.
Definition: TypeTraits.h:163
IsClass determines whether a type is a class type (but not a union).
Definition: TypeTraits.h:275
IsConst determines whether a type is const or not.
Definition: TypeTraits.h:322
IsEmpty determines whether a type is a class (but not a union) that is empty.
Definition: TypeTraits.h:426
IsEnum determines whether a type is an enum type.
Definition: TypeTraits.h:248
IsFloatingPoint determines whether a type is a floating point type (float, double,...
Definition: TypeTraits.h:138
IsIntegral determines whether a type is an integral type.
Definition: TypeTraits.h:109
IsLvalueReference determines whether a type is an lvalue reference.
Definition: TypeTraits.h:206
Traits class for identifying POD types.
Definition: TypeTraits.h:349
IsPointer determines whether a type is a possibly-CV-qualified pointer type (but not a pointer-to-mem...
Definition: TypeTraits.h:192
IsReference determines whether a type is an lvalue or rvalue reference.
Definition: TypeTraits.h:297
IsRvalueReference determines whether a type is an rvalue reference.
Definition: TypeTraits.h:223
IsSame tests whether two types are the same type.
Definition: TypeTraits.h:516
IsVoid determines whether a type is void.
Definition: TypeTraits.h:69
IsVolatile determines whether a type is volatile or not.
Definition: TypeTraits.h:335
RemoveConst< typenameRemoveVolatile< T >::Type >::Type Type
Definition: TypeTraits.h:720