meta.h
Engine/source/persistence/rapidjson/internal/meta.h
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