diff --git a/Lib/ruby/rubystdcommon.swg b/Lib/ruby/rubystdcommon.swg new file mode 100644 index 000000000..58e681403 --- /dev/null +++ b/Lib/ruby/rubystdcommon.swg @@ -0,0 +1,240 @@ +%fragment("StdTraits","header",fragment="StdTraitsCommon") +{ +namespace swig { + /* + Traits that provides the from method + */ + template struct traits_from_ptr { + static VALUE from(Type *val, int owner = 0) { + return SWIG_NewPointerObj(val, type_info(), owner); + } + }; + + template struct traits_from { + static VALUE from(const Type& val) { + fprintf( stderr, "%s %d\n", __PRETTY_FUNCTION__, __LINE__); + return traits_from_ptr::from(new Type(val), 1); + } + }; + + template struct traits_from { + static VALUE from(Type* val) { + return traits_from_ptr::from(val, 0); + } + }; + + template struct traits_from { + static VALUE from(const Type* val) { + fprintf( stderr, "conversion from const Type*n"); + return traits_from_ptr::from(const_cast(val), 0); + } + }; + + + template + inline VALUE from(const Type& val) { + fprintf( stderr, "%s %d\n", __PRETTY_FUNCTION__, __LINE__); + return traits_from::from(val); + } + + template + inline VALUE from_ptr(Type* val, int owner) { + return traits_from_ptr::from(val, owner); + } + + /* + Traits that provides the asval/as/check method + */ + template + struct traits_asptr { + static int asptr(VALUE obj, Type **val) { + Type *p; + int res = (SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0) == SWIG_OK) ? SWIG_OLDOBJ : 0; + if (SWIG_IsOK(res)) { + if (val) *val = p; + } + return res; + } + }; + + template + inline int asptr(VALUE obj, Type **vptr) { + return traits_asptr::asptr(obj, vptr); + } + + template + struct traits_asval { + static int asval(VALUE obj, Type *val) { + if (val) { + Type *p = 0; + int res = traits_asptr::asptr(obj, &p); + if (!SWIG_IsOK(res)) return res; + if (p) { + typedef typename noconst_traits::noconst_type noconst_type; + *(const_cast(val)) = *p; + if (SWIG_IsNewObj(res)){ + %delete(p); + res = SWIG_DelNewMask(res); + } + return res; + } else { + return SWIG_ERROR; + } + } else { + return traits_asptr::asptr(obj, (Type **)(0)); + } + } + }; + + template struct traits_asval { + static int asval(VALUE obj, Type **val) { + if (val) { + typedef typename noconst_traits::noconst_type noconst_type; + noconst_type *p = 0; + int res = traits_asptr::asptr(obj, &p); + if (SWIG_IsOK(res)) { + *(const_cast(val)) = p; + } + return res; + } else { + return traits_asptr::asptr(obj, (Type **)(0)); + } + } + }; + + template + inline int asval(VALUE obj, Type *val) { + return traits_asval::asval(obj, val); + } + + template + struct traits_as { + static Type as(VALUE obj, bool throw_error) { + Type v; + int res = asval(obj, &v); + if (!obj || !SWIG_IsOK(res)) { + VALUE lastErr = rb_gv_get("$!"); + if (lastErr == Qnil) { + %type_error(swig::type_name()); + } + if (throw_error) throw std::invalid_argument("bad type"); + } + return v; + } + }; + + template + struct traits_as { + static Type as(VALUE obj, bool throw_error) { + Type *v = 0; + int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res) && v) { + if (SWIG_IsNewObj(res)) { + Type r(*v); + %delete(v); + return r; + } else { + return *v; + } + } else { + // Uninitialized return value, no Type() constructor required. + static Type *v_def = (Type*) malloc(sizeof(Type)); + VALUE lastErr = rb_gv_get("$!"); + if (lastErr == Qnil) { + %type_error(swig::type_name()); + } + if (throw_error) throw std::invalid_argument("bad type"); + memset(v_def,0,sizeof(Type)); + return *v_def; + } + } + }; + + template + struct traits_as { + static Type* as(VALUE obj, bool throw_error) { + Type *v = 0; + int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + if (SWIG_IsOK(res)) { + return v; + } else { + VALUE lastErr = rb_gv_get("$!"); + if (lastErr == Qnil) { + %type_error(swig::type_name()); + } + if (throw_error) throw std::invalid_argument("bad type"); + return 0; + } + } + }; + + template + inline Type as(VALUE obj, bool te = false) { + return traits_as::category>::as(obj, te); + } + + template + struct traits_check { + static bool check(VALUE obj) { + int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template + struct traits_check { + static bool check(VALUE obj) { + int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR; + return SWIG_IsOK(res) ? true : false; + } + }; + + template + inline bool check(VALUE obj) { + return traits_check::category>::check(obj); + } +} +} + +// +// Backward compatibility +// + +%define %specialize_std_container(Type,Check,As,From) +%{ +namespace swig { + template <> struct traits_asval { + typedef Type value_type; + static int asval(VALUE obj, value_type *val) { + if (Check(obj)) { + if (val) *val = As(obj); + return SWIG_OK; + } + return SWIG_ERROR; + } + }; + template <> struct traits_from { + typedef Type value_type; + static VALUE from(const value_type& val) { + fprintf( stderr, "%s %d\n", __PRETTY_FUNCTION__, __LINE__); + return From(val); + } + }; + + template <> + struct traits_check { + static int check(VALUE obj) { + int res = Check(obj); + return obj && res ? res : 0; + } + }; +} +%} +%enddef + + +#define specialize_std_vector(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_list(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_deque(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_set(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From) +#define specialize_std_multiset(Type,Check,As,From) %specialize_std_container(%arg(Type),Check,As,From)