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