📄 variant_cc.h
字号:
// The clone() is implemented here.
template<typename T>
struct Impl : ImplBase
{
Impl ( T v ) : data ( v )
{}
virtual ~Impl () {}
virtual ImplBase* clone() const
{
Impl<T> *copy = new Impl<T>(data);
// need to copy other methods manually because
// we need a deep copy of the FunctorBase *'s
// vector<CallbackPair>::operator=() would only copy the pointers
// to the functors, not the functors themselves
// copy->methods = methods;
for (MethodList::const_iterator copy_it = methods.begin(); copy_it != methods.end();
++copy_it)
{
const CallbackPair &pr = *copy_it;
CBFunctorBase *pFbase = pr.second->clone();
copy->methods.push_back(CallbackPair(pr.first, pFbase));
}
// must reset the callee object to copy
for(MethodList::iterator i = copy->methods.begin();
i != copy->methods.end(); ++i)
{
(*i).second->setCallee(&(copy->data));
}
return copy;
}
T data ;
} ;
template<typename T>
#ifdef NO_EXPLICIT_MEMBER_TPL_INSTANTIATION
static Impl<T>* CastFromBase ( ImplBase* v , T const* =NULL )
#else
static Impl<T>* CastFromBase ( ImplBase* v )
#endif
{
Impl<T>* p = dynamic_cast<Impl<T>*> ( v ) ;
if ( p == NULL )
throw VariantException("variant_cc_t::CastFromBase()",
typeid(T).name()+string(" is not a valid type"));
return p ;
}
ImplBase* data ;
} ;
//
// non-member auxiliary functions.
// Needed for compilers that fail with: my_variant.get<int>().
//
// usage: int n = variant_cast<int>(my_variant);
template<typename T>
T variant_cast (const variant_cc_t& v)
{
#ifdef NO_EXPLICIT_MEMBER_TPL_INSTANTIATION
return v.get((T const*)(NULL));
#else
return v.get<T>();
#endif
}
// usage: bool b = variant_is_type_as(my_variant,my_type_variable);
//
// NOTE: For some reason MSVC fails to properly instantiate this functions unless
// the 'T const&' argument is added.
template<typename T>
bool variant_is_type_as (const variant_cc_t& v, T const& t)
{
return v.is_type_as(t);
}
template<typename T>
bool variant_is_type_as (const variant_cc_t& v, T const* t)
{
return v.is_type_as(t);
}
// *** variant_invoke the method with the registered name on the object ***
// Originally, we did these as variant_cc_t members, but MSC 6.0 had problems
// letting us invoke particular versions of templated members which we
// need to do to properly support functions that pass arguments by reference
// no arg, void return is not a template - nothing to parametrize
inline void variant_invoke0(variant_cc_t& v, const int &funcName)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor0 * pFtor =
dynamic_cast<CBFunctor0 *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
(*pFtor)();
}
template<class P1> void variant_invoke1(variant_cc_t& v, const int &funcName, P1 p1)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor1<P1> * pFtor =
dynamic_cast<CBFunctor1<P1> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
(*pFtor)(p1);
}
template<class P1, class P2> void variant_invoke2(variant_cc_t& v, const int &funcName, P1 p1, P2 p2)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor2<P1, P2> * pFtor =
dynamic_cast<CBFunctor2<P1, P2> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
(*pFtor)(p1, p2);
}
template<class P1, class P2, class P3>
void variant_invoke3(variant_cc_t& v, const int &funcName, P1 p1, P2 p2, P3 p3)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor3<P1, P2, P3> * pFtor =
dynamic_cast<CBFunctor3<P1, P2, P3> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
(*pFtor)(p1, p2, p3);
}
template<class P1, class P2, class P3, class P4>
void variant_invoke4(variant_cc_t& v, const int &funcName, P1 p1, P2 p2, P3 p3, P4 p4)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor4<P1, P2, P3, P4> * pFtor =
dynamic_cast<CBFunctor4<P1, P2, P3, P4> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
(*pFtor)(p1, p2, p3, p4);
}
template<class RT> RT variant_invoke_w_ret0(variant_cc_t& v, const int &funcName, RT *dummy)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor0wRet<RT> * pFtor =
dynamic_cast<CBFunctor0wRet<RT> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
return (*pFtor)();
}
template<class P1, class RT> RT variant_invoke_w_ret1(variant_cc_t& v, const int &funcName, P1 p1,
RT *dummy)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor1wRet<P1, RT> * pFtor =
dynamic_cast<CBFunctor1wRet<P1, RT> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
return (*pFtor)(p1);
}
template<class P1, class P2, class RT> RT variant_invoke_w_ret2(variant_cc_t& v, const int &funcName, P1 p1,
P2 p2, RT *dummy)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor2wRet<P1, P2, RT> * pFtor =
dynamic_cast<CBFunctor2wRet<P1, P2, RT> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
return (*pFtor)(p1, p2);
}
template<class P1, class P2, class P3, class RT>
RT variant_invoke_w_ret3(variant_cc_t& v, const int &funcName, P1 p1,
P2 p2, P3 p3, RT *dummy)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor3wRet<P1, P2, P3, RT> * pFtor =
dynamic_cast<CBFunctor3wRet<P1, P2, P3, RT> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
return (*pFtor)(p1, p2, p3);
}
template<class P1, class P2, class P3, class P4, class RT>
RT variant_invoke_w_ret4(variant_cc_t& v, const int &funcName, P1 p1,
P2 p2, P3 p3, P4 p4, RT *dummy)
{
CBFunctorBase *pBase = v.GetFunctorBase(funcName);
CBFunctor4wRet<P1, P2, P3, P4, RT> * pFtor =
dynamic_cast<CBFunctor4wRet<P1, P2, P3, P4, RT> *>(pBase);
if (pFtor == NULL)
{
cout << typeid(pFtor).name() << endl;
cout << typeid(pBase).name() << endl;
throw VariantException("variant_invoke()",
"dynamic_cast failed!");
}
return (*pFtor)(p1, p2, p3, p4);
}
// helper template functions to create functors out of raw function pointers
inline CBFunctor0
cb_ptr_fun(void (*func) (void))
{
return CBFunctor0(makeFunctor((CBFunctor0 *) NULL, func));
}
template<class P1> CBFunctor1<P1>
cb_ptr_fun(void (*func) (P1))
{
return CBFunctor1<P1>(makeFunctor((CBFunctor1<P1> *) NULL, func));
}
template<class P1, class P2> CBFunctor2<P1, P2>
cb_ptr_fun(void (*func) (P1, P2))
{
return CBFunctor2<P1, P2>(makeFunctor((CBFunctor2<P1, P2> *) NULL, func));
}
template<class P1, class P2, class P3> CBFunctor3<P1, P2, P3>
cb_ptr_fun(void (*func) (P1, P2, P3))
{
return CBFunctor3<P1, P2, P3>(makeFunctor((CBFunctor3<P1, P2, P3> *) NULL, func));
}
template<class P1, class P2, class P3, class P4> CBFunctor4<P1, P2, P3, P4>
cb_ptr_fun(void (*func) (P1, P2, P3, P4))
{
return CBFunctor4<P1, P2, P3, P4>(makeFunctor((CBFunctor4<P1, P2, P3, P4> *) NULL, func));
}
template<class RT> CBFunctor0wRet<RT>
cb_ptr_fun_w_ret(RT (*func) (void))
{
return CBFunctor0wRet<RT>(makeFunctor((CBFunctor0wRet<RT> *) NULL, func));
}
template<class P1, class RT> CBFunctor1wRet<P1, RT>
cb_ptr_fun_w_ret(RT (*func) (P1))
{
return CBFunctor1wRet<P1, RT>(makeFunctor((CBFunctor1wRet<P1, RT> *) NULL, func));
}
template<class P1, class P2, class RT> CBFunctor2wRet<P1, P2, RT>
cb_ptr_fun_w_ret(RT (*func) (P1, P2))
{
return CBFunctor2wRet<P1, P2, RT>(makeFunctor((CBFunctor2wRet<P1, P2, RT> *) NULL, func));
}
template<class P1, class P2, class P3, class RT> CBFunctor3wRet<P1, P2, P3, RT>
cb_ptr_fun_w_ret(RT (*func) (P1, P2, P3))
{
return CBFunctor3wRet<P1, P2, P3, RT>(makeFunctor((CBFunctor3wRet<P1, P2, P3, RT> *) NULL, func));
}
template<class P1, class P2, class P3, class P4, class RT> CBFunctor4wRet<P1, P2, P3, P4, RT>
cb_ptr_fun_w_ret(RT (*func) (P1, P2, P3, P4))
{
return CBFunctor4wRet<P1, P2, P3, P4, RT>(makeFunctor((CBFunctor4wRet<P1, P2, P3, P4, RT> *) NULL, func));
}
END_DTL_NAMESPACE
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -