123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // Tencent is pleased to support the open source community by making RapidJSON available.
- //
- // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
- //
- // Licensed under the MIT License (the "License"); you may not use this file except
- // in compliance with the License. You may obtain a copy of the License at
- //
- // http://opensource.org/licenses/MIT
- //
- // Unless required by applicable law or agreed to in writing, software distributed
- // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- // CONDITIONS OF ANY KIND, either express or implied. See the License for the
- // specific language governing permissions and limitations under the License.
- #ifndef RAPIDJSON_INTERNAL_META_H_
- #define RAPIDJSON_INTERNAL_META_H_
- #include "../rapidjson.h"
- #ifdef __GNUC__
- RAPIDJSON_DIAG_PUSH
- RAPIDJSON_DIAG_OFF(effc++)
- #endif
- #if defined(_MSC_VER)
- RAPIDJSON_DIAG_PUSH
- RAPIDJSON_DIAG_OFF(6334)
- #endif
- #if RAPIDJSON_HAS_CXX11_TYPETRAITS
- #include <type_traits>
- #endif
- //@cond RAPIDJSON_INTERNAL
- RAPIDJSON_NAMESPACE_BEGIN
- namespace internal {
- // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
- template <typename T> struct Void { typedef void Type; };
- ///////////////////////////////////////////////////////////////////////////////
- // BoolType, TrueType, FalseType
- //
- template <bool Cond> struct BoolType {
- static const bool Value = Cond;
- typedef BoolType Type;
- };
- typedef BoolType<true> TrueType;
- typedef BoolType<false> FalseType;
- ///////////////////////////////////////////////////////////////////////////////
- // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
- //
- template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
- template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
- template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
- template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
- template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
- template <> struct AndExprCond<true, true> : TrueType {};
- template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
- template <> struct OrExprCond<false, false> : FalseType {};
- template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
- template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
- template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
- template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
- ///////////////////////////////////////////////////////////////////////////////
- // AddConst, MaybeAddConst, RemoveConst
- template <typename T> struct AddConst { typedef const T Type; };
- template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
- template <typename T> struct RemoveConst { typedef T Type; };
- template <typename T> struct RemoveConst<const T> { typedef T Type; };
- ///////////////////////////////////////////////////////////////////////////////
- // IsSame, IsConst, IsMoreConst, IsPointer
- //
- template <typename T, typename U> struct IsSame : FalseType {};
- template <typename T> struct IsSame<T, T> : TrueType {};
- template <typename T> struct IsConst : FalseType {};
- template <typename T> struct IsConst<const T> : TrueType {};
- template <typename CT, typename T>
- struct IsMoreConst
- : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
- BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
- template <typename T> struct IsPointer : FalseType {};
- template <typename T> struct IsPointer<T*> : TrueType {};
- ///////////////////////////////////////////////////////////////////////////////
- // IsBaseOf
- //
- #if RAPIDJSON_HAS_CXX11_TYPETRAITS
- template <typename B, typename D> struct IsBaseOf
- : BoolType< ::std::is_base_of<B,D>::value> {};
- #else // simplified version adopted from Boost
- template<typename B, typename D> struct IsBaseOfImpl {
- RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
- RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
- typedef char (&Yes)[1];
- typedef char (&No) [2];
- template <typename T>
- static Yes Check(const D*, T);
- static No Check(const B*, int);
- struct Host {
- operator const B*() const;
- operator const D*();
- };
- enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
- };
- template <typename B, typename D> struct IsBaseOf
- : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
- #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
- //////////////////////////////////////////////////////////////////////////
- // EnableIf / DisableIf
- //
- template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
- template <typename T> struct EnableIfCond<false, T> { /* empty */ };
- template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
- template <typename T> struct DisableIfCond<true, T> { /* empty */ };
- template <typename Condition, typename T = void>
- struct EnableIf : EnableIfCond<Condition::Value, T> {};
- template <typename Condition, typename T = void>
- struct DisableIf : DisableIfCond<Condition::Value, T> {};
- // SFINAE helpers
- struct SfinaeTag {};
- template <typename T> struct RemoveSfinaeTag;
- template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
- #define RAPIDJSON_REMOVEFPTR_(type) \
- typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
- < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
- #define RAPIDJSON_ENABLEIF(cond) \
- typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
- <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
- #define RAPIDJSON_DISABLEIF(cond) \
- typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
- <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
- #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
- typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
- <RAPIDJSON_REMOVEFPTR_(cond), \
- RAPIDJSON_REMOVEFPTR_(returntype)>::Type
- #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
- typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
- <RAPIDJSON_REMOVEFPTR_(cond), \
- RAPIDJSON_REMOVEFPTR_(returntype)>::Type
- } // namespace internal
- RAPIDJSON_NAMESPACE_END
- //@endcond
- #if defined(__GNUC__) || defined(_MSC_VER)
- RAPIDJSON_DIAG_POP
- #endif
- #endif // RAPIDJSON_INTERNAL_META_H_
|