meta.h

Engine/source/persistence/rapidjson/internal/meta.h

More...

Detailed Description

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