Listing 5
template <bool, typename T> struct treat_enum_as_int_base
{
typedef T type;
static T & get_ref(T & val) { return val; };
};
template <typename T> struct treat_enum_as_int_base<true, T>
{
typedef int type;
static int & get_ref(T & val)
{ return reinterpret_cast<int&>(val); };
};
template <typename T> struct treat_enum_as_int_t : public
treat_enum_as_int_base< ::boost::is_enum<T>::value, T>
{};
template <typename T> typename treat_enum_as_int_t<T>::type &
treat_enum_as_int(T & val)
{
return treat_enum_as_int_t<T>::get_ref(val);
}
template <bool> struct read_if
{
template <typename is_t, typename T>
inline read_if(is_t & is, T & val)
{
is >> treat_enum_as_int(val);
if (!is)
{
throw std::runtime_error("read failed on parameter");
}
}
};
// Ignore this parameter - do not read from stream
template <> struct read_if<false>
{
template <typename is_t, typename T> inline read_if(is_t &, T){}
};
// Read types that do not require to be indirected
template <class param_t, class is_t, class T>
void read_from_stream(is_t & is, T & val,
is_indirect_tag<false>, bool &)
{
read_if<traits<param_t>::in>(is, val);
}
// Read types that are passed by pointer (and check for null)
template <class param_t, class is_t, typename T>
inline void read_from_stream(is_t & is, T & val,
is_indirect_tag<true>, bool & is_not_null)
{
read_if<true>(is, is_not_null);
if (is_not_null)
{
read_if<traits<param_t>::in>(is, val);
}
}
// Read only [in] parameters from the input stream
template <class param_t, class is_t, class T>
void read_arg(is_t & is, T & val, bool & is_not_null)
{
read_from_stream<param_t>(is, val,
is_indirect_tag<traits<param_t>::indirect>(), is_not_null);
}
// for functions with upto 2 arguments (download supports 7)
template <typename F, typename is_t, typename os_t >
void dispatch_call (is_t & is, os_t & os, F func)
{
typedef func_type<F> func_t;
typedef typename func_t::param1_t P1; // type of first param
typedef typename func_t::param2_t P2; // type of second param
typedef typename returnable_t<func_t::return_t>::type R;
typedef typename traits< P1 >::value_type V1;
typedef typename traits< P2 >::value_type V2;
typedef typename traits< R >::value_type RT;
// declare variables to receive data
V1 arg1 = V1(); bool is_not_null_1 = true;
V2 arg2 = V2(); bool is_not_null_2 = true;
// read the [in] args from the input stream
read_arg<P1>(is, arg1, is_not_null_1);
read_arg<P2>(is, arg2, is_not_null_2);
int function_result = call_returned;
RT retval
try
{
// call the specified function
retval = func_t::call(func,
make_arg< P1 >::to_arg(arg1, is_not_null_1),
make_arg< P2 >::to_arg(arg2, is_not_null_2));
}
catch (...) { function_result = exception_thrown; }
// marshal the return data [out] parameters
// (and/or a flag for whether an exception occurred)
//...
}