00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "ruby/ruby.h"
00016 #include "node.h"
00017 #include "internal.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 VALUE rb_cEnumerator;
00101 static ID id_rewind, id_each;
00102 static VALUE sym_each;
00103
00104 VALUE rb_eStopIteration;
00105
00106 struct enumerator {
00107 VALUE obj;
00108 ID meth;
00109 VALUE args;
00110 VALUE fib;
00111 VALUE dst;
00112 VALUE lookahead;
00113 VALUE feedvalue;
00114 VALUE stop_exc;
00115 };
00116
00117 static VALUE rb_cGenerator, rb_cYielder;
00118
00119 struct generator {
00120 VALUE proc;
00121 };
00122
00123 struct yielder {
00124 VALUE proc;
00125 };
00126
00127 static VALUE generator_allocate(VALUE klass);
00128 static VALUE generator_init(VALUE obj, VALUE proc);
00129
00130
00131
00132
00133 static void
00134 enumerator_mark(void *p)
00135 {
00136 struct enumerator *ptr = p;
00137 rb_gc_mark(ptr->obj);
00138 rb_gc_mark(ptr->args);
00139 rb_gc_mark(ptr->fib);
00140 rb_gc_mark(ptr->dst);
00141 rb_gc_mark(ptr->lookahead);
00142 rb_gc_mark(ptr->feedvalue);
00143 rb_gc_mark(ptr->stop_exc);
00144 }
00145
00146 #define enumerator_free RUBY_TYPED_DEFAULT_FREE
00147
00148 static size_t
00149 enumerator_memsize(const void *p)
00150 {
00151 return p ? sizeof(struct enumerator) : 0;
00152 }
00153
00154 static const rb_data_type_t enumerator_data_type = {
00155 "enumerator",
00156 {
00157 enumerator_mark,
00158 enumerator_free,
00159 enumerator_memsize,
00160 },
00161 };
00162
00163 static struct enumerator *
00164 enumerator_ptr(VALUE obj)
00165 {
00166 struct enumerator *ptr;
00167
00168 TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr);
00169 if (!ptr || ptr->obj == Qundef) {
00170 rb_raise(rb_eArgError, "uninitialized enumerator");
00171 }
00172 return ptr;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static VALUE
00204 obj_to_enum(int argc, VALUE *argv, VALUE obj)
00205 {
00206 VALUE meth = sym_each;
00207
00208 if (argc > 0) {
00209 --argc;
00210 meth = *argv++;
00211 }
00212 return rb_enumeratorize(obj, meth, argc, argv);
00213 }
00214
00215 static VALUE
00216 enumerator_allocate(VALUE klass)
00217 {
00218 struct enumerator *ptr;
00219 VALUE enum_obj;
00220
00221 enum_obj = TypedData_Make_Struct(klass, struct enumerator, &enumerator_data_type, ptr);
00222 ptr->obj = Qundef;
00223
00224 return enum_obj;
00225 }
00226
00227 static VALUE
00228 enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv)
00229 {
00230 struct enumerator *ptr;
00231
00232 TypedData_Get_Struct(enum_obj, struct enumerator, &enumerator_data_type, ptr);
00233
00234 if (!ptr) {
00235 rb_raise(rb_eArgError, "unallocated enumerator");
00236 }
00237
00238 ptr->obj = obj;
00239 ptr->meth = rb_to_id(meth);
00240 if (argc) ptr->args = rb_ary_new4(argc, argv);
00241 ptr->fib = 0;
00242 ptr->dst = Qnil;
00243 ptr->lookahead = Qundef;
00244 ptr->feedvalue = Qundef;
00245 ptr->stop_exc = Qfalse;
00246
00247 return enum_obj;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 static VALUE
00285 enumerator_initialize(int argc, VALUE *argv, VALUE obj)
00286 {
00287 VALUE recv, meth = sym_each;
00288
00289 if (argc == 0) {
00290 if (!rb_block_given_p())
00291 rb_raise(rb_eArgError, "wrong number of argument (0 for 1+)");
00292
00293 recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
00294 }
00295 else {
00296 recv = *argv++;
00297 if (--argc) {
00298 meth = *argv++;
00299 --argc;
00300 }
00301 }
00302
00303 return enumerator_init(obj, recv, meth, argc, argv);
00304 }
00305
00306
00307 static VALUE
00308 enumerator_init_copy(VALUE obj, VALUE orig)
00309 {
00310 struct enumerator *ptr0, *ptr1;
00311
00312 ptr0 = enumerator_ptr(orig);
00313 if (ptr0->fib) {
00314
00315 rb_raise(rb_eTypeError, "can't copy execution context");
00316 }
00317
00318 TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr1);
00319
00320 if (!ptr1) {
00321 rb_raise(rb_eArgError, "unallocated enumerator");
00322 }
00323
00324 ptr1->obj = ptr0->obj;
00325 ptr1->meth = ptr0->meth;
00326 ptr1->args = ptr0->args;
00327 ptr1->fib = 0;
00328 ptr1->lookahead = Qundef;
00329 ptr1->feedvalue = Qundef;
00330
00331 return obj;
00332 }
00333
00334 VALUE
00335 rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
00336 {
00337 return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);
00338 }
00339
00340 static VALUE
00341 enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
00342 {
00343 int argc = 0;
00344 VALUE *argv = 0;
00345 const struct enumerator *e = enumerator_ptr(obj);
00346 ID meth = e->meth;
00347
00348 if (e->args) {
00349 argc = RARRAY_LENINT(e->args);
00350 argv = RARRAY_PTR(e->args);
00351 }
00352 return rb_block_call(e->obj, meth, argc, argv, func, arg);
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 static VALUE
00364 enumerator_each(VALUE obj)
00365 {
00366 if (!rb_block_given_p()) return obj;
00367 return enumerator_block_call(obj, 0, obj);
00368 }
00369
00370 static VALUE
00371 enumerator_with_index_i(VALUE val, VALUE m, int argc, VALUE *argv)
00372 {
00373 NODE *memo = (NODE *)m;
00374 VALUE idx = memo->u1.value;
00375 memo->u1.value = rb_int_succ(idx);
00376
00377 if (argc <= 1)
00378 return rb_yield_values(2, val, idx);
00379
00380 return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 static VALUE
00396 enumerator_with_index(int argc, VALUE *argv, VALUE obj)
00397 {
00398 VALUE memo;
00399
00400 rb_scan_args(argc, argv, "01", &memo);
00401 RETURN_ENUMERATOR(obj, argc, argv);
00402 if (NIL_P(memo))
00403 memo = INT2FIX(0);
00404 else
00405 memo = rb_to_int(memo);
00406 return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)NEW_MEMO(memo, 0, 0));
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 static VALUE
00420 enumerator_each_with_index(VALUE obj)
00421 {
00422 return enumerator_with_index(0, NULL, obj);
00423 }
00424
00425 static VALUE
00426 enumerator_with_object_i(VALUE val, VALUE memo, int argc, VALUE *argv)
00427 {
00428 if (argc <= 1)
00429 return rb_yield_values(2, val, memo);
00430
00431 return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 static VALUE
00462 enumerator_with_object(VALUE obj, VALUE memo)
00463 {
00464 RETURN_ENUMERATOR(obj, 1, &memo);
00465 enumerator_block_call(obj, enumerator_with_object_i, memo);
00466
00467 return memo;
00468 }
00469
00470 static VALUE
00471 next_ii(VALUE i, VALUE obj, int argc, VALUE *argv)
00472 {
00473 struct enumerator *e = enumerator_ptr(obj);
00474 VALUE feedvalue = Qnil;
00475 VALUE args = rb_ary_new4(argc, argv);
00476 rb_fiber_yield(1, &args);
00477 if (e->feedvalue != Qundef) {
00478 feedvalue = e->feedvalue;
00479 e->feedvalue = Qundef;
00480 }
00481 return feedvalue;
00482 }
00483
00484 static VALUE
00485 next_i(VALUE curr, VALUE obj)
00486 {
00487 struct enumerator *e = enumerator_ptr(obj);
00488 VALUE nil = Qnil;
00489 VALUE result;
00490
00491 result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
00492 e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
00493 rb_ivar_set(e->stop_exc, rb_intern("result"), result);
00494 return rb_fiber_yield(1, &nil);
00495 }
00496
00497 static void
00498 next_init(VALUE obj, struct enumerator *e)
00499 {
00500 VALUE curr = rb_fiber_current();
00501 e->dst = curr;
00502 e->fib = rb_fiber_new(next_i, obj);
00503 e->lookahead = Qundef;
00504 }
00505
00506 static VALUE
00507 get_next_values(VALUE obj, struct enumerator *e)
00508 {
00509 VALUE curr, vs;
00510
00511 if (e->stop_exc)
00512 rb_exc_raise(e->stop_exc);
00513
00514 curr = rb_fiber_current();
00515
00516 if (!e->fib || !rb_fiber_alive_p(e->fib)) {
00517 next_init(obj, e);
00518 }
00519
00520 vs = rb_fiber_resume(e->fib, 1, &curr);
00521 if (e->stop_exc) {
00522 e->fib = 0;
00523 e->dst = Qnil;
00524 e->lookahead = Qundef;
00525 e->feedvalue = Qundef;
00526 rb_exc_raise(e->stop_exc);
00527 }
00528 return vs;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 static VALUE
00579 enumerator_next_values(VALUE obj)
00580 {
00581 struct enumerator *e = enumerator_ptr(obj);
00582 VALUE vs;
00583
00584 if (e->lookahead != Qundef) {
00585 vs = e->lookahead;
00586 e->lookahead = Qundef;
00587 return vs;
00588 }
00589
00590 return get_next_values(obj, e);
00591 }
00592
00593 static VALUE
00594 ary2sv(VALUE args, int dup)
00595 {
00596 if (TYPE(args) != T_ARRAY)
00597 return args;
00598
00599 switch (RARRAY_LEN(args)) {
00600 case 0:
00601 return Qnil;
00602
00603 case 1:
00604 return RARRAY_PTR(args)[0];
00605
00606 default:
00607 if (dup)
00608 return rb_ary_dup(args);
00609 return args;
00610 }
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 static VALUE
00636 enumerator_next(VALUE obj)
00637 {
00638 VALUE vs = enumerator_next_values(obj);
00639 return ary2sv(vs, 0);
00640 }
00641
00642 static VALUE
00643 enumerator_peek_values(VALUE obj)
00644 {
00645 struct enumerator *e = enumerator_ptr(obj);
00646
00647 if (e->lookahead == Qundef) {
00648 e->lookahead = get_next_values(obj, e);
00649 }
00650 return e->lookahead;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 static VALUE
00682 enumerator_peek_values_m(VALUE obj)
00683 {
00684 return rb_ary_dup(enumerator_peek_values(obj));
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 static VALUE
00710 enumerator_peek(VALUE obj)
00711 {
00712 VALUE vs = enumerator_peek_values(obj);
00713 return ary2sv(vs, 1);
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 static VALUE
00745 enumerator_feed(VALUE obj, VALUE v)
00746 {
00747 struct enumerator *e = enumerator_ptr(obj);
00748
00749 if (e->feedvalue != Qundef) {
00750 rb_raise(rb_eTypeError, "feed value already set");
00751 }
00752 e->feedvalue = v;
00753
00754 return Qnil;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 static VALUE
00767 enumerator_rewind(VALUE obj)
00768 {
00769 struct enumerator *e = enumerator_ptr(obj);
00770
00771 rb_check_funcall(e->obj, id_rewind, 0, 0);
00772
00773 e->fib = 0;
00774 e->dst = Qnil;
00775 e->lookahead = Qundef;
00776 e->feedvalue = Qundef;
00777 e->stop_exc = Qfalse;
00778 return obj;
00779 }
00780
00781 static VALUE
00782 inspect_enumerator(VALUE obj, VALUE dummy, int recur)
00783 {
00784 struct enumerator *e;
00785 const char *cname;
00786 VALUE eobj, str;
00787 int tainted, untrusted;
00788
00789 TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e);
00790
00791 cname = rb_obj_classname(obj);
00792
00793 if (!e || e->obj == Qundef) {
00794 return rb_sprintf("#<%s: uninitialized>", cname);
00795 }
00796
00797 if (recur) {
00798 str = rb_sprintf("#<%s: ...>", cname);
00799 OBJ_TAINT(str);
00800 return str;
00801 }
00802
00803 eobj = e->obj;
00804
00805 tainted = OBJ_TAINTED(eobj);
00806 untrusted = OBJ_UNTRUSTED(eobj);
00807
00808
00809 str = rb_sprintf("#<%s: ", cname);
00810 rb_str_concat(str, rb_inspect(eobj));
00811 rb_str_buf_cat2(str, ":");
00812 rb_str_buf_cat2(str, rb_id2name(e->meth));
00813
00814 if (e->args) {
00815 long argc = RARRAY_LEN(e->args);
00816 VALUE *argv = RARRAY_PTR(e->args);
00817
00818 rb_str_buf_cat2(str, "(");
00819
00820 while (argc--) {
00821 VALUE arg = *argv++;
00822
00823 rb_str_concat(str, rb_inspect(arg));
00824 rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
00825
00826 if (OBJ_TAINTED(arg)) tainted = TRUE;
00827 if (OBJ_UNTRUSTED(arg)) untrusted = TRUE;
00828 }
00829 }
00830
00831 rb_str_buf_cat2(str, ">");
00832
00833 if (tainted) OBJ_TAINT(str);
00834 if (untrusted) OBJ_UNTRUST(str);
00835 return str;
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845 static VALUE
00846 enumerator_inspect(VALUE obj)
00847 {
00848 return rb_exec_recursive(inspect_enumerator, obj, 0);
00849 }
00850
00851
00852
00853
00854 static void
00855 yielder_mark(void *p)
00856 {
00857 struct yielder *ptr = p;
00858 rb_gc_mark(ptr->proc);
00859 }
00860
00861 #define yielder_free RUBY_TYPED_DEFAULT_FREE
00862
00863 static size_t
00864 yielder_memsize(const void *p)
00865 {
00866 return p ? sizeof(struct yielder) : 0;
00867 }
00868
00869 static const rb_data_type_t yielder_data_type = {
00870 "yielder",
00871 {
00872 yielder_mark,
00873 yielder_free,
00874 yielder_memsize,
00875 },
00876 };
00877
00878 static struct yielder *
00879 yielder_ptr(VALUE obj)
00880 {
00881 struct yielder *ptr;
00882
00883 TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
00884 if (!ptr || ptr->proc == Qundef) {
00885 rb_raise(rb_eArgError, "uninitialized yielder");
00886 }
00887 return ptr;
00888 }
00889
00890
00891 static VALUE
00892 yielder_allocate(VALUE klass)
00893 {
00894 struct yielder *ptr;
00895 VALUE obj;
00896
00897 obj = TypedData_Make_Struct(klass, struct yielder, &yielder_data_type, ptr);
00898 ptr->proc = Qundef;
00899
00900 return obj;
00901 }
00902
00903 static VALUE
00904 yielder_init(VALUE obj, VALUE proc)
00905 {
00906 struct yielder *ptr;
00907
00908 TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
00909
00910 if (!ptr) {
00911 rb_raise(rb_eArgError, "unallocated yielder");
00912 }
00913
00914 ptr->proc = proc;
00915
00916 return obj;
00917 }
00918
00919
00920 static VALUE
00921 yielder_initialize(VALUE obj)
00922 {
00923 rb_need_block();
00924
00925 return yielder_init(obj, rb_block_proc());
00926 }
00927
00928
00929 static VALUE
00930 yielder_yield(VALUE obj, VALUE args)
00931 {
00932 struct yielder *ptr = yielder_ptr(obj);
00933
00934 return rb_proc_call(ptr->proc, args);
00935 }
00936
00937
00938 static VALUE yielder_yield_push(VALUE obj, VALUE args)
00939 {
00940 yielder_yield(obj, args);
00941 return obj;
00942 }
00943
00944 static VALUE
00945 yielder_yield_i(VALUE obj, VALUE memo, int argc, VALUE *argv)
00946 {
00947 return rb_yield_values2(argc, argv);
00948 }
00949
00950 static VALUE
00951 yielder_new(void)
00952 {
00953 return yielder_init(yielder_allocate(rb_cYielder), rb_proc_new(yielder_yield_i, 0));
00954 }
00955
00956
00957
00958
00959 static void
00960 generator_mark(void *p)
00961 {
00962 struct generator *ptr = p;
00963 rb_gc_mark(ptr->proc);
00964 }
00965
00966 #define generator_free RUBY_TYPED_DEFAULT_FREE
00967
00968 static size_t
00969 generator_memsize(const void *p)
00970 {
00971 return p ? sizeof(struct generator) : 0;
00972 }
00973
00974 static const rb_data_type_t generator_data_type = {
00975 "generator",
00976 {
00977 generator_mark,
00978 generator_free,
00979 generator_memsize,
00980 },
00981 };
00982
00983 static struct generator *
00984 generator_ptr(VALUE obj)
00985 {
00986 struct generator *ptr;
00987
00988 TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
00989 if (!ptr || ptr->proc == Qundef) {
00990 rb_raise(rb_eArgError, "uninitialized generator");
00991 }
00992 return ptr;
00993 }
00994
00995
00996 static VALUE
00997 generator_allocate(VALUE klass)
00998 {
00999 struct generator *ptr;
01000 VALUE obj;
01001
01002 obj = TypedData_Make_Struct(klass, struct generator, &generator_data_type, ptr);
01003 ptr->proc = Qundef;
01004
01005 return obj;
01006 }
01007
01008 static VALUE
01009 generator_init(VALUE obj, VALUE proc)
01010 {
01011 struct generator *ptr;
01012
01013 TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
01014
01015 if (!ptr) {
01016 rb_raise(rb_eArgError, "unallocated generator");
01017 }
01018
01019 ptr->proc = proc;
01020
01021 return obj;
01022 }
01023
01024
01025 static VALUE
01026 generator_initialize(int argc, VALUE *argv, VALUE obj)
01027 {
01028 VALUE proc;
01029
01030 if (argc == 0) {
01031 rb_need_block();
01032
01033 proc = rb_block_proc();
01034 } else {
01035 rb_scan_args(argc, argv, "1", &proc);
01036
01037 if (!rb_obj_is_proc(proc))
01038 rb_raise(rb_eTypeError,
01039 "wrong argument type %s (expected Proc)",
01040 rb_obj_classname(proc));
01041
01042 if (rb_block_given_p()) {
01043 rb_warn("given block not used");
01044 }
01045 }
01046
01047 return generator_init(obj, proc);
01048 }
01049
01050
01051 static VALUE
01052 generator_init_copy(VALUE obj, VALUE orig)
01053 {
01054 struct generator *ptr0, *ptr1;
01055
01056 ptr0 = generator_ptr(orig);
01057
01058 TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
01059
01060 if (!ptr1) {
01061 rb_raise(rb_eArgError, "unallocated generator");
01062 }
01063
01064 ptr1->proc = ptr0->proc;
01065
01066 return obj;
01067 }
01068
01069
01070 static VALUE
01071 generator_each(VALUE obj)
01072 {
01073 struct generator *ptr = generator_ptr(obj);
01074 VALUE yielder;
01075
01076 yielder = yielder_new();
01077
01078 return rb_proc_call(ptr->proc, rb_ary_new3(1, yielder));
01079 }
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 static VALUE
01128 stop_result(VALUE self)
01129 {
01130 return rb_attr_get(self, rb_intern("result"));
01131 }
01132
01133 void
01134 Init_Enumerator(void)
01135 {
01136 rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
01137 rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
01138
01139 rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
01140 rb_include_module(rb_cEnumerator, rb_mEnumerable);
01141
01142 rb_define_alloc_func(rb_cEnumerator, enumerator_allocate);
01143 rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
01144 rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
01145 rb_define_method(rb_cEnumerator, "each", enumerator_each, 0);
01146 rb_define_method(rb_cEnumerator, "each_with_index", enumerator_each_with_index, 0);
01147 rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
01148 rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, -1);
01149 rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1);
01150 rb_define_method(rb_cEnumerator, "next_values", enumerator_next_values, 0);
01151 rb_define_method(rb_cEnumerator, "peek_values", enumerator_peek_values_m, 0);
01152 rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
01153 rb_define_method(rb_cEnumerator, "peek", enumerator_peek, 0);
01154 rb_define_method(rb_cEnumerator, "feed", enumerator_feed, 1);
01155 rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
01156 rb_define_method(rb_cEnumerator, "inspect", enumerator_inspect, 0);
01157
01158 rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
01159 rb_define_method(rb_eStopIteration, "result", stop_result, 0);
01160
01161
01162 rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
01163 rb_include_module(rb_cGenerator, rb_mEnumerable);
01164 rb_define_alloc_func(rb_cGenerator, generator_allocate);
01165 rb_define_method(rb_cGenerator, "initialize", generator_initialize, -1);
01166 rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
01167 rb_define_method(rb_cGenerator, "each", generator_each, 0);
01168
01169
01170 rb_cYielder = rb_define_class_under(rb_cEnumerator, "Yielder", rb_cObject);
01171 rb_define_alloc_func(rb_cYielder, yielder_allocate);
01172 rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
01173 rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
01174 rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2);
01175
01176 id_rewind = rb_intern("rewind");
01177 id_each = rb_intern("each");
01178 sym_each = ID2SYM(id_each);
01179
01180 rb_provide("enumerator.so");
01181 }
01182