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
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(4);
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_store(field_def, 3, cxx2rb::metadata_wrap(it->getMetaData()));
00037 rb_ary_push(fieldlist, field_def);
00038 }
00039
00040 return fieldlist;
00041 }
00042
00043
00044 static VALUE compound_field_get(VALUE rbvalue, VALUE name, VALUE raw)
00045 {
00046 VALUE registry = value_get_registry(rbvalue);
00047 Value value = rb2cxx::object<Value>(rbvalue);
00048 if (! value.getData())
00049 return Qnil;
00050
00051 try {
00052 Value field_value = value_get_field(value, StringValuePtr(name));
00053 if (RTEST(raw))
00054 return cxx2rb::value_wrap(field_value, registry, rbvalue);
00055 else return typelib_to_ruby(field_value, registry, rbvalue);
00056 }
00057 catch(FieldNotFound)
00058 { rb_raise(rb_eArgError, "no field '%s'", StringValuePtr(name)); }
00059 catch(std::exception const& e)
00060 { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00061 }
00062
00063 static VALUE compound_field_set(VALUE self, VALUE name, VALUE newval)
00064 {
00065 Value& tlib_value(rb2cxx::object<Value>(self));
00066
00067 try {
00068 Value field_value = value_get_field(tlib_value, StringValuePtr(name));
00069 typelib_from_ruby(field_value, newval);
00070 return newval;
00071 }
00072 catch(FieldNotFound)
00073 { rb_raise(rb_eArgError, "no field '%s' in '%s'", StringValuePtr(name), rb_obj_classname(self)); }
00074 catch(std::exception const& e)
00075 { rb_raise(rb_eRuntimeError, "%s", e.what()); }
00076 }
00077
00078
00079
00080
00081
00082
00083 static VALUE pointer_deference(VALUE self)
00084 {
00085 VALUE pointed_to = rb_iv_get(self, "@points_to");
00086 if (!NIL_P(pointed_to))
00087 return pointed_to;
00088
00089 Value const& value(rb2cxx::object<Value>(self));
00090 Indirect const& indirect(static_cast<Indirect const&>(value.getType()));
00091
00092 VALUE registry = value_get_registry(self);
00093
00094 void* ptr_value = *reinterpret_cast<void**>(value.getData());
00095 if (!ptr_value)
00096 rb_raise(rb_eArgError, "cannot deference a NULL pointer");
00097
00098 Value new_value(ptr_value, indirect.getIndirection() );
00099 return cxx2rb::value_wrap(new_value, registry, Qnil);
00100 }
00101
00102
00103
00104
00105
00106 Enum::integral_type rb2cxx::enum_value(VALUE rb_value, Enum const& e)
00107 {
00108
00109 if (TYPE(rb_value) == T_FIXNUM)
00110 {
00111 Enum::integral_type value = FIX2INT(rb_value);
00112 try {
00113 e.get(value);
00114 return value;
00115 }
00116 catch(Enum::ValueNotFound) { }
00117 rb_raise(rb_eArgError, "%i is not a valid value for %s", value, e.getName().c_str());
00118 }
00119
00120 char const* name;
00121 if (SYMBOL_P(rb_value))
00122 name = rb_id2name(SYM2ID(rb_value));
00123 else
00124 name = StringValuePtr(rb_value);
00125
00126 try { return e.get(name); }
00127 catch(Enum::SymbolNotFound) { }
00128 rb_raise(rb_eArgError, "%s is not a valid symbol for %s", name, e.getName().c_str());
00129 }
00130
00131
00132
00133
00134
00135
00136 VALUE enum_keys(VALUE self)
00137 {
00138 if (self == cEnum)
00139 return rb_hash_new();
00140
00141 Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00142
00143 VALUE keys = rb_iv_get(self, "@values");
00144 if (!NIL_P(keys))
00145 return keys;
00146
00147 keys = rb_hash_new();
00148 typedef std::list<std::string> string_list;
00149 string_list names = type.names();
00150 for (string_list::const_iterator it = names.begin(); it != names.end(); ++it)
00151 rb_hash_aset(keys, rb_str_new2(it->c_str()), INT2FIX(type.get(*it)));
00152
00153 rb_iv_set(self, "@values", keys);
00154 return keys;
00155 }
00156
00157
00158
00159
00160
00161
00162 static VALUE enum_value_of(VALUE self, VALUE name)
00163 {
00164 Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00165
00166 try {
00167 int value = type.get(StringValuePtr(name));
00168 return INT2NUM(value);
00169 } catch (Enum::SymbolNotFound) {
00170 rb_raise(rb_eArgError, "this enumeration has no value for %s", StringValuePtr(name));
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 static VALUE enum_name_of(VALUE self, VALUE integer)
00181 {
00182 Enum const& type = static_cast<Enum const&>(rb2cxx::object<Type>(self));
00183
00184 try {
00185 std::string name = type.get(NUM2INT(integer));
00186 return rb_str_new2(name.c_str());
00187 } catch (Enum::ValueNotFound) {
00188 rb_raise(rb_eArgError, "this enumeration has no name for %i", NUM2INT(integer));
00189 }
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 static VALUE indirect_type_deference(VALUE self)
00202 {
00203 VALUE registry = type_get_registry(self);
00204 Type const& type(rb2cxx::object<Type>(self));
00205 Indirect const& indirect(static_cast<Indirect const&>(type));
00206 return cxx2rb::type_wrap(indirect.getIndirection(), registry);
00207 }
00208
00209
00210 static Value array_element(VALUE rbarray, VALUE rbindex)
00211 {
00212 Value& value(rb2cxx::object<Value>(rbarray));
00213 Array const& array(static_cast<Array const&>(value.getType()));
00214 size_t index = NUM2INT(rbindex);
00215
00216 if (index >= array.getDimension())
00217 {
00218 rb_raise(rb_eIndexError, "Out of bounds: %lu > %lu", index, array.getDimension());
00219 return Value();
00220 }
00221
00222 Type const& array_type(array.getIndirection());
00223
00224 int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00225 data += array_type.getSize() * index;
00226 return Value(data, array_type);
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 static VALUE array_get(int argc, VALUE* argv, VALUE self)
00237 {
00238 Value& value = rb2cxx::object<Value>(self);
00239 Array const& array = static_cast<Array const&>(value.getType());
00240 if (array.getDimension() == 0)
00241 return self;
00242
00243 Type const& array_type = array.getIndirection();
00244 VALUE registry = value_get_registry(self);
00245
00246 int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00247 size_t index = NUM2INT(argv[0]);
00248 if (index >= array.getDimension())
00249 rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index, array.getDimension());
00250
00251 if (argc == 1)
00252 {
00253 Value v = Value(data + array_type.getSize() * index, array_type);
00254 return cxx2rb::value_wrap( v, registry, self );
00255 }
00256 else if (argc == 2)
00257 {
00258 VALUE ret = rb_ary_new();
00259 size_t size = NUM2INT(argv[1]);
00260 if (index + size > array.getDimension())
00261 rb_raise(rb_eIndexError, "Out of bounds: %li > %li", index + size - 1, array.getDimension());
00262
00263 for (size_t i = index; i < index + size; ++i)
00264 {
00265 Value v = Value(data + array_type.getSize() * i, array_type);
00266 VALUE rb_v = cxx2rb::value_wrap( v, registry, self );
00267
00268 rb_ary_push(ret, rb_v);
00269 }
00270
00271 return ret;
00272 }
00273 else
00274 rb_raise(rb_eArgError, "invalid argument count (%i for 1 or 2)", argc);
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284 static VALUE array_set(VALUE self, VALUE rbindex, VALUE newvalue)
00285 {
00286 Value element = array_element(self, rbindex);
00287 return typelib_from_ruby(element, newvalue);
00288 }
00289
00290
00291
00292
00293
00294
00295 static VALUE array_do_each(VALUE rbarray)
00296 {
00297 Value& value = rb2cxx::object<Value>(rbarray);
00298 Array const& array = static_cast<Array const&>(value.getType());
00299 if (array.getDimension() == 0)
00300 return rbarray;
00301
00302 Type const& array_type = array.getIndirection();
00303 VALUE registry = value_get_registry(rbarray);
00304
00305 int8_t* data = reinterpret_cast<int8_t*>(value.getData());
00306
00307 for (size_t i = 0; i < array.getDimension(); ++i, data += array_type.getSize())
00308 rb_yield(cxx2rb::value_wrap( Value(data, array_type), registry, rbarray ));
00309
00310 return rbarray;
00311 }
00312
00313
00314
00315
00316
00317
00318 static VALUE array_size(VALUE rbarray)
00319 {
00320 Value& value(rb2cxx::object<Value>(rbarray));
00321 Array const& array(static_cast<Array const&>(value.getType()));
00322 return INT2FIX(array.getDimension());
00323 }
00324
00325
00326
00327
00328
00329
00330 static VALUE array_class_length(VALUE rbarray)
00331 {
00332 Array const& array(dynamic_cast<Array const&>(rb2cxx::object<Type>(rbarray)));
00333 return INT2FIX(array.getDimension());
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 static VALUE pointer_nil_p(VALUE self)
00343 {
00344 Value const& value(rb2cxx::object<Value>(self));
00345 if ( *reinterpret_cast<void**>(value.getData()) == 0 )
00346 return Qtrue;
00347 return Qfalse;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 static VALUE numeric_type_integer_p(VALUE self)
00357 {
00358 Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00359 return type.getNumericCategory() == Numeric::Float ? Qfalse : Qtrue;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 static VALUE numeric_type_size(VALUE self)
00369 {
00370 Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00371 return INT2FIX(type.getSize());
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 static VALUE numeric_type_unsigned_p(VALUE self)
00382 {
00383 Numeric const& type(dynamic_cast<Numeric const&>(rb2cxx::object<Type>(self)));
00384 switch(type.getNumericCategory())
00385 {
00386 case Numeric::SInt: return Qfalse;
00387 case Numeric::UInt: return Qtrue;
00388 case Numeric::Float:
00389 rb_raise(rb_eArgError, "not an integral type");
00390 default:
00391 return Qnil;
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 static VALUE container_kind(VALUE self)
00404 {
00405 Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00406 return rb_str_new2(type.kind().c_str());
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 static VALUE container_natural_size(VALUE self)
00418 {
00419 Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00420 return INT2FIX(type.getNaturalSize());
00421 }
00422
00423
00424
00425
00426
00427
00428
00429 static VALUE container_random_access_p(VALUE self)
00430 {
00431 Container const& type(dynamic_cast<Container const&>(rb2cxx::object<Type>(self)));
00432 return type.isRandomAccess() ? Qtrue : Qfalse;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442 static VALUE container_length(VALUE self)
00443 {
00444 Value value = rb2cxx::object<Value>(self);
00445 Container const& type(dynamic_cast<Container const&>(value.getType()));
00446
00447 return INT2NUM(type.getElementCount(value.getData()));
00448 }
00449
00450
00451
00452
00453
00454
00455
00456 static VALUE container_clear(VALUE self)
00457 {
00458 Value value = rb2cxx::object<Value>(self);
00459 Container const& type(dynamic_cast<Container const&>(value.getType()));
00460
00461 type.clear(value.getData());
00462 return Qnil;
00463 }
00464
00465 static Typelib::Value container_element(uint64_t* buffer10, Type const& element_t, VALUE obj)
00466 {
00467 Typelib::Value element_v;
00468 if (element_t.getCategory() == Type::Numeric && sizeof(int64_t) * 10 >= element_t.getSize())
00469 {
00470
00471
00472 element_v = Value(buffer10, element_t);
00473 typelib_from_ruby(element_v, obj);
00474 }
00475 else
00476 {
00477 element_v = rb2cxx::object<Value>(obj);
00478 if (element_t != element_v.getType())
00479 rb_raise(rb_eArgError, "wrong type %s for new element, expected %s", element_v.getType().getName().c_str(), element_t.getName().c_str());
00480 }
00481 return element_v;
00482 }
00483
00484 static VALUE container_do_push(VALUE self, VALUE obj)
00485 {
00486 Value container_v = rb2cxx::object<Value>(self);
00487 Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00488
00489 uint64_t buffer[10];
00490 Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00491 container_t.push(container_v.getData(), element_v);
00492 return self;
00493 }
00494
00495 static VALUE container_do_set(VALUE self, VALUE index, VALUE obj)
00496 {
00497 Value container_v = rb2cxx::object<Value>(self);
00498 Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00499
00500 uint64_t buffer[10];
00501 Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00502 container_t.setElement(container_v.getData(), NUM2INT(index), element_v);
00503 return self;
00504 }
00505
00506 static VALUE container_do_get(VALUE self, VALUE index, VALUE raw)
00507 {
00508 Value container_v = rb2cxx::object<Value>(self);
00509 Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00510 VALUE registry = value_get_registry(self);
00511
00512 Value v = container_t.getElement(container_v.getData(), NUM2INT(index));
00513 if (RTEST(raw))
00514 return cxx2rb::value_wrap(v, registry, self);
00515 else return typelib_to_ruby(v, registry, self);
00516 }
00517
00518 struct ContainerIterator : public ValueVisitor
00519 {
00520 VALUE m_registry;
00521 VALUE m_parent;
00522 bool m_raw;
00523
00524 ContainerIterator(VALUE registry, VALUE parent, bool raw)
00525 {
00526 m_registry = registry;
00527 m_parent = parent;
00528 m_raw = raw;
00529 }
00530 virtual void dispatch(Value v)
00531 {
00532 if (m_raw)
00533 rb_yield(cxx2rb::value_wrap(v, m_registry, m_parent));
00534 else
00535 rb_yield(typelib_to_ruby(v, m_registry, m_parent));
00536 }
00537 };
00538
00539
00540
00541
00542
00543
00544
00545 static VALUE container_each(VALUE self, VALUE raw)
00546 {
00547 Value value = rb2cxx::object<Value>(self);
00548 VALUE registry = value_get_registry(self);
00549 ContainerIterator iterator(registry, self, RTEST(raw));
00550 dynamic_cast<Typelib::Container const&>(value.getType()).visit(value.getData(), iterator);
00551 return self;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561 static VALUE container_erase(VALUE self, VALUE obj)
00562 {
00563 Value container_v = rb2cxx::object<Value>(self);
00564 Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00565
00566 uint64_t buffer[10];
00567 Value element_v = container_element(buffer, container_t.getIndirection(), obj);
00568
00569 if (container_t.erase(container_v.getData(), element_v))
00570 return Qtrue;
00571 else
00572 return Qfalse;
00573 }
00574
00575 bool container_delete_if_i(Value v, VALUE registry, VALUE container)
00576 {
00577 VALUE rb_v = cxx2rb::value_wrap(v, registry, container);
00578 if (RTEST(rb_yield(rb_v)))
00579 return true;
00580 return false;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589 static VALUE container_delete_if(VALUE self)
00590 {
00591 Value container_v = rb2cxx::object<Value>(self);
00592 Container const& container_t(dynamic_cast<Container const&>(container_v.getType()));
00593
00594 VALUE registry = value_get_registry(self);
00595 container_t.delete_if(container_v.getData(), boost::bind(container_delete_if_i, _1, registry, self));
00596 return self;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605 static VALUE vector_contained_memory_id(VALUE self)
00606 {
00607 Value container_v = rb2cxx::object<Value>(self);
00608 std::vector<uint8_t> const* vector = reinterpret_cast<std::vector<uint8_t>*>(container_v.getData());
00609 if (vector->empty())
00610 return Qnil;
00611 return ULL2NUM(reinterpret_cast<uint64_t>(&(*vector)[0]));
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621 static VALUE vector_raw_memcpy(VALUE self,VALUE _source,VALUE _size)
00622 {
00623 Value container_v = rb2cxx::object<Value>(self);
00624 Container const& container_t = static_cast<Container const&>(container_v.getType());
00625 bool is_memcpy = false;
00626 bool no_layout = false;
00627 try
00628 {
00629 MemoryLayout ops = Typelib::layout_of(container_t.getIndirection());
00630 is_memcpy = (ops.size() == 2 && ops[0] == MemLayout::FLAG_MEMCPY);
00631 }
00632 catch(std::runtime_error) { no_layout = true; }
00633 if(no_layout)
00634 rb_raise(rb_eTypeError, "no layout available for elements of %s", container_t.getName().c_str());
00635 if(!is_memcpy)
00636 rb_raise(rb_eTypeError, "raw_memcpy is not supported for vectors of type %s", container_t.getName().c_str());
00637
00638 unsigned int element_size = container_t.getIndirection().getSize();
00639 unsigned int size = NUM2UINT(_size);
00640 if (size % element_size)
00641 rb_raise(rb_eArgError, "provided size in bytes (%u) is not a round number of elements for vectors of type %s (each element is %u bytes in size)", size, container_t.getName().c_str(), element_size);
00642
00643 std::vector<uint8_t> *vector = reinterpret_cast<std::vector<uint8_t>*>(container_v.getData());
00644 const void *source = reinterpret_cast<const void*>(NUM2ULL(_source));
00645 vector->resize(size);
00646 memcpy(&(*vector)[0],source,size);
00647 return Qnil;
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657 static VALUE numeric_to_ruby(VALUE mod, VALUE self)
00658 {
00659 Value const& value(rb2cxx::object<Value>(self));
00660 VALUE registry = value_get_registry(self);
00661 try {
00662 return typelib_to_ruby(value, registry, Qnil);
00663 } catch(Typelib::NullTypeFound) { }
00664 rb_raise(rb_eTypeError, "trying to convert 'void'");
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 static VALUE numeric_from_ruby(VALUE self, VALUE arg)
00677 {
00678 Value& value(rb2cxx::object<Value>(self));
00679 try {
00680 typelib_from_ruby(value, arg);
00681 return self;
00682 } catch(Typelib::UnsupportedType) { }
00683 rb_raise(rb_eTypeError, "cannot perform the requested convertion");
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 void typelib_ruby::Typelib_init_specialized_types()
00712 {
00713 VALUE mTypelib = rb_define_module("Typelib");
00714 cNumeric = rb_define_class_under(mTypelib, "NumericType", cType);
00715 rb_define_singleton_method(cNumeric, "integer?", RUBY_METHOD_FUNC(numeric_type_integer_p), 0);
00716 rb_define_singleton_method(cNumeric, "unsigned?", RUBY_METHOD_FUNC(numeric_type_unsigned_p), 0);
00717 rb_define_singleton_method(cNumeric, "size", RUBY_METHOD_FUNC(numeric_type_size), 0);
00718 rb_define_singleton_method(cNumeric, "to_ruby", RUBY_METHOD_FUNC(&numeric_to_ruby), 1);
00719 rb_define_method(cNumeric, "typelib_from_ruby", RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00720
00721 cOpaque = rb_define_class_under(mTypelib, "OpaqueType", cType);
00722 cNull = rb_define_class_under(mTypelib, "NullType", cType);
00723
00724 cIndirect = rb_define_class_under(mTypelib, "IndirectType", cType);
00725 rb_define_singleton_method(cIndirect, "deference", RUBY_METHOD_FUNC(indirect_type_deference), 0);
00726
00727 cPointer = rb_define_class_under(mTypelib, "PointerType", cIndirect);
00728 rb_define_method(cPointer, "deference", RUBY_METHOD_FUNC(pointer_deference), 0);
00729 rb_define_method(cPointer, "null?", RUBY_METHOD_FUNC(pointer_nil_p), 0);
00730
00731 cCompound = rb_define_class_under(mTypelib, "CompoundType", cType);
00732 rb_define_singleton_method(cCompound, "get_fields", RUBY_METHOD_FUNC(compound_get_fields), 0);
00733 rb_define_method(cCompound, "typelib_get_field", RUBY_METHOD_FUNC(compound_field_get), 2);
00734 rb_define_method(cCompound, "typelib_set_field", RUBY_METHOD_FUNC(compound_field_set), 2);
00735
00736 cEnum = rb_define_class_under(mTypelib, "EnumType", cType);
00737 rb_define_singleton_method(cEnum, "keys", RUBY_METHOD_FUNC(enum_keys), 0);
00738 rb_define_singleton_method(cEnum, "value_of", RUBY_METHOD_FUNC(enum_value_of), 1);
00739 rb_define_singleton_method(cEnum, "name_of", RUBY_METHOD_FUNC(enum_name_of), 1);
00740 rb_define_singleton_method(cEnum, "to_ruby", RUBY_METHOD_FUNC(&numeric_to_ruby), 1);
00741 rb_define_method(cEnum, "typelib_from_ruby", RUBY_METHOD_FUNC(&numeric_from_ruby), 1);
00742
00743 cArray = rb_define_class_under(mTypelib, "ArrayType", cIndirect);
00744 rb_define_singleton_method(cArray, "length", RUBY_METHOD_FUNC(array_class_length), 0);
00745 rb_define_method(cArray, "do_get", RUBY_METHOD_FUNC(array_get), -1);
00746 rb_define_method(cArray, "do_set", RUBY_METHOD_FUNC(array_set), 2);
00747 rb_define_method(cArray, "do_each", RUBY_METHOD_FUNC(array_do_each), 0);
00748 rb_define_method(cArray, "size", RUBY_METHOD_FUNC(array_size), 0);
00749
00750 cContainer = rb_define_class_under(mTypelib, "ContainerType", cIndirect);
00751 rb_define_singleton_method(cContainer, "container_kind", RUBY_METHOD_FUNC(container_kind), 0);
00752 rb_define_singleton_method(cContainer, "natural_size", RUBY_METHOD_FUNC(container_natural_size), 0);
00753 rb_define_singleton_method(cContainer, "random_access?", RUBY_METHOD_FUNC(container_random_access_p), 0);
00754 rb_define_method(cContainer, "length", RUBY_METHOD_FUNC(container_length), 0);
00755 rb_define_method(cContainer, "size", RUBY_METHOD_FUNC(container_length), 0);
00756 rb_define_method(cContainer, "do_clear", RUBY_METHOD_FUNC(container_clear), 0);
00757 rb_define_method(cContainer, "do_push", RUBY_METHOD_FUNC(container_do_push), 1);
00758 rb_define_method(cContainer, "do_get", RUBY_METHOD_FUNC(container_do_get), 2);
00759 rb_define_method(cContainer, "do_set", RUBY_METHOD_FUNC(container_do_set), 2);
00760 rb_define_method(cContainer, "do_each", RUBY_METHOD_FUNC(container_each), 1);
00761 rb_define_method(cContainer, "do_erase", RUBY_METHOD_FUNC(container_erase), 1);
00762 rb_define_method(cContainer, "do_delete_if", RUBY_METHOD_FUNC(container_delete_if), 0);
00763
00764 VALUE mVector = rb_define_module_under(cContainer, "StdVector");
00765 rb_define_method(mVector, "contained_memory_id", RUBY_METHOD_FUNC(vector_contained_memory_id), 0);
00766 rb_define_method(mVector, "raw_memcpy", RUBY_METHOD_FUNC(vector_raw_memcpy), 2);
00767 }
00768