Last active
December 17, 2015 05:48
-
-
Save urasandesu/5560100 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#ifndef URASANDESU_SWATHE_METADATA_SIGNATURE_H | |
#include <Urasandesu/Swathe/Metadata/Signature.h> | |
#endif | |
#ifndef URASANDESU_SWATHE_METADATA_IMETHOD_H | |
#include <Urasandesu/Swathe/Metadata/IMethod.h> | |
#endif | |
#ifndef URASANDESU_SWATHE_METADATA_ITYPE_H | |
#include <Urasandesu/Swathe/Metadata/IType.h> | |
#endif | |
namespace Urasandesu { namespace Swathe { namespace Metadata { | |
namespace SignatureDetail { | |
using boost::mpl::and_; | |
typedef boost::mpl::bool_<false> False; | |
template<class SignatureHolder, class HasGetSignature> | |
struct PutImplForSpecializedGetter | |
{ | |
static void Put(SimpleBlob &sb, SignatureHolder const &sigHolder) | |
{ | |
sb.Put<COR_SIGNATURE>(SignatureHolder::GetSignature(sigHolder)); | |
} | |
}; | |
template<class T> | |
struct PutImplForSpecializedGetter<T, False> | |
{ | |
static void Put(SimpleBlob &sb, T const &v) | |
{ | |
sb.Put<COR_SIGNATURE>(v); | |
} | |
}; | |
template<class SignatureHolder, class IsSequence> | |
struct PutImplForSequenceDispensing | |
{ | |
static void Put(SimpleBlob &sb, SignatureHolder const &sigs) | |
{ | |
typedef PutImplForPointerDispensing<typename SignatureHolder::value_type> Impl; | |
for (auto i = sigs.begin(), i_end = sigs.end(); i != i_end; ++i) | |
Impl::Put(sb, *i); | |
} | |
}; | |
template<class SignatureHolder> | |
struct PutImplForSequenceDispensing<SignatureHolder, False> | |
{ | |
CPP_ANONYM_DECLARE_HAS_STATIC_MEMBER_FUNCTION(GetSignature, GetSignature, COR_SIGNATURE, (SignatureHolder const &v)); | |
static void Put(SimpleBlob &sb, SignatureHolder const &sigHolder) | |
{ | |
typedef CPP_ANONYM_HAS_STATIC_MEMBER_FUNCTION(GetSignature, SignatureHolder)::type HasGetSignature; | |
typedef PutImplForSpecializedGetter<SignatureHolder, HasGetSignature> Impl; | |
Impl::Put(sb, sigHolder); | |
} | |
}; | |
CPP_ANONYM_DECLARE_HAS_MEMBER_TYPE(PutterHasIterator, iterator); | |
CPP_ANONYM_DECLARE_HAS_MEMBER_TYPE(PutterHasValueType, value_type); | |
template<class SignatureHolder> | |
struct PutImplForPointerDispensing | |
{ | |
static void Put(SimpleBlob &sb, SignatureHolder const &sigHolder) | |
{ | |
typedef CPP_ANONYM_HAS_MEMBER_TYPE(PutterHasIterator, SignatureHolder)::type HasIterator; | |
typedef CPP_ANONYM_HAS_MEMBER_TYPE(PutterHasValueType, SignatureHolder)::type HasValueType; | |
typedef and_<HasIterator, HasValueType>::type IsSequence; | |
typedef PutImplForSequenceDispensing<SignatureHolder, IsSequence> Impl; | |
Impl::Put(sb, sigHolder); | |
} | |
}; | |
template<class SignatureHolder> | |
struct PutImplForPointerDispensing<SignatureHolder *> | |
{ | |
static void Put(SimpleBlob &sb, SignatureHolder const *pSigHolder) | |
{ | |
auto const &sig = pSigHolder->GetSignature(); | |
auto const &blob = sig.GetBlob(); | |
for (auto i = blob.begin(), i_end = blob.end(); i != i_end; ++i) | |
sb.Put<COR_SIGNATURE>(*i); | |
} | |
}; | |
struct Putter | |
{ | |
Putter(SimpleBlob& sb) : | |
m_sb(sb) | |
{ } | |
template<class SignatureHolder> | |
Putter& operator ,(SignatureHolder const &v) | |
{ | |
typedef PutImplForPointerDispensing<SignatureHolder> Impl; | |
Impl::Put(m_sb, v); | |
return *this; | |
} | |
SimpleBlob& m_sb; | |
}; | |
template<class T> | |
Putter operator +=(SimpleBlob& blob, T const &v) | |
{ | |
return Putter(blob), v; | |
} | |
class SignatureImpl::SignatureImplPimpl | |
{ | |
public: | |
SignatureImplPimpl(SignatureImpl *pClass) : | |
m_pClass(pClass) | |
{ } | |
void Initialize(IType const *pType) | |
{ | |
BOOST_THROW_EXCEPTION(Urasandesu::CppAnonym::CppAnonymNotImplementedException()); | |
} | |
void Initialize(IMethod const *pMethod) | |
{ | |
_ASSERTE(pMethod != nullptr); | |
_ASSERTE(m_blob.empty()); | |
auto sb = SimpleBlob(); | |
sb += | |
pMethod->GetCallingConvention(), | |
pMethod->GetParameterTypes().size(), | |
pMethod->GetReturnType(), | |
pMethod->GetParameterTypes() | |
; | |
m_blob.reserve(sb.Size()); | |
m_blob.assign(sb.Ptr(), sb.Ptr() + sb.Size()); | |
} | |
void Initialize(IField const *pField) | |
{ | |
BOOST_THROW_EXCEPTION(Urasandesu::CppAnonym::CppAnonymNotImplementedException()); | |
} | |
vector<COR_SIGNATURE> const &GetBlob() const | |
{ | |
return m_blob; | |
} | |
private: | |
SignatureImpl *m_pClass; | |
vector<COR_SIGNATURE> m_blob; | |
}; | |
SignatureImpl::SignatureImpl() | |
{ | |
#ifdef _DEBUG | |
BOOST_MPL_ASSERT_RELATION(sizeof(SignatureImplPimpl), <=, sizeof(storage_type)); | |
#else | |
BOOST_MPL_ASSERT_RELATION(sizeof(SignatureImplPimpl), ==, sizeof(storage_type)); | |
#endif | |
new(Pimpl())SignatureImplPimpl(this); | |
} | |
SignatureImpl::~SignatureImpl() | |
{ | |
Pimpl()->~SignatureImplPimpl(); | |
} | |
SignatureImpl::SignatureImplPimpl *SignatureImpl::Pimpl() | |
{ | |
return reinterpret_cast<SignatureImplPimpl *>(&m_storage); | |
} | |
SignatureImpl::SignatureImplPimpl const *SignatureImpl::Pimpl() const | |
{ | |
return const_cast<SignatureImpl *>(this)->Pimpl(); | |
} | |
void SignatureImpl::Initialize(IType const *pType) | |
{ | |
Pimpl()->Initialize(pType); | |
} | |
void SignatureImpl::Initialize(IMethod const *pMethod) | |
{ | |
Pimpl()->Initialize(pMethod); | |
} | |
void SignatureImpl::Initialize(IField const *pField) | |
{ | |
Pimpl()->Initialize(pField); | |
} | |
vector<COR_SIGNATURE> const &SignatureImpl::GetBlob() const | |
{ | |
return Pimpl()->GetBlob(); | |
} | |
} // namespace SignatureDetail { | |
}}} // namespace Urasandesu { namespace Swathe { namespace Metadata { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment