⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dobase.hpp

📁 The library provides supports for run-time loaded plugin classes in C++
💻 HPP
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 2007, Arne Steinarson// Licensing for DynObj project - see DynObj-license.txt in this folder#ifndef DOBASE_HPP#define DOBASE_HPP#include <string.h>// Basic interfaces#include "DoBaseI.h"#include "DoError.h"// Include DynShared support#if DO_USE_DYNSHARED==1    #include "DoDynShared.hpp"#endif// Doxygen stuff/// @cond internal///////////////////////////////////// This compile-time assert is adopted from Boosttemplate<bool b>struct DoErrorIfNot;template<>struct DoErrorIfNot<true>{ };#define DO_ASSERT(cond) sizeof(DoErrorIfNot<cond>)//////////////////////////////////////// Peel off pointers, refs & consttemplate <class T>struct DoBaseType {    typedef T type;};template <class T>struct DoBaseType<T*> {    typedef typename DoBaseType<T>::type type;};template <class T>struct DoBaseType<T&> {    typedef typename DoBaseType<T>::type type;};template <class T>struct DoBaseType<const T> {    typedef typename DoBaseType<T>::type type;};/////////////////////////////////////////// Simple test for same typetemplate <class T, class U>struct IsSameType {    enum { v=false };};template <class T>struct IsSameType<T,T> {    enum { v=true };};///////////////////////////////////////////////// Tests if a class has a VTable or nottemplate<class T>struct IsVObjImpl {    struct IA : public T {        int m;    };    struct IB : public T {        virtual void F( );        int m;    };    enum { v = (sizeof(IA)==sizeof(IB)) }; };/// @endcond internal/** @ingroup DynTemplate * Test if a type has a VTable or not.  * @return v is set to true if type has a VTable and false otherwise. */template<class T>struct IsVObj {    typedef typename DoBaseType<T>::type type;    enum { v=IsVObjImpl<type>::v || IsSameType<VObj,type>::v };};/// @cond internal/*template<class T>struct IsVObj<T*> {	enum { v = IsVObj<T>::v };};template<class T>struct IsVObj<T&> {	enum { v = IsVObj<T>::v };};*/// This avoids long error messages for the void casetemplate<>   struct IsVObj<void> {	enum { v = false };};///////////////////////////////////////////////////// Is a class derived from DynI?template <class T, class U>struct DoIsTypeAImpl {	// Test functions	static char F( U* );	static short F(...);	static T* pt;	enum { v=sizeof(F(pt))==sizeof(char) };};template <class T, class U>struct DoIsTypeA {    enum { v=DoIsTypeAImpl<typename DoBaseType<T>::type,U>::v };};// Check if type is consttemplate <class T>struct DoIsConst {    enum { v=0 };};template <class T>struct DoIsConst<const T> {    enum { v=1 };};template <class T>  // Should this be needed?struct DoIsConst<const T&> {    enum { v=1 };};template <class T>  // Should this be needed?struct DoIsConst<const T*> {    enum { v=1 };};/////////////////////////////////////////// Check if type is ref or nottemplate <class T>struct DoIsRef {     enum { v=0 };};template <class T>struct DoIsRef<T&> {     enum { v=1 };};/////////////////////////////////////////// Check if type is ref or nottemplate <class T>struct DoIsPointer {     enum { v=0 };};template <class T>struct DoIsPointer<T*> {     enum { v=1 };};// Casting based on type ID:stemplate<class U, int M, int N>struct DoCaster;	// Generic case, compile time errortemplate<class U, int N>struct DoCaster<U,0,N> {	// Case for detected VObj	static U Cast( const void *pv, doCastAlgo algo ){        if( !pv ) return 0;        return reinterpret_cast<U>(::doGetObj((void*)pv,doTypeInfo<U>::Id(),NULL,algo));	}};template<class U, int N>struct DoCaster<U,1,N> {	// Case for DynI	static U Cast( const DynI *pdi, doCastAlgo algo ) {        if( !pdi ) return 0;		return reinterpret_cast<U>(::doGetObj((void*)pdi,doTypeInfo<U>::Id(),DI_GET_TYPE(pdi),algo));	}};#if DO_USE_DYNSHARED==1template<class U, int N>struct DoCaster<U,N,1> {	// Case for RTDynShared	static U Cast( const RTDynShared *prtds, doCastAlgo algo ) {        if( !prtds ) return 0;        // Return pointer to self?        if( IsSameType<U,DynSharedI>::v ||            IsSameType<U,DynI>::v ||            IsSameType<U,VObj>::v ) return prtds;        else        	return DoCaster<U,2,0>::Cast( prtds, algo );	}};#else // DO_USE_DYNSHARED    // Provide dummy template class for test below    struct RTDynShared { };#endif// Type-string case (for do_cast_str)template<class U, int M, int N>struct DoCasterStr;	// Generic case, compile time errortemplate<class U, int N>struct DoCasterStr<U,0,N> {	// Case for detected VObj	static U Cast( const void *pv, doCastAlgo algo ){        if( !pv ) return 0;        return reinterpret_cast<U>(::doGetObj((void*)pv,doTypeInfo<U>::Name(),NULL,algo));	}};template<class U, int N>struct DoCasterStr<U,1,N> {	// Case for DynI	static U Cast( const DynI *pdi, doCastAlgo algo ) {        if( !pdi ) return 0;		return reinterpret_cast<U>(::doGetObj((void*)pdi,doTypeInfo<U>::Name(),DI_GET_TYPE(pdi),algo));	}};#if DO_USE_DYNSHARED==1template<class U, int N>struct DoCasterStr<U,N,1> {	// Case for RTDynShared	static U Cast( const RTDynShared *prtds, doCastAlgo algo ) {        if( !prtds ) return 0;        // Return pointer to self?        if( IsSameType<U,DynSharedI>::v ||            IsSameType<U,DynI>::v ||            IsSameType<U,VObj>::v ) return prtds;        else        	return DoCasterStr<U,2,0>::Cast( prtds, algo );	}};#endif/// @endcond internal/** @ingroup DynTemplate * Cast a pointer to another C++ type across DLL/SO boundaries.  * This does type lookup using information from the library compiler. * It is the equivalent of dynamic_cast in C++ or QueryInterface in COM.  * It uses integer type ID:s internally (not type strings) and is therefore  * faster then string based casts. * @return a pointer to the requested interface/class if found, otherwise NULL. */template<class U, class T>U do_cast( T* pt, doCastAlgo algo=doCastCross ) {	// OK when we have positive on IsVObj or IsDynI, 	// negative when both are false (compile time error, we 	// cannot cast from the type).    // Verify constness first (compile time)    DO_ASSERT( DoIsConst<U>::v || !DoIsConst<T>::v );    DO_ASSERT( IsVObj<T>::v );	return DoCaster< U, DoIsTypeA<T,DynI>::v, DoIsTypeA<T,RTDynShared>::v >::Cast(pt,algo);}/** @ingroup DynTemplate * Cast a reference to another C++ type across DLL/SO boundaries.  * This does type lookup using information from the source object compiler. * It is the equivalent of dynamic_cast in C++ or QueryInterface in COM.  * It uses integer type ID:s internally (not type strings) and is therefore  * faster then string based casts. * @return a pointer to the requested interface/class if found, otherwise NULL. */template<class U, class T>U do_cast_ref( T& t, doCastAlgo algo=doCastCross ) {    // Verify constness first (compile time)    DO_ASSERT( (int)DoIsConst<U>::v >= (int)DoIsConst<T>::v );    DO_ASSERT( IsVObj<T>::v );    // Then cast	return *DoCaster< typename DoBaseType<U>::type*, DoIsTypeA<T,DynI>::v, DoIsTypeA<T,RTDynShared>::v >::Cast(&t,algo);}/** @ingroup DynTemplate * As above but uses type strings (and can therefore find custom objects). * Using string based casts is slower than casts based on integer ID. * @return a pointer to the requested interface/class if found, otherwise NULL. */template<class U, class T>U do_cast_str( T* pt, doCastAlgo algo=doCastCross ) {    // Verify constness first (compile time)    DO_ASSERT( DoIsConst<U>::v || !DoIsConst<T>::v );    DO_ASSERT( IsVObj<T>::v );	return DoCasterStr< U, DoIsTypeA<T,DynI>::v, DoIsTypeA<T,RTDynShared>::v >::Cast(pt,algo);}/** @ingroup DynTemplate * As above but uses type strings and for references. * @return a referece to the requested interface/class if found, otherwise NULL. */template<class U, class T>U do_cast_ref_str( T& t, doCastAlgo algo=doCastCross ) {    // Verify constness first (compile time)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -