1
// Copyright (C) 2011 Milo Yip
3
// Permission is hereby granted, free of charge, to any person obtaining a copy
4
// of this software and associated documentation files (the "Software"), to deal
5
// in the Software without restriction, including without limitation the rights
6
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
// copies of the Software, and to permit persons to whom the Software is
8
// furnished to do so, subject to the following conditions:
10
// The above copyright notice and this permission notice shall be included in
11
// all copies or substantial portions of the Software.
13
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
#ifndef RAPIDJSON_INTERNAL_META_H_
22
#define RAPIDJSON_INTERNAL_META_H_
24
#ifndef RAPIDJSON_RAPIDJSON_H_
25
#error <rapidjson.h> not yet included. Do not include this file directly.
30
RAPIDJSON_DIAG_OFF(effc++)
34
RAPIDJSON_DIAG_OFF(6334)
37
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
38
#include <type_traits>
41
//@cond RAPIDJSON_INTERNAL
42
RAPIDJSON_NAMESPACE_BEGIN
45
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
46
template <typename T> struct Void { typedef void Type; };
48
///////////////////////////////////////////////////////////////////////////////
49
// BoolType, TrueType, FalseType
51
template <bool Cond> struct BoolType {
52
static const bool Value = Cond;
53
typedef BoolType Type;
55
typedef BoolType<true> TrueType;
56
typedef BoolType<false> FalseType;
59
///////////////////////////////////////////////////////////////////////////////
60
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
63
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
64
template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
65
template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
66
template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
68
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
69
template <> struct AndExprCond<true, true> : TrueType {};
70
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
71
template <> struct OrExprCond<false, false> : FalseType {};
73
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
74
template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
75
template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
76
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
79
///////////////////////////////////////////////////////////////////////////////
80
// AddConst, MaybeAddConst, RemoveConst
81
template <typename T> struct AddConst { typedef const T Type; };
82
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
83
template <typename T> struct RemoveConst { typedef T Type; };
84
template <typename T> struct RemoveConst<const T> { typedef T Type; };
87
///////////////////////////////////////////////////////////////////////////////
88
// IsSame, IsConst, IsMoreConst, IsPointer
90
template <typename T, typename U> struct IsSame : FalseType {};
91
template <typename T> struct IsSame<T, T> : TrueType {};
93
template <typename T> struct IsConst : FalseType {};
94
template <typename T> struct IsConst<const T> : TrueType {};
96
template <typename CT, typename T>
98
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
99
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
101
template <typename T> struct IsPointer : FalseType {};
102
template <typename T> struct IsPointer<T*> : TrueType {};
104
///////////////////////////////////////////////////////////////////////////////
107
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
109
template <typename B, typename D> struct IsBaseOf
110
: BoolType< ::std::is_base_of<B,D>::value> {};
112
#else // simplified version adopted from Boost
114
template<typename B, typename D> struct IsBaseOfImpl {
115
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
116
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
118
typedef char (&Yes)[1];
119
typedef char (&No) [2];
121
template <typename T>
122
static Yes Check(const D*, T);
123
static No Check(const B*, int);
126
operator const B*() const;
130
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
133
template <typename B, typename D> struct IsBaseOf
134
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
136
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
139
//////////////////////////////////////////////////////////////////////////
140
// EnableIf / DisableIf
142
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
143
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
145
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
146
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
148
template <typename Condition, typename T = void>
149
struct EnableIf : EnableIfCond<Condition::Value, T> {};
151
template <typename Condition, typename T = void>
152
struct DisableIf : DisableIfCond<Condition::Value, T> {};
156
template <typename T> struct RemoveSfinaeTag;
157
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
159
#define RAPIDJSON_REMOVEFPTR_(type) \
160
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
161
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
163
#define RAPIDJSON_ENABLEIF(cond) \
164
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
165
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
167
#define RAPIDJSON_DISABLEIF(cond) \
168
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
169
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
171
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
172
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
173
<RAPIDJSON_REMOVEFPTR_(cond), \
174
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
176
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
177
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
178
<RAPIDJSON_REMOVEFPTR_(cond), \
179
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
181
} // namespace internal
182
RAPIDJSON_NAMESPACE_END
185
#if defined(__GNUC__) || defined(_MSC_VER)
189
#endif // RAPIDJSON_INTERNAL_META_H_