#include "class.h"
#include "rucy.h"
using namespace Rucy;
static Class cBase, cSub, cSimpleObj;
namespace Rucy
{
template <> inline Class get_ruby_class () {return cBase;}
template <> inline Class get_ruby_class () {return cSub;}
template <> inline Class get_ruby_class () {return cSimpleObj;}
}// Rucy
RUCY_WRAPPER_VALUE_FROM_TO(Base)
RUCY_WRAPPER_VALUE_FROM_TO(Sub)
RUCY_WRAPPER_VALUE_FROM_TO(SimpleObj)
template
class RubyBase : public ClassWrapper
{
public:
RUCY_OVERRIDE_BEGIN(ClassWrapper)
RUCY_OVERRIDE_ID(name_overridable_faster)
RUCY_OVERRIDE_END
virtual const char* name_overridable () const
{
RUCY_SYM(name_overridable);
return this->value.call(name_overridable).c_str();
}
virtual const char* name_overridable_faster () const
{
RUCY_SYM(name_overridable_faster);
if (RUCY_IS_OVERRIDDEN(name_overridable_faster))
return this->value.call(name_overridable_faster).c_str();
else
return Super::name_overridable_faster();
}
bool is_name_overridable_faster_overridden () const
{
RUCY_SYM(name_overridable_faster);
return RUCY_IS_OVERRIDDEN(name_overridable_faster);
}
};// RubyBase
#define THIS(type) to(self)
#define CHECK(type) RUCY_CHECK_OBJ(type, self)
#define CALL(type, obj, fun) RUCY_WRAPPER_CALL(type, obj, fun)
/*
alloc function.
*/
static
VALUE base_alloc(VALUE klass)
{
return value(new RubyBase, klass);
}
static
VALUE name(VALUE self)
{
CHECK(Base);
return value(THIS(Base)->name());
}
static
VALUE call_name(VALUE self)
{
CHECK(Base);
return value(THIS(Base)->name());
}
static
VALUE base_name_overridable(VALUE self)
{
CHECK(Base);
return value(CALL(Base, THIS(Base), name_overridable()));
}
static
VALUE call_name_overridable(VALUE self)
{
CHECK(Base);
return value(THIS(Base)->name_overridable());
}
static
VALUE base_name_overridable_faster(VALUE self)
{
CHECK(Base);
return value(CALL(Base, THIS(Base), name_overridable_faster()));
}
static
VALUE call_name_overridable_faster(VALUE self)
{
CHECK(Base);
return value(THIS(Base)->name_overridable_faster());
}
template
static
VALUE is_name_overridable_faster_overridden(VALUE self)
{
RUCY_CHECK_OBJ(T, self);
RubyBase* obj = dynamic_cast*>(THIS(T));
if (!obj) invalid_object_error(__FILE__, __LINE__, "dynamic_cast() failed.");
return value(obj->is_name_overridable_faster_overridden());
}
static RUCY_DEF_clear_override_flags(Base_clear_override_flags, Base);
static RUCY_DEF_clear_override_flags(Sub_clear_override_flags, Sub);
static
VALUE base_new_raw(VALUE self)
{
return value(new Base);
}
/*
alloc function.
*/
static
VALUE sub_alloc(VALUE klass)
{
return value(new RubyBase, klass);
}
static
VALUE sub_name_overridable(VALUE self)
{
CHECK(Sub);
return value(CALL(Sub, THIS(Sub), name_overridable()));
}
static
VALUE sub_name_overridable_faster(VALUE self)
{
CHECK(Sub);
return value(CALL(Sub, THIS(Sub), name_overridable_faster()));
}
static
VALUE sub_new_raw(VALUE self)
{
return value(new Sub);
}
/*
alloc function.
*/
static
VALUE simpleobj_alloc(VALUE klass)
{
return value(new ClassWrapper, klass);
}
static
VALUE simpleobj_initialize(VALUE self, VALUE name)
{
CHECK(SimpleObj);
THIS(SimpleObj)->init(name.c_str());
}
static std::vector > simpleobj_refs;
static
VALUE simpleobj_set_refs(VALUE self, VALUE objs)
{
int size = objs.size();
for (int i = 0; i < size; ++i)
simpleobj_refs.push_back(to(objs[i]));
return objs;
}
static
VALUE simpleobj_clear_refs(VALUE self)
{
simpleobj_refs.clear();
}
void
Init_class ()
{
Module mRucy = rb_define_module("Rucy");
Module mTester = rb_define_module_under(mRucy, "Tester");
cBase = rb_define_class_under(mTester, "Base", rb_cObject);
rb_define_alloc_func(cBase, base_alloc);
rb_define_method(cBase, "name", RUBY_METHOD_FUNC(name), 0);
rb_define_method(cBase, "name_overridable", RUBY_METHOD_FUNC(base_name_overridable), 0);
rb_define_method(cBase, "name_overridable_faster", RUBY_METHOD_FUNC(base_name_overridable_faster), 0);
rb_define_method(cBase, "call_name", RUBY_METHOD_FUNC(call_name), 0);
rb_define_method(cBase, "call_name_overridable", RUBY_METHOD_FUNC(call_name_overridable), 0);
rb_define_method(cBase, "call_name_overridable_faster", RUBY_METHOD_FUNC(call_name_overridable_faster), 0);
cBase.define_method(
"is_name_overridable_faster_overridden",
is_name_overridable_faster_overridden);
rb_define_singleton_method(cBase, "new_raw", RUBY_METHOD_FUNC(base_new_raw), 0);
cSub = rb_define_class_under(mTester, "Sub", cBase);
rb_define_alloc_func(cSub, sub_alloc);
rb_define_method(cSub, "name_overridable", RUBY_METHOD_FUNC(sub_name_overridable), 0);
rb_define_method(cSub, "name_overridable_faster", RUBY_METHOD_FUNC(sub_name_overridable_faster), 0);
cSub.define_method(
"is_name_overridable_faster_overridden",
is_name_overridable_faster_overridden);
rb_define_singleton_method(cSub, "new_raw", RUBY_METHOD_FUNC(sub_new_raw), 0);
cSimpleObj = rb_define_class_under(mTester, "SimpleObj", rb_cObject);
rb_define_alloc_func(cSimpleObj, simpleobj_alloc);
rb_define_private_method(cSimpleObj, "initialize", RUBY_METHOD_FUNC(simpleobj_initialize), 1);
rb_define_function(cSimpleObj, "set_refs", RUBY_METHOD_FUNC(simpleobj_set_refs), 1);
rb_define_function(cSimpleObj, "clear_refs", RUBY_METHOD_FUNC(simpleobj_clear_refs), 0);
}