Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:28:08

0001 // Tencent is pleased to support the open source community by making RapidJSON available.
0002 // 
0003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
0004 //
0005 // Licensed under the MIT License (the "License"); you may not use this file except
0006 // in compliance with the License. You may obtain a copy of the License at
0007 //
0008 // http://opensource.org/licenses/MIT
0009 //
0010 // Unless required by applicable law or agreed to in writing, software distributed 
0011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
0012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
0013 // specific language governing permissions and limitations under the License.
0014 
0015 #ifndef RAPIDJSON_INTERNAL_META_H_
0016 #define RAPIDJSON_INTERNAL_META_H_
0017 
0018 #include "../rapidjson.h"
0019 
0020 #ifdef __GNUC__
0021 RAPIDJSON_DIAG_PUSH
0022 RAPIDJSON_DIAG_OFF(effc++)
0023 #endif
0024 
0025 #if defined(_MSC_VER) && !defined(__clang__)
0026 RAPIDJSON_DIAG_PUSH
0027 RAPIDJSON_DIAG_OFF(6334)
0028 #endif
0029 
0030 #if RAPIDJSON_HAS_CXX11_TYPETRAITS
0031 #include <type_traits>
0032 #endif
0033 
0034 //@cond RAPIDJSON_INTERNAL
0035 RAPIDJSON_NAMESPACE_BEGIN
0036 namespace internal {
0037 
0038 // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
0039 template <typename T> struct Void { typedef void Type; };
0040 
0041 ///////////////////////////////////////////////////////////////////////////////
0042 // BoolType, TrueType, FalseType
0043 //
0044 template <bool Cond> struct BoolType {
0045     static const bool Value = Cond;
0046     typedef BoolType Type;
0047 };
0048 typedef BoolType<true> TrueType;
0049 typedef BoolType<false> FalseType;
0050 
0051 
0052 ///////////////////////////////////////////////////////////////////////////////
0053 // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
0054 //
0055 
0056 template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
0057 template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
0058 template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
0059 template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
0060 
0061 template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
0062 template <> struct AndExprCond<true, true> : TrueType {};
0063 template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
0064 template <> struct OrExprCond<false, false> : FalseType {};
0065 
0066 template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
0067 template <typename C> struct NotExpr  : SelectIf<C,FalseType,TrueType>::Type {};
0068 template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
0069 template <typename C1, typename C2> struct OrExpr  : OrExprCond<C1::Value, C2::Value>::Type {};
0070 
0071 
0072 ///////////////////////////////////////////////////////////////////////////////
0073 // AddConst, MaybeAddConst, RemoveConst
0074 template <typename T> struct AddConst { typedef const T Type; };
0075 template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
0076 template <typename T> struct RemoveConst { typedef T Type; };
0077 template <typename T> struct RemoveConst<const T> { typedef T Type; };
0078 
0079 
0080 ///////////////////////////////////////////////////////////////////////////////
0081 // IsSame, IsConst, IsMoreConst, IsPointer
0082 //
0083 template <typename T, typename U> struct IsSame : FalseType {};
0084 template <typename T> struct IsSame<T, T> : TrueType {};
0085 
0086 template <typename T> struct IsConst : FalseType {};
0087 template <typename T> struct IsConst<const T> : TrueType {};
0088 
0089 template <typename CT, typename T>
0090 struct IsMoreConst
0091     : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
0092               BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
0093 
0094 template <typename T> struct IsPointer : FalseType {};
0095 template <typename T> struct IsPointer<T*> : TrueType {};
0096 
0097 ///////////////////////////////////////////////////////////////////////////////
0098 // IsBaseOf
0099 //
0100 #if RAPIDJSON_HAS_CXX11_TYPETRAITS
0101 
0102 template <typename B, typename D> struct IsBaseOf
0103     : BoolType< ::std::is_base_of<B,D>::value> {};
0104 
0105 #else // simplified version adopted from Boost
0106 
0107 template<typename B, typename D> struct IsBaseOfImpl {
0108     RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
0109     RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
0110 
0111     typedef char (&Yes)[1];
0112     typedef char (&No) [2];
0113 
0114     template <typename T>
0115     static Yes Check(const D*, T);
0116     static No  Check(const B*, int);
0117 
0118     struct Host {
0119         operator const B*() const;
0120         operator const D*();
0121     };
0122 
0123     enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
0124 };
0125 
0126 template <typename B, typename D> struct IsBaseOf
0127     : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
0128 
0129 #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
0130 
0131 
0132 //////////////////////////////////////////////////////////////////////////
0133 // EnableIf / DisableIf
0134 //
0135 template <bool Condition, typename T = void> struct EnableIfCond  { typedef T Type; };
0136 template <typename T> struct EnableIfCond<false, T> { /* empty */ };
0137 
0138 template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
0139 template <typename T> struct DisableIfCond<true, T> { /* empty */ };
0140 
0141 template <typename Condition, typename T = void>
0142 struct EnableIf : EnableIfCond<Condition::Value, T> {};
0143 
0144 template <typename Condition, typename T = void>
0145 struct DisableIf : DisableIfCond<Condition::Value, T> {};
0146 
0147 // SFINAE helpers
0148 struct SfinaeTag {};
0149 template <typename T> struct RemoveSfinaeTag;
0150 template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
0151 
0152 #define RAPIDJSON_REMOVEFPTR_(type) \
0153     typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
0154         < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
0155 
0156 #define RAPIDJSON_ENABLEIF(cond) \
0157     typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
0158         <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
0159 
0160 #define RAPIDJSON_DISABLEIF(cond) \
0161     typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
0162         <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
0163 
0164 #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
0165     typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
0166         <RAPIDJSON_REMOVEFPTR_(cond), \
0167          RAPIDJSON_REMOVEFPTR_(returntype)>::Type
0168 
0169 #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
0170     typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
0171         <RAPIDJSON_REMOVEFPTR_(cond), \
0172          RAPIDJSON_REMOVEFPTR_(returntype)>::Type
0173 
0174 } // namespace internal
0175 RAPIDJSON_NAMESPACE_END
0176 //@endcond
0177 
0178 #if defined(_MSC_VER) && !defined(__clang__)
0179 RAPIDJSON_DIAG_POP
0180 #endif
0181 
0182 #ifdef __GNUC__
0183 RAPIDJSON_DIAG_POP
0184 #endif
0185 
0186 #endif // RAPIDJSON_INTERNAL_META_H_