all repos — mgba @ medusa

mGBA Game Boy Advance Emulator

src/third-party/discord-rpc/include/rapidjson/internal/meta.h (view raw)

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