File indexing completed on 2025-12-16 10:28:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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
0035 RAPIDJSON_NAMESPACE_BEGIN
0036 namespace internal {
0037
0038
0039 template <typename T> struct Void { typedef void Type; };
0040
0041
0042
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
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
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
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
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
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
0130
0131
0132
0133
0134
0135 template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
0136 template <typename T> struct EnableIfCond<false, T> { };
0137
0138 template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
0139 template <typename T> struct DisableIfCond<true, T> { };
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
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 }
0175 RAPIDJSON_NAMESPACE_END
0176
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