specialized_types.cc
Go to the documentation of this file.
00001 #include "typelib.hh"
00002 #include <iostream>
00003 
00004 #include <boost/bind.hpp>
00005 #include <typelib/value_ops.hh>
00006 
00007 using namespace Typelib;
00008 using std::vector;
00009 using namespace typelib_ruby;
00010 
00011 /**********************************************
00012  * Typelib::Compound
00013  */
00014 
00015 static VALUE compound_get_fields(VALUE self)
00016 {
00017     if (self == cCompound)
00018         return rb_ary_new();
00019 
00020     Type const& type(rb2cxx::object<Type>(self));
00021     Compound const& compound(dynamic_cast<Compound const&>(type));
00022     Compound::FieldList const& fields(compound.getFields());
00023     Compound::FieldList::const_iterator it, end = fields.end();
00024 
00025     VALUE registry  = type_get_registry(self);
00026     VALUE fieldlist = rb_ary_new();
00027     for (it = fields.begin(); it != end; ++it)
00028     {
00029         VALUE field_name = rb_str_new2(it->getName().c_str());
00030         VALUE field_type = cxx2rb::type_wrap(it->getType(), registry);
00031 
00032         VALUE field_def = rb_ary_new2(3);
00033         rb_ary_store(field_def, 0, field_name);
00034         rb_ary_store(field_def, 1, INT2FIX(it->getOffset()));
00035         rb_ary_store(field_def, 2, field_type);
00036         rb_ary_push(fieldlist, field_def);
00037     }
00038 
00039     return fieldlist;
00040 }
00041 
00042 /* Helper function for CompoundType#[] */
00043 static VALUE compound_field_get(VALUE rbvalue, VALUE name, VALUE raw)
00044 { 
00045     VALUE registry = value_get_registry(rbvalue);
00046     Value value = rb2cxx::object<Value>(rbvalue);
00047     if (! value.getData())
00048         return Qnil;
00049 
00050     try { 
00051         Value field_value = value_get_field(value, StringValuePtr(name));
00052         if (RTEST(raw))
00053             return cxx2rb::value_wrap(field_value, registry, rbvalue);
00054         else return typelib_to_ruby(field_value, registry, rbvalue);
00055     } 
00056     catch(FieldNotFound)
00057     { rb_raise(rb_eArgError, "no field '%s'", StringValuePtr(name)); } 
00058     catch(std::exception const& e)
00059     { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00060 }
00061 /* Helper function for CompoundType#[]= */
00062 static VALUE compound_field_set(VALUE self, VALUE name, VALUE newval)
00063 { 
00064     Value& tlib_value(rb2cxx::object<Value>(self));
00065 
00066     try {
00067         Value field_value = value_get_field(tlib_value, StringValuePtr(name));
00068         typelib_from_ruby(field_value, newval);
00069         return newval;
00070     }
00071     catch(FieldNotFound)
00072     { rb_raise(rb_eArgError, "no field '%s' in '%s'", StringValuePtr(name), rb_obj_classname(self)); }
00073     catch(std::exception const& e)
00074     { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00075 }
00076 
00077 /* call-seq:
00078  *  pointer.deference => pointed-to type
00079  *
00080  * Returns the value pointed to by +self+ 
00081  */
00082 static VALUE pointer_deference(VALUE self)
00083 {
00084     VALUE pointed_to = rb_iv_get(self, "@points_to");
00085     if (!NIL_P(pointed_to))
00086         return pointed_to;
00087 
00088     Value const& value(rb2cxx::object<Value>(self));
00089     Indirect const& indirect(static_cast<Indirect const&>(value.getType()));
00090     
00091     VALUE registry = value_get_registry(self);
00092 
00093     void* ptr_value = *reinterpret_cast<void**>(value.getData());
00094     if (!ptr_value)
00095         rb_raise(rb_eArgError, "cannot deference a NULL pointer");
00096 
00097     Value new_value(ptr_value, indirect.getIndirection() );
00098     return cxx2rb::value_wrap(new_value, registry, Qnil);
00099 }
00100 
00101 
00102 /* Get the C value associated with a ruby representation of an enum
00103  * Valid ruby representations are: symbols, strings and integer
00104  */
00105 Enum::integral_type rb2cxx::enum_value(VALUE rb_value, Enum const& e)
00106 {
00107     // m_value can be either an integer, a symbol or a string
00108     if (TYPE(rb_value) == T_FIXNUM)
00109     {
00110         Enum::integral_type value = FIX2INT(rb_value);
00111         try { 
00112             e.get(value); 
00113             return value;
00114         }
00115         catch(Enum::ValueNotFound) {  }
00116         rb_raise(rb_eArgError, "%i is not a valid value for %s", value, e.getName().c_str());
00117     }
00118 
00119     char const* name;
00120     if (SYMBOL_P(rb_value))
00121         name = rb_id2name(SYM2ID(rb_value));
00122     else
00123         name = StringValuePtr(rb_value);
00124 
00125     try { return e.get(name); }
00126     catch(Enum::SymbolNotFound) {  }
00127     rb_raise(rb_eArgError, "%s is not a valid symbol for %s", name, e.getName().c_str());
00128 }
00129 
00130 /* call-seq:
00131  *  enum.keys => array of keys
00132  *
00133  * Returns a string array of all the keys defined for this enumeration
00134  */
00135 VALUE enum_keys(VALUE self)
00136 {
00137     if (self == cEnum)
00138         return rb_hash_new();
00139 
00140     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00141 
00142     VALUE keys = rb_iv_get(self, "@values");
00143     if (!NIL_P(keys)) 
00144         return keys;
00145 
00146     keys = rb_hash_new();
00147     typedef std::list<std::string> string_list;
00148     string_list names = type.names();
00149     for (string_list::const_iterator it = names.begin(); it != names.end(); ++it)
00150         rb_hash_aset(keys, rb_str_new2(it->c_str()), INT2FIX(type.get(*it)));
00151 
00152     rb_iv_set(self, "@values", keys);
00153     return keys;
00154 }
00155 
00156 /* call-seq:
00157  *  enum.value_of(name) => integer
00158  *
00159  * Returns the integral value asoociated with the given name.
00160  */
00161 static VALUE enum_value_of(VALUE self, VALUE name)
00162 {
00163     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00164 
00165     try {
00166         int value = type.get(StringValuePtr(name));
00167         return INT2NUM(value);
00168     } catch (Enum::SymbolNotFound) {
00169         rb_raise(rb_eArgError, "this enumeration has no value for %s", StringValuePtr(name));
00170     }
00171 }
00172 
00173 /* call-seq:
00174  *  enum.name_of(integer) => key
00175  *
00176  * Returns the symbolic name of +integer+ in this enumeration, or raises
00177  * ArgumentError if there is no matching name.
00178  */
00179 static VALUE enum_name_of(VALUE self, VALUE integer)
00180 {
00181     Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00182 
00183     try {
00184         std::string name = type.get(NUM2INT(integer));
00185         return rb_str_new2(name.c_str());
00186     } catch (Enum::ValueNotFound) {
00187         rb_raise(rb_eArgError, "this enumeration has no name for %i", NUM2INT(integer));
00188     }
00189 }
00190 
00191 /**********************************************
00192  * Typelib::Pointer
00193  */
00194 
00195 /* call-seq:
00196  *  type.deference => other_type
00197  *
00198  * Returns the type referenced by this one
00199  */
00200 static VALUE indirect_type_deference(VALUE self)
00201 {
00202     VALUE registry = type_get_registry(self);
00203     Type const& type(rb2cxx::object<Type>(self));
00204     Indirect const& indirect(static_cast<Indirect const&>(type));
00205     return cxx2rb::type_wrap(indirect.getIndirection(), registry);
00206 }
00207 
00208 
00209 static Value array_element(VALUE rbarray, VALUE rbindex)
00210 {
00211     Value& value(rb2cxx::object<Value>(rbarray));
00212     Array const& array(static_cast<Array const&>(value.getType()));
00213     size_t index = NUM2INT(rbindex);
00214     
00215     if (index >= array.getDimension())
00216     {
00217         rb_raise(rb_eIndexError, "Out of bounds: %lu > %lu", index, array.getDimension());
00218         return Value();
00219     }
00220 
00221     Type const& array_type(array.getIndirection());
00222 
00223     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00224     data += array_type.getSize() * index;
00225     return Value(data, array_type);
00226 }
00227 
00228 /* call-seq:
00229  *  array[index]    => value
00230  *
00231  * Returns the value at +index+ in the array. Since Typelib arrays are *not*
00232  * dynamically extensible, trying to set a non-existent index will raise an
00233  * IndexError exception.
00234  */
00235 static VALUE array_get(int argc, VALUE* argv, VALUE self)
00236 { 
00237     Value& value            = rb2cxx::object<Value>(self);
00238     Array const& array      = static_cast<Array const&>(value.getType());
00239     if (array.getDimension() == 0)
00240         return self;
00241 
00242     Type  const& array_type = array.getIndirection();
00243     VALUE registry          = value_get_registry(self);
00244 
00245     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00246     size_t index = NUM2INT(argv[0]);
00247     if (index >= array.getDimension())
00248         rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index, array.getDimension());
00249 
00250     if (argc == 1)
00251     {
00252         Value v = Value(data + array_type.getSize() * index, array_type);
00253         return cxx2rb::value_wrap( v, registry, self );
00254     }
00255     else if (argc == 2)
00256     {
00257         VALUE ret = rb_ary_new();
00258         size_t size = NUM2INT(argv[1]);
00259         if (index + size > array.getDimension())
00260             rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index + size - 1, array.getDimension());
00261 
00262         for (size_t i = index; i < index + size; ++i)
00263         {
00264             Value v = Value(data + array_type.getSize() * i, array_type);
00265             VALUE rb_v = cxx2rb::value_wrap( v, registry, self );
00266 
00267             rb_ary_push(ret, rb_v);
00268         }
00269 
00270         return ret;
00271     }
00272     else
00273         rb_raise(rb_eArgError, "invalid argument count (%i for 1 or 2)", argc);
00274 }
00275 
00276 /* call-seq:
00277  *  array[index] = new_value    => new_value
00278  *
00279  * Sets the value at +index+ to +new_value+. Since Typelib arrays are *not*
00280  * dynamically extensible, trying to set a non-existent index will raise an
00281  * IndexError exception.
00282  */
00283 static VALUE array_set(VALUE self, VALUE rbindex, VALUE newvalue)
00284 { 
00285     Value element = array_element(self, rbindex);
00286     return typelib_from_ruby(element, newvalue); 
00287 }
00288 
00289 /* call-seq:
00290  *  array.each { |v| ... }      => array
00291  *
00292  * Iterates on all elements of the array
00293  */
00294 static VALUE array_do_each(VALUE rbarray)
00295 {
00296     Value& value            = rb2cxx::object<Value>(rbarray);
00297     Array const& array      = static_cast<Array const&>(value.getType());
00298     if (array.getDimension() == 0)
00299         return rbarray;
00300 
00301     Type  const& array_type = array.getIndirection();
00302     VALUE registry          = value_get_registry(rbarray);
00303 
00304     int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00305 
00306     for (size_t i = 0; i < array.getDimension(); ++i, data += array_type.getSize())
00307         rb_yield(cxx2rb::value_wrap( Value(data, array_type), registry, rbarray ));
00308 
00309     return rbarray;
00310 }
00311 
00312 /* call-seq:
00313  *  array.size              => size
00314  *
00315  * Returns the count of elements in +array+
00316  */
00317 static VALUE array_size(VALUE rbarray)
00318 {
00319     Value& value(rb2cxx::object<Value>(rbarray));
00320     Array const& array(static_cast<Array const&>(value.getType()));
00321     return INT2FIX(array.getDimension());
00322 }
00323 
00324 /* call-seq:
00325  *  array.length                    => length
00326  *
00327  * Returns the count of elemnts in +array+
00328  */
00329 static VALUE array_class_length(VALUE rbarray)
00330 {
00331     Array const& array(dynamic_cast<Array const&>(rb2cxx::object<Type>(rbarray)));
00332     return INT2FIX(array.getDimension());
00333 }
00334 
00335 /*
00336  * call-seq:
00337  *  pointer.null?               => boolean
00338  *
00339  * checks if this is a NULL pointer 
00340  */
00341 static VALUE pointer_nil_p(VALUE self)
00342 {
00343     Value const& value(rb2cxx::object<Value>(self));
00344     if ( *reinterpret_cast<void**>(value.getData()) == 0 )
00345         return Qtrue;
00346     return Qfalse;
00347 }
00348 
00349 /*
00350  * call-seq:
00351  *  numeric.integer?        => true or false
00352  *
00353  * Returns true if the type is an integral type and false if it is a floating-point type
00354  */
00355 static VALUE numeric_type_integer_p(VALUE self)
00356 {
00357     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00358     return type.getNumericCategory() == Numeric::Float ? Qfalse : Qtrue;
00359 }
00360 
00361 /*
00362  * call-seq:
00363  *  numeric.size            => value
00364  *
00365  * The size of this type in bytes
00366  */
00367 static VALUE numeric_type_size(VALUE self)
00368 {
00369     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00370     return INT2FIX(type.getSize());
00371 }
00372 
00373 /*
00374  * call-seq:
00375  *  numeric.unsigned?       => value
00376  *
00377  * If integer? returns true, returns whether this type is an unsigned or signed
00378  * integral type.
00379  */
00380 static VALUE numeric_type_unsigned_p(VALUE self)
00381 {
00382     Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00383     switch(type.getNumericCategory())
00384     {
00385         case Numeric::SInt: return Qfalse;
00386         case Numeric::UInt: return Qtrue;
00387         case Numeric::Float:
00388             rb_raise(rb_eArgError, "not an integral type");
00389     }
00390     return Qnil; // never reached
00391 }
00392 
00393 
00394 /*
00395  * call-seq:
00396  *  klass.container_kind => name
00397  *
00398  * Returns the name of the generic container. For instance, a
00399  * /std/vector</double> type would return /std/vector.
00400  */
00401 static VALUE container_kind(VALUE self)
00402 {
00403     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00404     return rb_str_new2(type.kind().c_str());
00405 }
00406 
00407 /*
00408  * call-seq:
00409  *  container.natural_size => a_number
00410  *
00411  * Returns the container's size on the local machine. This can be different from
00412  * the value returned by size() in case a registry has been generated on a
00413  * different architecture.
00414  */
00415 static VALUE container_natural_size(VALUE self)
00416 {
00417     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00418     return INT2FIX(type.getNaturalSize());
00419 }
00420 
00421 /*
00422  * call-seq:
00423  *  container.random_access?
00424  *
00425  * Returns true if this container type is a random access container
00426  */
00427 static VALUE container_random_access_p(VALUE self)
00428 {
00429     Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00430     return type.isRandomAccess() ? Qtrue : Qfalse;
00431 }
00432 
00433 
00434 /*
00435  * call-seq:
00436  *  container.length => value
00437  *
00438  * Returns the count of elements in +container+
00439  */
00440 static VALUE container_length(VALUE self)
00441 {
00442     Value value = rb2cxx::object<Value>(self);
00443     Container const& type(dynamic_cast<Container const&>(value.getType()));
00444 
00445     return INT2NUM(type.getElementCount(value.getData()));
00446 }
00447 
00448 /*
00449  * call-seq:
00450  *  container.clear
00451  *
00452  * Removes all elements from that container
00453  */
00454 static VALUE container_clear(VALUE self)
00455 {
00456     Value value = rb2cxx::object<Value>(self);
00457     Container const& type(dynamic_cast<Container const&>(value.getType()));
00458 
00459     type.clear(value.getData());
00460     return Qnil;
00461 }
00462 
00463 static Typelib::Value container_element(uint64_t* buffer10, Type const& element_t, VALUE obj)
00464 {
00465     Typelib::Value element_v;
00466     if (element_t.getCategory() == Type::Numeric && sizeof(int64_t) * 10 >= element_t.getSize())
00467     {
00468         // Special case: allow the caller to use Ruby numeric directly. This is
00469         // way faster if a lot of insertions need to be done
00470         element_v = Value(buffer10, element_t);
00471         typelib_from_ruby(element_v, obj);
00472     }
00473     else
00474     {
00475         element_v   = rb2cxx::object<Value>(obj);
00476         if (element_t != element_v.getType())
00477             rb_raise(rb_eArgError, "wrong type %s for new element, expected %s", element_v.getType().getName().c_str(), element_t.getName().c_str());
00478     }
00479     return element_v;
00480 }
00481 
00482 static VALUE container_do_push(VALUE self, VALUE obj)
00483 {
00484     Value container_v = rb2cxx::object<Value>(self);
00485     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00486 
00487     uint64_t buffer[10];
00488     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00489     container_t.push(container_v.getData(), element_v);
00490     return self;
00491 }
00492 
00493 static VALUE container_do_set(VALUE self, VALUE index, VALUE obj)
00494 {
00495     Value container_v = rb2cxx::object<Value>(self);
00496     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00497 
00498     uint64_t buffer[10];
00499     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00500     container_t.setElement(container_v.getData(), NUM2INT(index), element_v);
00501     return self;
00502 }
00503 
00504 static VALUE container_do_get(VALUE self, VALUE index, VALUE raw)
00505 {
00506     Value container_v = rb2cxx::object<Value>(self);
00507     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00508     VALUE registry = value_get_registry(self);
00509 
00510     Value v = container_t.getElement(container_v.getData(), NUM2INT(index));
00511     if (RTEST(raw))
00512         return cxx2rb::value_wrap(v, registry, self);
00513     else return typelib_to_ruby(v, registry, self);
00514 }
00515 
00516 struct ContainerIterator : public ValueVisitor
00517 {
00518     VALUE m_registry;
00519     VALUE m_parent;
00520     bool m_raw;
00521 
00522     ContainerIterator(VALUE registry, VALUE parent, bool raw)
00523     {
00524         m_registry = registry;
00525         m_parent = parent;
00526         m_raw = raw;
00527     }
00528     virtual void dispatch(Value v)
00529     {
00530         if (m_raw)
00531             rb_yield(cxx2rb::value_wrap(v, m_registry, m_parent));
00532         else
00533             rb_yield(typelib_to_ruby(v, m_registry, m_parent));
00534     }
00535 };
00536 
00537 /*
00538  * call-seq:
00539  *  container.each { |obj| ... } => container
00540  *
00541  * Iterates on the elements of the container
00542  */
00543 static VALUE container_each(VALUE self, VALUE raw)
00544 {
00545     Value value = rb2cxx::object<Value>(self);
00546     VALUE registry = value_get_registry(self);
00547     ContainerIterator iterator(registry, self, RTEST(raw));
00548     dynamic_cast<Typelib::Container const&>(value.getType()).visit(value.getData(), iterator);
00549     return self;
00550 }
00551 
00552 /*
00553  * call-seq:
00554  *  container.erase(obj) => true or false
00555  *
00556  * Removes +obj+ from the container. Returns true if +obj+ has been found and
00557  * deleted, and false otherwise
00558  */
00559 static VALUE container_erase(VALUE self, VALUE obj)
00560 {
00561     Value container_v = rb2cxx::object<Value>(self);
00562     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00563 
00564     uint64_t buffer[10];
00565     Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00566 
00567     if (container_t.erase(container_v.getData(), element_v))
00568         return Qtrue;
00569     else
00570         return Qfalse;
00571 }
00572 
00573 bool container_delete_if_i(Value v, VALUE registry, VALUE container)
00574 {
00575     VALUE rb_v = cxx2rb::value_wrap(v, registry, container);
00576     if (RTEST(rb_yield(rb_v)))
00577         return true;
00578     return false;
00579 }
00580 
00581 /*
00582  * call-seq:
00583  *  container.delete_if { |obj| ... } => container
00584  *
00585  * Removes the elements in the container for which the block returns true.
00586  */
00587 static VALUE container_delete_if(VALUE self)
00588 {
00589     Value container_v = rb2cxx::object<Value>(self);
00590     Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00591 
00592     VALUE registry = value_get_registry(self);
00593     container_t.delete_if(container_v.getData(), boost::bind(container_delete_if_i, _1, registry, self));
00594     return self;
00595 }
00596 
00597 /*
00598  * call-seq:
00599  *  vector.contained_memory_id => value or nil
00600  *
00601  * (see ContainerType#contained_memory_id)
00602  */
00603 static VALUE vector_contained_memory_id(VALUE self)
00604 {
00605     Value container_v = rb2cxx::object<Value>(self);
00606     std::vector<uint8_t> const* vector = reinterpret_cast<std::vector<uint8_t>*>(container_v.getData());
00607     if (vector->empty())
00608         return Qnil;
00609     return ULL2NUM(reinterpret_cast<uint64_t>(&(*vector)[0]));
00610 }
00611 
00612 /* 
00613  * call-seq:
00614  *   to_ruby(value)     => non-Typelib object or self
00615  *
00616  * Converts +self+ to its Ruby equivalent. If no equivalent
00617  * type is available, returns self
00618  */
00619 static VALUE numeric_to_ruby(VALUE mod, VALUE self)
00620 {
00621     Value const& value(rb2cxx::object<Value>(self));
00622     VALUE registry = value_get_registry(self);
00623     try {
00624         return typelib_to_ruby(value, registry, Qnil);
00625     } catch(Typelib::NullTypeFound) { }
00626     rb_raise(rb_eTypeError, "trying to convert 'void'");
00627 }
00628 
00629 /*
00630  * call-seq:
00631  *   value.from_ruby(ruby_object) => self
00632  *
00633  * Initializes +self+ with the information contained in +ruby_object+.
00634  *
00635  * This particular method is not type-safe. You should use Typelib.from_ruby
00636  * unless you know what you are doing.
00637  */
00638 static VALUE numeric_from_ruby(VALUE self, VALUE arg)
00639 {
00640     Value& value(rb2cxx::object<Value>(self));
00641     try {
00642         typelib_from_ruby(value, arg);
00643         return self;
00644     } catch(Typelib::UnsupportedType) { }
00645     rb_raise(rb_eTypeError, "cannot perform the requested convertion");
00646 }
00647 
00648 
00649 /* Document-class: Typelib::NumericType
00650  *
00651  * Wrapper for numeric types (int, float, ...)
00652  */
00653 
00654 /* Document-class: Typelib::IndirectType
00655  *
00656  * Base class for types which deference other objects, like pointers or arrays
00657  * See also ArrayType and PointerType
00658  */
00659 
00660 /* Document-class: Typelib::PointerType
00661  *
00662  * Base class for pointers (references to other values)
00663  */
00664 
00665 /* Document-class: Typelib::CompoundType
00666  *
00667  * Base class for types composed by other types (structures and unions in C).
00668  * Each field is assigned its type and its offset inside the structure. So
00669  * unions are represented with all fields having an offset of zero, while
00670  * structures have consecutive offsets.
00671  */
00672 
00673 void typelib_ruby::Typelib_init_specialized_types()
00674 {
00675     VALUE mTypelib  = rb_define_module("Typelib");
00676     cNumeric   = rb_define_class_under(mTypelib, "NumericType", cType);
00677     rb_define_singleton_method(cNumeric, "integer?", RUBY_METHOD_FUNC(numeric_type_integer_p), 0);
00678     rb_define_singleton_method(cNumeric, "unsigned?", RUBY_METHOD_FUNC(numeric_type_unsigned_p), 0);
00679     rb_define_singleton_method(cNumeric, "size", RUBY_METHOD_FUNC(numeric_type_size), 0);
00680     rb_define_singleton_method(cNumeric, "to_ruby", RUBY_METHOD_FUNC(&numeric_to_ruby), 1);
00681     rb_define_method(cNumeric, "typelib_from_ruby", RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00682 
00683     cOpaque    = rb_define_class_under(mTypelib, "OpaqueType", cType);
00684     cNull      = rb_define_class_under(mTypelib, "NullType", cType);
00685 
00686     cIndirect  = rb_define_class_under(mTypelib, "IndirectType", cType);
00687     rb_define_singleton_method(cIndirect, "deference",    RUBY_METHOD_FUNC(indirect_type_deference), 0);
00688 
00689     cPointer  = rb_define_class_under(mTypelib, "PointerType", cIndirect);
00690     rb_define_method(cPointer, "deference", RUBY_METHOD_FUNC(pointer_deference), 0);
00691     rb_define_method(cPointer, "null?", RUBY_METHOD_FUNC(pointer_nil_p), 0);
00692     
00693     cCompound = rb_define_class_under(mTypelib, "CompoundType", cType);
00694     rb_define_singleton_method(cCompound, "get_fields",   RUBY_METHOD_FUNC(compound_get_fields), 0);
00695     rb_define_method(cCompound, "typelib_get_field", RUBY_METHOD_FUNC(compound_field_get), 2);
00696     rb_define_method(cCompound, "typelib_set_field", RUBY_METHOD_FUNC(compound_field_set), 2);
00697 
00698     cEnum = rb_define_class_under(mTypelib, "EnumType", cType);
00699     rb_define_singleton_method(cEnum, "keys", RUBY_METHOD_FUNC(enum_keys), 0);
00700     rb_define_singleton_method(cEnum, "value_of",      RUBY_METHOD_FUNC(enum_value_of), 1);
00701     rb_define_singleton_method(cEnum, "name_of",      RUBY_METHOD_FUNC(enum_name_of), 1);
00702     rb_define_singleton_method(cEnum, "to_ruby",      RUBY_METHOD_FUNC(&numeric_to_ruby), 1);
00703     rb_define_method(cEnum, "typelib_from_ruby",    RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00704 
00705     cArray    = rb_define_class_under(mTypelib, "ArrayType", cIndirect);
00706     rb_define_singleton_method(cArray, "length", RUBY_METHOD_FUNC(array_class_length), 0);
00707     rb_define_method(cArray, "do_get",  RUBY_METHOD_FUNC(array_get), -1);
00708     rb_define_method(cArray, "do_set",  RUBY_METHOD_FUNC(array_set), 2);
00709     rb_define_method(cArray, "do_each",    RUBY_METHOD_FUNC(array_do_each), 0);
00710     rb_define_method(cArray, "size",    RUBY_METHOD_FUNC(array_size), 0);
00711 
00712     cContainer = rb_define_class_under(mTypelib, "ContainerType", cIndirect);
00713     rb_define_singleton_method(cContainer, "container_kind", RUBY_METHOD_FUNC(container_kind), 0);
00714     rb_define_singleton_method(cContainer, "natural_size",   RUBY_METHOD_FUNC(container_natural_size), 0);
00715     rb_define_singleton_method(cContainer, "random_access?",   RUBY_METHOD_FUNC(container_random_access_p), 0);
00716     rb_define_method(cContainer, "length",    RUBY_METHOD_FUNC(container_length), 0);
00717     rb_define_method(cContainer, "size",    RUBY_METHOD_FUNC(container_length), 0);
00718     rb_define_method(cContainer, "do_clear",    RUBY_METHOD_FUNC(container_clear), 0);
00719     rb_define_method(cContainer, "do_push",    RUBY_METHOD_FUNC(container_do_push), 1);
00720     rb_define_method(cContainer, "do_get",    RUBY_METHOD_FUNC(container_do_get), 2);
00721     rb_define_method(cContainer, "do_set",    RUBY_METHOD_FUNC(container_do_set), 2);
00722     rb_define_method(cContainer, "do_each",      RUBY_METHOD_FUNC(container_each), 1);
00723     rb_define_method(cContainer, "do_erase",     RUBY_METHOD_FUNC(container_erase), 1);
00724     rb_define_method(cContainer, "do_delete_if", RUBY_METHOD_FUNC(container_delete_if), 0);
00725 
00726     VALUE mVector = rb_define_module_under(cContainer, "StdVector");
00727     rb_define_method(mVector, "contained_memory_id", RUBY_METHOD_FUNC(vector_contained_memory_id), 0);
00728 }
00729 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Mon Sep 14 2015 15:08:18