ifndef Rice__Enum__ipp_ define Rice__Enum__ipp_
include “Data_Object.hpp” include “Class.hpp” include “String.hpp” include “protect.hpp” include <memory>
template<typename Enum_T> long Rice::Default_Enum_Traits<Enum_T>::as_long(Enum_T value) {
return static_cast<long>(value);
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits>
-
Enum()
: Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >() , enums_() , enums_guard_(&enums_) , names_() , names_guard_(&names_)
{ }
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits>
-
Enum(
char const * name, Module module) : Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >() , enums_() , enums_guard_(&enums_) , names_() , names_guard_(&names_)
{
this->template bind<void>(initialize(name, module));
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits>
-
Enum(Enum<Enum_T, Enum_Traits> const & other)
: Module_impl<Data_Type<Enum_T>, Enum<Enum_T, Enum_Traits> >(other) , enums_(other.enums_) , enums_guard_(&enums_) , names_(other.names_) , names_guard_(&names_)
{ }
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>
-
operator=(Rice::Enum<Enum_T, Enum_Traits> const & other) {
Rice::Enum<Enum_T, Enum_Traits> tmp(other); this->swap(tmp); return *this;
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits>
-
~Enum() { }
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>
-
initialize(
char const * name, Module module)
{
Class c = Rice::define_class_under<Enum_T>(module, name) .define_method("to_s", to_s) .define_method("to_i", to_i) .define_method("inspect", inspect) .define_method("<=>", compare) //.define_method("hash", hash) .define_method("eql?", eql) .define_method("==", eql) .define_method("===", eql) .define_singleton_method("each", each) .define_singleton_method("from_int", from_int) .include_module(rb_mComparable); // TODO: This should be unnecessary (it should be taken care of when // define_class_under binds the C++ and ruby types) this->set_value(c); protect(rb_iv_set, c, "enums", enums_); protect(rb_iv_set, c, "names", names_); return *this;
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Enum<Enum_T, Enum_Traits> & Rice::Enum<Enum_T, Enum_Traits>
-
define_value(
char const * name, Enum_T value)
{
std_unique_ptr<Enum_T> copy(new Enum_T(value)); Rice::Data_Object<Enum_T> m(copy.get(), *this); copy.release(); names_[m] = String(name); this->const_set(name, m); enums_.push(m); return *this;
}
template<typename Enum_T, typename Enum_Traits>
- void Rice::Enum<Enum_T, Enum_Traits>
-
swap(Enum<Enum_T, Enum_Traits> & other) {
Data_Type<Enum_T>::swap(other); enums_.swap(other.enums_); names_.swap(other.names_);
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
each(Object self) {
VALUE enums_v = rb_iv_get(self, "enums"); Check_Type(enums_v, T_ARRAY); Array enums(enums_v); for(size_t j = 0; j < enums.size(); ++j) { rb_yield(enums[j].value()); } return Qnil;
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
to_s(Object self) {
Data_Type<Enum_T> klass; Rice::Data_Object<Enum_T> m(self, klass); Object enum_class = rb_class_of(m); Hash names(rb_iv_get(enum_class, "names")); Object name = names[m]; if(name.is_nil()) { return String::format("INVALID(%d)", Enum_Traits::as_long(*m)); } else { return String(name); }
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
inspect(Object self) {
return String::format( "#<%s::%s>", String(self.class_of().name()).c_str(), String(to_s(self)).c_str());
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
compare(Object lhs, Object rhs) {
if(lhs.class_of() != rhs.class_of()) { String lhs_name(lhs.class_of().name()); String rhs_name(rhs.class_of().name()); rb_raise( rb_eTypeError, "Cannot compare %s to %s", lhs_name.c_str(), rhs_name.c_str()); } Data_Type<Enum_T> klass; Rice::Data_Object<Enum_T> l(lhs, klass); Rice::Data_Object<Enum_T> r(rhs, klass); Enum_T left(*l); Enum_T right(*r); if(left == right) { return INT2NUM(0); } else if(Enum_Traits::as_long(left) < Enum_Traits::as_long(right)) { return INT2NUM(-1); } else { return INT2NUM(1); }
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
eql(Object lhs, Object rhs) {
using ::from_ruby; // Workaround for g++ 3.3.3 bool is_equal = from_ruby<int>(compare(lhs, rhs)) == 0; return to_ruby(is_equal);
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
to_i(Object self) {
Data_Type<Enum_T> klass; Rice::Data_Object<Enum_T> m(self, klass); return LONG2NUM(Enum_Traits::as_long(*m));
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
hash(Object self) {
return to_i(self);
}
template<typename Enum_T, typename Enum_Traits>
- Rice::Object Rice::Enum<Enum_T, Enum_Traits>
-
from_int(Class klass, Object i) {
using ::from_ruby; // Workaround for g++ 3.3.3 Rice::Data_Object<Enum_T> m( new Enum_T(static_cast<Enum_T>(from_ruby<long>(i))), klass); return m.value();
}
template<typename T>
- Rice::Enum<T> Rice
-
define_enum(
char const * name, Module module)
{
return Enum<T>(name, module);
} endif // Rice__Enum__ipp_