C++でxtalのiteratorを返す関数を作る
さらにしつこくC++からxtalをいじってみてます。
次はC++で書いたxtalのiteratorを、生成して返すC++の関数を作ってみます。(わけわからん)
ちょっとソース読んでごにょごにょしてたら、動いたのでよしとします。
#include "xtal/xtal.h" class IterTest { int value_; public: IterTest(int value) : value_(value) {} void iter_next(const xtal::VMachine& vm) { if (value_ > 10) { vm.return_result(xtal::Null()); return; } vm.return_result(xtal::UserData<IterTest>::from_this(this), xtal::Any(value_)); value_++; } }; //これがiteratorを返す関数 xtal::Any gen_itertest(int value) { return xtal::new_userdata<IterTest, int>(value); } int main() { // Xtalの初期化 xtal::initialize(); try { xtal::TClass<IterTest> itertest("IterTest"); // IterTest クラスを構築 itertest.inherit(xtal::Iterator()); itertest.def("new", xtal::New<IterTest, int>().param(xtal::Named("value", 0))); itertest.method("iter_first", &IterTest::iter_next); itertest.method("iter_next", &IterTest::iter_next); // これを書いておかないとループに入ってメモリを馬鹿食いする xtal::lib().def("IterTest", itertest); xtal::Class iter("iter"); iter.fun("gen", &gen_itertest); xtal::lib().def("iter", iter); xtal::Any ret = xtal::lib().member("iterator"); } catch(xtal::Any ex) { std::cout << ex << std::endl; } return 0; }
コメントに書きましたが、別にlibに登録したくないIterTestを登録しないと、うまく動かなくなっちゃいます。動かすと(おそらくコンパイルで)無限ループに陥り、メモリを馬鹿食いし始めます。
string.cppのStringSPlitImplとか見る限りでは、IterTestは登録しなくてもいいように見えるんだけどなぁ。
test : lib::IterTest(5); test.join("-").p; lib::iter::gen(5).join(",").p;