From: nobu.nakada@... Date: 2000-02-05T15:17:43+09:00 Subject: [ruby-list:20504] Re: Wrapping Regexp in C++ --Multipart_Sat_Feb__5_15:11:22_2000-1 Content-Type: text/plain; charset=ISO-2022-JP なかだです。 At Sat, 5 Feb 2000 03:49:03 +0900, OZAWA Sakuro wrote: > > > VALUE Object::objects = rb_ary_new(); > > あいや、もとい。 > > VALUE Object::objects = (ruby_init(), rb_ary_new()); > > ぐはぁ(吐血) > C++のstaticメンバの初期化って、定数じゃなくてもよかったんだ……。 うぐぅ。あれじゃダメです。Ruby に教えてないじゃん。 rb_global_variable() かましてやんないと。 それに Object::objを初期化する前に Ruby を呼んでるから、そのと きに GC が発生すると問題アリアリかも。 -- そうだ 強気に ちょっと インチキに☆彡 中田 "Bugるくらいがちょうどいいかも;-)" 伸悦 --Multipart_Sat_Feb__5_15:11:22_2000-1 Content-Type: text/plain; Type=Ruby; charset="ISO-2022-JP" Content-Disposition: attachment; filename="extconf.rb" Content-Transfer-Encoding: 7bit require 'mkmf' if have_library("ruby", "ruby_init") have_func("rb_register_address") create_makefile("libruby++") end --Multipart_Sat_Feb__5_15:11:22_2000-1 Content-Type: text/plain; Type=C++; charset="ISO-2022-JP" Content-Disposition: attachment; filename="rbobj" Content-Transfer-Encoding: 7bit /* -*- mode: c++; c-file-style: "ruby" -*- */ #include #include namespace ruby { using namespace std; #include "ruby.h" extern VALUE ruby_errinfo; struct Exception : public runtime_error { VALUE error; Exception() : error(ruby_errinfo) {} }; class Object { static VALUE objects; VALUE obj; protected: operator VALUE() const {return obj;} struct Creator {}; typedef VALUE (*Initializer)(Creator &); Object(const Creator& o, Initializer i); public: Object() : obj(0) {} virtual ~Object(); operator bool() const {return RTEST(obj);} bool operator !() const {return !RTEST(obj);} }; class Array : public Object { protected: struct Creator : public Object::Creator { static VALUE initialize(Creator& arg); Creator(size_t n) : size(n) {} protected: size_t size; }; public: Array(size_t n) : Object(Creator(n), (Initializer)Creator::initialize) {} }; class Regexp : public Object { protected: struct Creator : public Object::Creator { static VALUE initialize(Creator& arg); Creator(const char* s, size_t l, int f) : str(s), length(l), flags(f) {} Creator(const string& s, int f) : str(s.c_str()), length(s.size()), flags(f) {} protected: const char* str; size_t length; int flags; }; public: Regexp(const string& s, int flags = 0) : Object(Creator(s, flags), (Initializer)Creator::initialize) {} Regexp(const char* s, size_t l, int flags = 0) : Object(Creator(s, l, flags), (Initializer)Creator::initialize) {} // string sとマッチした位置を返す。マッチしなければnpos(=-1)を返す。 string::size_type match(const string& s); }; } // namespace ruby --Multipart_Sat_Feb__5_15:11:22_2000-1 Content-Type: text/plain; Type=C++; charset="ISO-2022-JP" Content-Disposition: attachment; filename="rbobj.cc" Content-Transfer-Encoding: 7bit /* -*- mode: c++; c-file-style: "ruby" -*- */ #include "rbobj" namespace ruby { #ifndef HAVE_RB_REGISTER_ADDRESS #define rb_register_address(v) rb_global_variable(v) #define rb_unregister_address(v) ((void)(v)) #endif VALUE Object::objects = (ruby_init(), rb_register_address(&objects), rb_ary_new()); Object::Object(const Creator& c, Initializer i) : obj(0) { int state = 0; obj = rb_protect((VALUE (*)())i, (VALUE)&c, &state); if (state) throw Exception(); if (!rb_special_const_p(obj) && !rb_ary_includes(objects, obj)) rb_ary_push(objects, obj); } Object::~Object() { if (!rb_special_const_p(obj)) rb_ary_delete(objects, obj); obj = 0; } VALUE Array::Creator::initialize(Creator& arg) { return rb_ary_new2(arg.size); } VALUE Regexp::Creator::initialize(Creator& arg) { return rb_reg_new(arg.str, arg.length, arg.flags); } string::size_type Regexp::match(const string& s) { VALUE str = rb_str_new(s.c_str(), s.size()); VALUE result = rb_reg_match(*this, str); if (NIL_P(result)) { return string::npos; // マッチしなかった。 } return NUM2INT(result); // マッチ位置 } } // namespace ruby --Multipart_Sat_Feb__5_15:11:22_2000-1--