#include "protect.hpp" #include "Object.hpp" #include "detail/from_ruby.ipp" #include "detail/to_ruby.ipp" // --------------------------------------------------------------------- template<> inline Rice::Object from_ruby(Rice::Object x) { return x; } template<> inline Rice::Object to_ruby(Rice::Object const & x) { return x; } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline int num2int(VALUE x) { return NUM2INT(x); } inline VALUE int2num(int x) { return INT2NUM(x); } } } template<> inline int from_ruby(Rice::Object x) { return Rice::protect(Rice::detail::num2int, x); } template<> inline Rice::Object to_ruby(int const & x) { return Rice::protect(Rice::detail::int2num, x); } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline long num2long(VALUE x) { return NUM2LONG(x); } inline VALUE long2num(long x) { return LONG2NUM(x); } } } template<> inline long from_ruby(Rice::Object x) { return Rice::protect(Rice::detail::num2long, x); } template<> inline Rice::Object to_ruby(long const & x) { return Rice::protect(Rice::detail::long2num, x); } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline unsigned int num2uint(VALUE x) { return NUM2UINT(x); } inline VALUE uint2num(unsigned int x) { return UINT2NUM(x); } } } template<> inline unsigned int from_ruby(Rice::Object x) { return Rice::protect(Rice::detail::num2uint, x); } template<> inline Rice::Object to_ruby(unsigned int const & x) { return Rice::protect(Rice::detail::uint2num, x); } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline unsigned long num2ulong(VALUE x) { return NUM2ULONG(x); } inline VALUE ulong2num(unsigned long x) { return ULONG2NUM(x); } } } template<> inline unsigned long from_ruby(Rice::Object x) { return Rice::protect(Rice::detail::num2ulong, x); } template<> inline Rice::Object to_ruby(unsigned long const & x) { return Rice::protect(Rice::detail::ulong2num, x); } // --------------------------------------------------------------------- template<> inline bool from_ruby(Rice::Object x) { return RTEST(x); } template<> inline Rice::Object to_ruby(bool const & x) { return x ? Qtrue : Qfalse; } // --------------------------------------------------------------------- template<> inline char from_ruby(Rice::Object x) { if(x.rb_type() == T_STRING) { if(RSTRING_LEN(x.value()) == 0) { return RSTRING_PTR(x.value())[0]; } else { throw std::invalid_argument("from_ruby: string must have length 1"); } } else { return from_ruby(x) & 0xff; } } template<> inline Rice::Object to_ruby(char const & x) { return to_ruby(x); } // --------------------------------------------------------------------- template<> inline unsigned char from_ruby(Rice::Object x) { // TODO: I'm not sure if this is the right behavior yet return from_ruby(x); } template<> inline Rice::Object to_ruby(unsigned char const & x) { return to_ruby(x); } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline VALUE num2dbl(VALUE x, double * d) { *d = NUM2DBL(x); return Qnil; } inline VALUE dbl2num(double x) { return rb_float_new(x); } } } template<> inline float from_ruby(Rice::Object x) { double d; Rice::protect(Rice::detail::num2dbl, x, &d); return float(d); } template<> inline Rice::Object to_ruby(float const & x) { return Rice::protect(Rice::detail::dbl2num, x); } // --------------------------------------------------------------------- template<> inline double from_ruby(Rice::Object x) { double d; Rice::protect(Rice::detail::num2dbl, x, &d); return d; } template<> inline Rice::Object to_ruby(double const & x) { return Rice::protect(Rice::detail::dbl2num, x); } // --------------------------------------------------------------------- namespace Rice { namespace detail { inline VALUE str2ccstr(VALUE x) { return (VALUE)(StringValuePtr(x)); } } } template<> inline char const * from_ruby(Rice::Object x) { return (char const *)Rice::protect(Rice::detail::str2ccstr, x); } template<> inline Rice::Object to_ruby(char const * const & x) { return Rice::protect(rb_str_new2, x); } // --------------------------------------------------------------------- template<> inline std::string from_ruby(Rice::Object x) { return std::string(from_ruby(x)); } template<> inline Rice::Object to_ruby(std::string const & x) { return to_ruby(x.c_str()); }