meta.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_INTERNAL_META_H_
16 #define RAPIDJSON_INTERNAL_META_H_
17 
18 #include "../rapidjson.h"
19 
20 #ifdef __GNUC__
21 RAPIDJSON_DIAG_PUSH
22 RAPIDJSON_DIAG_OFF(effc++)
23 #endif
24 
25 #if defined(_MSC_VER) && !defined(__clang__)
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(6334)
28 #endif
29 
30 #if RAPIDJSON_HAS_CXX11_TYPETRAITS
31 #include <type_traits>
32 #endif
33 
34 //@cond RAPIDJSON_INTERNAL
36 namespace internal {
37 
38 // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
39 template <typename T> struct Void { typedef void Type; };
40 
41 ///////////////////////////////////////////////////////////////////////////////
42 // BoolType, TrueType, FalseType
43 //
44 template <bool Cond> struct BoolType {
45  static const bool Value = Cond;
46  typedef BoolType Type;
47 };
48 typedef BoolType<true> TrueType;
49 typedef BoolType<false> FalseType;
50 
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
54 //
55 
56 template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
57 template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
58 template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
59 template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
60 
61 template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
62 template <> struct AndExprCond<true, true> : TrueType {};
63 template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
64 template <> struct OrExprCond<false, false> : FalseType {};
65 
66 template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
67 template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
68 template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
69 template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
70 
71 
72 ///////////////////////////////////////////////////////////////////////////////
73 // AddConst, MaybeAddConst, RemoveConst
74 template <typename T> struct AddConst { typedef const T Type; };
75 template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
76 template <typename T> struct RemoveConst { typedef T Type; };
77 template <typename T> struct RemoveConst<const T> { typedef T Type; };
78 
79 
80 ///////////////////////////////////////////////////////////////////////////////
81 // IsSame, IsConst, IsMoreConst, IsPointer
82 //
83 template <typename T, typename U> struct IsSame : FalseType {};
84 template <typename T> struct IsSame<T, T> : TrueType {};
85 
86 template <typename T> struct IsConst : FalseType {};
87 template <typename T> struct IsConst<const T> : TrueType {};
88 
89 template <typename CT, typename T>
90 struct IsMoreConst
91  : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
92  BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
93 
94 template <typename T> struct IsPointer : FalseType {};
95 template <typename T> struct IsPointer<T*> : TrueType {};
96 
97 ///////////////////////////////////////////////////////////////////////////////
98 // IsBaseOf
99 //
100 #if RAPIDJSON_HAS_CXX11_TYPETRAITS
101 
102 template <typename B, typename D> struct IsBaseOf
103  : BoolType< ::std::is_base_of<B,D>::value> {};
104 
105 #else // simplified version adopted from Boost
106 
107 template<typename B, typename D> struct IsBaseOfImpl {
108  RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
109  RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
110 
111  typedef char (&Yes)[1];
112  typedef char (&No) [2];
113 
114  template <typename T>
115  static Yes Check(const D*, T);
116  static No Check(const B*, int);
117 
118  struct Host {
119  operator const B*() const;
120  operator const D*();
121  };
122 
123  enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
124 };
125 
126 template <typename B, typename D> struct IsBaseOf
127  : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
128 
129 #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
130 
131 
132 //////////////////////////////////////////////////////////////////////////
133 // EnableIf / DisableIf
134 //
135 template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
136 template <typename T> struct EnableIfCond<false, T> { /* empty */ };
137 
138 template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
139 template <typename T> struct DisableIfCond<true, T> { /* empty */ };
140 
141 template <typename Condition, typename T = void>
142 struct EnableIf : EnableIfCond<Condition::Value, T> {};
143 
144 template <typename Condition, typename T = void>
145 struct DisableIf : DisableIfCond<Condition::Value, T> {};
146 
147 // SFINAE helpers
148 struct SfinaeTag {};
149 template <typename T> struct RemoveSfinaeTag;
150 template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
151 
152 #define RAPIDJSON_REMOVEFPTR_(type) \
153  typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
154  < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
155 
156 #define RAPIDJSON_ENABLEIF(cond) \
157  typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
158  <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
159 
160 #define RAPIDJSON_DISABLEIF(cond) \
161  typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
162  <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
163 
164 #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
165  typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
166  <RAPIDJSON_REMOVEFPTR_(cond), \
167  RAPIDJSON_REMOVEFPTR_(returntype)>::Type
168 
169 #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
170  typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
171  <RAPIDJSON_REMOVEFPTR_(cond), \
172  RAPIDJSON_REMOVEFPTR_(returntype)>::Type
173 
174 } // namespace internal
176 //@endcond
177 
178 #if defined(_MSC_VER) && !defined(__clang__)
179 RAPIDJSON_DIAG_POP
180 #endif
181 
182 #ifdef __GNUC__
183 RAPIDJSON_DIAG_POP
184 #endif
185 
186 #endif // RAPIDJSON_INTERNAL_META_H_
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:445
Definition: 013_class.h:14
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
Definition: 013_class.h:10
Type
Type of JSON value.
Definition: rapidjson.h:618