|
Boost : |
From: Alexander Nasonov (alnsn-mycop_at_[hidden])
Date: 2003-02-19 05:11:16
Peter Dimov wrote:
> The other option is to support a dynamic_cast-style extract:
>
> T * p = extract<T*>(&var);
> T & r = extract<T&>(var);
>
> but it would likely require partial ordering/specialization.
I don't have access to a compiler with broken partial
ordering/specialization but I tried to keep it in mind when I implemented
extraction for dynamic_any. This code fragment is taken from
dynamic_any/any.hpp. Start reading from the bottom.
// T is not a class.
template<class T>
const T * extract_const_ptr(const placeholder * p, bool_id<false>)
{
if(p == 0 || p->type(sig()) != typeid(T))
return 0;
typedef const nonclass_holder<T> holder_type;
holder_type * ptr = static_cast<holder_type *>(p);
return &ptr->value;
}
// T is a class.
template<class T>
const T * extract_const_ptr(const placeholder * p, bool_id<true>)
{
return dynamic_cast<const T *>(p);
}
template<class T>
const T * extract_const_ptr(const placeholder * p, type_id<const T>)
{
bool_id< ::boost::is_class<T>::value> id;
return extract_const_ptr<T>(p, id);
}
// T is not a class.
template<class T>
T * extract_nonconst_ptr(placeholder * p, bool_id<false>)
{
if(p == 0 || p->type(sig()) != typeid(T))
return 0;
typedef nonclass_holder<T> holder_type;
holder_type * ptr = static_cast<holder_type *>(p);
return &ptr->value;
}
// T is a class.
template<class T>
T * extract_nonconst_ptr(placeholder * p, bool_id<true>)
{
return dynamic_cast<T *>(p);
}
template<class T>
T * extract_nonconst_ptr(placeholder * p, type_id<T>)
{
bool_id< ::boost::is_class<T>::value> id;
return extract_nonconst_ptr<T>(p, id);
}
// T is const.
template<class T>
T * extract_ptr(const placeholder * p, bool_id<true>)
{
return extract_const_ptr(p, type_id<T>());
}
// T is not const.
template<class T>
T * extract_ptr(placeholder * p, bool_id<false>)
{
return extract_nonconst_ptr(p, type_id<T>());
}
// Placeholder is 'placeholder' or 'const placeholder'.
template<class T, class Placeholder>
T * extract_ptr(Placeholder * p)
{
bool_id< ::boost::is_const<T>::value> id;
// Note to users: if you get compile error here then you are trying
// to extract non-const pointer or reference from const 'any'.
return extract_ptr<T>(p, id);
}
template<class T, class Placeholder>
T & extract_ref(Placeholder * p, type_id<T &>)
{
if(T * ptr = extract_ptr<T>(p))
return *ptr;
throw bad_extract();
}
// T is a reference.
template<class T, class Placeholder>
T extract(Placeholder * p, bool_id<true>)
{
return extract_ref(p, type_id<T>());
}
// T is not a reference.
template<class T, class Placeholder>
T extract(Placeholder * p, bool_id<false>)
{
return extract_ref(p, type_id<const T &>());
}
template<class T, class Placeholder>
T extract(Placeholder * p)
{
bool_id< ::boost::is_reference<T>::value> id;
return extract<T>(p, id);
}
-- Alexander Nasonov Remove -mycop from my e-mail address for timely response
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk