#ifndef RBIMPL_ITERATOR_H /*-*-C++-*-vi:se ft=cpp:*/ #define RBIMPL_ITERATOR_H /** * @file * @author Ruby developers * @copyright This file is a part of the programming language Ruby. * Permission is hereby granted, to either redistribute and/or * modify this file, provided that the conditions mentioned in the * file COPYING are met. Consult the file for details. * @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are * implementation details. Don't take them as canon. They could * rapidly appear then vanish. The name (path) of this header file * is also an implementation detail. Do not expect it to persist * at the place it is now. Developers are free to move it anywhere * anytime at will. * @note To ruby-core: remember that this header can be possibly * recursively included from extension libraries written in C++. * Do not expect for instance `__VA_ARGS__` is always available. * We assume C99 for ruby itself but we don't assume languages of * extension libraries. They could be written in C++98. * @brief Block related APIs. */ #include "ruby/internal/attr/deprecated.h" #include "ruby/internal/attr/noreturn.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/value.h" RBIMPL_SYMBOL_EXPORT_BEGIN() /** * @private * * @deprecated This macro once was a thing in the old days, but makes no sense * any longer today. Exists here for backwards compatibility * only. You can safely forget about it. */ #define RB_BLOCK_CALL_FUNC_STRICT 1 /** * @private * * @deprecated This macro once was a thing in the old days, but makes no sense * any longer today. Exists here for backwards compatibility * only. You can safely forget about it. */ #define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1 /** * Shim for block function parameters. Historically ::rb_block_call_func_t had * only two parameters. Over time it evolved to have much more than that. By * using this macro you can absorb such API differences. * * ```CXX * // This works since 2.1.0 * VALUE my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c)); * ``` */ #define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \ VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg /** * This is the type of a function that the interpreter expect for C-backended * blocks. Blocks are often written in Ruby. But C extensions might want to * have their own blocks. In order to do so authors have to create a separate * C function of this type, and pass its pointer to rb_block_call(). * * ```CXX * VALUE * my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c)) * { * const auto plus = rb_intern("+"); * return rb_funcall(c, plus, 1, y); * } * * VALUE * my_own_method(VALUE self) * { * const auto each = rb_intern("each"); * return rb_block_call(self, each, 0, 0, my_own_iterator, self); * } * ``` */ typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)); /** * Shorthand type that represents an iterator-written-in-C function pointer. */ typedef rb_block_call_func *rb_block_call_func_t; /** * This is a shorthand of calling `obj.each`. * * @param[in] obj The receiver. * @return What `obj.each` returns. * * @internal * * Does anyone still need it? This API was to use with rb_iterate(), which is * marked deprecated (see below). Old idiom to call an iterator was: * * ```CXX * VALUE recv; * VALUE iter_func(ANYARGS); * VALUE iter_data; * rb_iterate(rb_each, recv, iter_func, iter_data); * ``` */ VALUE rb_each(VALUE obj); /** * Yields the block. In Ruby there is a concept called a block. You can pass * one to a method. In a method, when called with a block, you can yield it * using this function. * * ```CXX * VALUE * iterate(VALUE self) * { * extern int get_n(VALUE); * extern VALUE get_v(VALUE, VALUE); * const auto n = get_n(self); * * for (int i=0; i