123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- // 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) && !defined(__clang__)
- 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(_MSC_VER) && !defined(__clang__)
- RAPIDJSON_DIAG_POP
- #endif
- #ifdef __GNUC__
- RAPIDJSON_DIAG_POP
- #endif
- #endif // RAPIDJSON_INTERNAL_META_H_
|