include “protect.hpp” include “Object.hpp” include “detail/from_ruby.ipp” include “detail/to_ruby.ipp”
// ——————————————————————— template<> inline Rice::Object from_ruby<Rice::Object>(Rice::Object x) {
return x;
}
template<> inline Rice::Object to_ruby<Rice::Object>(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<int>(Rice::Object x) {
return Rice::detail::num2int(x);
}
template<> inline Rice::Object to_ruby<int>(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<long>(Rice::Object x) {
return Rice::protect(Rice::detail::num2long, x);
}
template<> inline Rice::Object to_ruby<long>(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<unsigned int>(Rice::Object x) {
return Rice::detail::num2uint(x);
}
template<> inline Rice::Object to_ruby<unsigned int>(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<unsigned long>(Rice::Object x) {
return Rice::protect(Rice::detail::num2ulong, x);
}
template<> inline Rice::Object to_ruby<unsigned long>(unsigned long const & x) {
return Rice::protect(Rice::detail::ulong2num, x);
}
// ——————————————————————— template<> inline bool from_ruby<bool>(Rice::Object x) {
return RTEST(x);
}
template<> inline Rice::Object to_ruby<bool>(bool const & x) {
return x ? Qtrue : Qfalse;
}
// ——————————————————————— template<> inline char from_ruby<char>(Rice::Object x) {
if(x.rb_type() == T_STRING) { if(RSTRING_LEN(x.value()) == 1) { return RSTRING_PTR(x.value())[0]; } else { throw std::invalid_argument("from_ruby<char>: string must have length 1"); } } else { return from_ruby<int>(x) & 0xff; }
}
template<> inline Rice::Object to_ruby<char>(char const & x) {
return to_ruby<int>(x);
}
// ———————————————————————
template<> inline unsigned char from_ruby<unsigned char>(Rice::Object x) {
// TODO: I'm not sure if this is the right behavior yet return from_ruby<char>(x);
}
template<> inline Rice::Object to_ruby<unsigned char>(unsigned char const & x) {
return to_ruby<unsigned int>(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<float>(Rice::Object x) {
double d; Rice::protect(Rice::detail::num2dbl, x, &d); return float(d);
}
template<> inline Rice::Object to_ruby<float>(float const & x) {
return Rice::protect(Rice::detail::dbl2num, x);
}
// ———————————————————————
template<> inline double from_ruby<double>(Rice::Object x) {
double d; Rice::protect(Rice::detail::num2dbl, x, &d); return d;
}
template<> inline Rice::Object to_ruby<double>(double const & x) {
return Rice::protect(Rice::detail::dbl2num, x);
}
// ——————————————————————— template<> inline char const * from_ruby<char const *>(Rice::Object x) {
return Rice::String(x).str().data();
}
template<> inline Rice::Object to_ruby<char const *>(char const * const & x) {
return Rice::protect(rb_str_new2, x);
}
// ——————————————————————— template<> inline std::string from_ruby<std::string>(Rice::Object x) {
return Rice::String(x).str();
}
template<> inline Rice::Object to_ruby<std::string>(std::string const & x) {
return Rice::protect(rb_str_new, x.data(), x.size());
}
template<> inline std::string* from_ruby<std::string* >(Rice::Object x) {
return new std::string(Rice::String(x).str());
}