|
Boost : |
From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-11-12 04:35:22
Douglas Gregor wrote:
> On Monday 11 November 2002 11:45 am, Alexander Nasonov wrote:
>> Implementation can first try to call 'call_ex' and if it throws internal
>> exception (default behavoir) then revert to 'call' member-function.
>
> I'm assuming you aren't referring to an actual C++ exception. I would
> assume that the default behavior of call_ex would be to call the call
> function in the derived class (assuming you are still planning to use the
> curiously recurring template pattern).
Exception was a first thing that came into my mind. Thank you Douglas for
your idea! This is what we have now:
template<class EndFunction, typename Signature>
struct function
{
// actually, result_type may depend on OperationList
// const correctness issues are skiped for simplicity
template<class OperationLlist>
result_type operator()(any<OperationList> & a, any<OperationList> & b)
{
EndFunction & func = static_cast<EndFunction &>(*this);
// pseudo-algorithm
if(!can_make_call)
return func.nocall(a, b);
else
{
// assume that 'a' holds v1 and 'b' holds v2
return func.call_ex(v1, typeid(v1), v2, typeid(v2));
}
}
template<typename T>
result_type call_ex(const T & a, const std::type_info &,
const T & b, const std::type_info &)
{
EndFunction & func = static_cast<EndFunction &>(*this);
return func.call(a, b);
}
template<typename T>
result_type call(const T & a, const T & b)
{
// One of 'call_ex' or 'call' must be overriden by EndFunction
BOOST_STATIC_ASSERT(false);
}
template<class OperationLlist>
result_type nocall(any<OperationList> & a, any<OperationList> & b)
{
throw nocall();
}
// ...
};
// Example (two different versions of less):
struct simple :
struct function<simple, bool (const arg &, const arg &)>
{
template<typename T>
bool call(const T & a, const T & b)
{
return a < b;
}
};
struct advanced :
struct function<advanced, bool (const arg &, const arg &)>
{
template<typename T>
bool call_ex(const T & a, const std::type_info & ta,
const T & b, const std::type_info & tb)
{
return (ta == tb) ? (a < b) : ta.before(tb);
}
template<class OperationLlist>
bool nocall(any<OperationList> & a, any<OperationList> & b)
{
return a.type().before(b.type());
}
};
boost::dynamic_any::any<mpl::list<simple, advanced> > a(0), b(1), c;
bool d = simple()(a, b);
assert(d);
bool e = advanced()()(a, b);
assert(e);
bool f = advanced()()(b, c);
assert(f == typeid(int).before(typeid(void)));
bool g = simple()(b, c); // throws nocall
Best regards,
Alexander Nasonov
mailbox: alnsn
server: mail.ru
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk