Listing 4: auto_unbox<>.
struct object_convertible
{
object_convertible ( System::Object * );
};
template<typename T>
class is_managed
{
static char select( object_convertible );
static double __cdecl select( ... );
static T get();
public:
enum { value = sizeof(select(get())) == sizeof(char) };
};
template<bool> struct auto_unbox_helper;
template<>
struct auto_unbox_helper<true> // managed
{
template<typename T>
struct inner
{
typedef T result_type;
static T unbox( System::Object *o )
{
return __try_cast<T>( o );
}
};
};
template<>
struct auto_unbox_helper<false> // not managed
{
template<typename T>
struct inner
{
typedef T __gc& result_type;
static T __gc& unbox( System::Object *o )
{
return *__try_cast<T __box*>( o );
}
};
};
template<typename T>
struct auto_unbox
{
typedef typename auto_unbox_helper<is_managed<T>::value>::
template inner<T> helper;
static typename helper::result_type unbox( System::Object *o )
{
return helper::unbox( o );
}
};