From 407c4850f19f92c703847cea1e07b3151e1cdc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Thu, 6 May 2021 15:50:02 +0900 Subject: include/ruby/internal/intern/enumerator.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/intern/enumerator.h | 199 ++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/ruby/internal/intern/enumerator.h b/include/ruby/internal/intern/enumerator.h index 2ee88bafe6..20e5d7c6fc 100644 --- a/include/ruby/internal/intern/enumerator.h +++ b/include/ruby/internal/intern/enumerator.h @@ -20,6 +20,7 @@ * extension libraries. They could be written in C++98. * @brief Public APIs related to ::rb_cEnumerator. */ +#include "ruby/internal/attr/nonnull.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/intern/eval.h" /* rb_frame_this_func */ #include "ruby/internal/iterator.h" /* rb_block_given_p */ @@ -28,52 +29,230 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() -typedef VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE); +/** + * This is the type of functions that rb_enumeratorize_with_size() expects. In + * theory an enumerator can have indefinite number of elements, but in practice + * it often is the case we can compute the size of an enumerator beforehand. + * If your enumerator has such property, supply a function that calculates such + * values. + * + * @param[in] recv The original receiver of the enumerator. + * @param[in] argv Arguments passed to `Object#enum_for` etc. + * @param[in] eobj The enumerator object. + * @return The size of `eobj`, in ::rb_cNumeric, or ::RUBY_Qnil if the size + * is not known until we actually iterate. + */ +typedef VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj); +/** + * Decomposed `Enumerator::ArithmeicSequence`. This is a subclass of + * ::rb_cEnumerator, which represents a sequence of numbers with common + * difference. Internal data structure of the class is opaque to users, but + * you can obtain a decomposed one using rb_arithmetic_sequence_extract(). + */ typedef struct { - VALUE begin; - VALUE end; - VALUE step; - int exclude_end; + VALUE begin; /**< "Left" or "lowest" endpoint of the sequence. */ + VALUE end; /**< "Right" or "highest" endpoint of the sequence.*/ + VALUE step; /**< Step between a sequence. */ + int exclude_end; /**< Whether the endpoint is open or closed. */ } rb_arithmetic_sequence_components_t; /* enumerator.c */ -VALUE rb_enumeratorize(VALUE, VALUE, int, const VALUE *); -VALUE rb_enumeratorize_with_size(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *); -VALUE rb_enumeratorize_with_size_kw(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *, int); -int rb_arithmetic_sequence_extract(VALUE, rb_arithmetic_sequence_components_t *); -VALUE rb_arithmetic_sequence_beg_len_step(VALUE, long *begp, long *lenp, long *stepp, long len, int err); + +/** + * Constructs an enumerator. This roughly resembles `Object#enum_for`. + * + * @param[in] recv A receiver of `meth`. + * @param[in] meth Method ID in a symbol object. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to `meth`. + * @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol. + * @return A new instance of ::rb_cEnumerator which, when yielded, + * enumerates by calling `meth` on `recv` with `argv`. + */ +VALUE rb_enumeratorize(VALUE recv, VALUE meth, int argc, const VALUE *argv); + +/** + * Identical to rb_enumeratorize(), except you can additionally specify the + * size function of return value. + * + * @param[in] recv A receiver of `meth`. + * @param[in] meth Method ID in a symbol object. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to `meth`. + * @param[in] func Size calculator. + * @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol. + * @return A new instance of ::rb_cEnumerator which, when yielded, + * enumerates by calling `meth` on `recv` with `argv`. + * @note `func` can be zero, which means the size is unknown. + */ +VALUE rb_enumeratorize_with_size(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func); + +/** + * Identical to rb_enumeratorize_with_func(), except you can specify how to + * handle the last element of the given array. + * + * @param[in] recv A receiver of `meth`. + * @param[in] meth Method ID in a symbol object. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to `meth`. + * @param[in] func Size calculator. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @exception rb_eTypeError `meth` is not an instance of ::rb_cSymbol. + * @return A new instance of ::rb_cEnumerator which, when yielded, + * enumerates by calling `meth` on `recv` with `argv`. + * @note `func` can be zero, which means the size is unknown. + */ +VALUE rb_enumeratorize_with_size_kw(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func, int kw_splat); + +RBIMPL_ATTR_NONNULL(()) +/** + * Extracts components of the passed arithmetic sequence. This can be seen as + * an extended version of rb_range_values(). + * + * @param[in] as Target instance of `Enumerator::ArithmericSequence`. + * @param[out] buf Decomposed results buffer. + * @return 0 `as` is not `Enumerator::ArithmericSequence`. + * @return 1 Success. + * @post `buf` is filled. + */ +int rb_arithmetic_sequence_extract(VALUE as, rb_arithmetic_sequence_components_t *buf); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_range_beg_len(), except it takes an instance of + * `Enumerator::ArithmericSequence`. + * + * @param[in] as An `Enumerator::ArithmericSequence` instance. + * @param[out] begp Return value buffer. + * @param[out] lenp Return value buffer. + * @param[out] stepp Return value buffer. + * @param[in] len Updated length. + * @param[in] err In case `len` is out of range... + * - `0`: returns ::RUBY_Qnil. + * - `1`: raises ::rb_eRangeError. + * - `2`: `beg` and `len` expanded accordingly. + * @exception rb_eRangeError `as` cannot fit into `long`. + * @retval RUBY_Qfalse `as` is not `Enumerator::ArithmericSequence`. + * @retval RUBY_Qnil `len` is out of `as` but `err` is zero. + * @retval RUBY_Qtrue Otherwise. + * @post `beg` is the (possibly updated) left endpoint. + * @post `len` is the (possibly updated) length of the range. + * + * @internal + * + * Currently no 3rd party applications of this function is found. But that can + * be because this function is relatively new. + */ +VALUE rb_arithmetic_sequence_beg_len_step(VALUE as, long *begp, long *lenp, long *stepp, long len, int err); RBIMPL_SYMBOL_EXPORT_END() +/** @cond INTERNAL_MACRO */ #ifndef RUBY_EXPORT # define rb_enumeratorize_with_size(obj, id, argc, argv, size_fn) \ rb_enumeratorize_with_size(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn)) # define rb_enumeratorize_with_size_kw(obj, id, argc, argv, size_fn, kw_splat) \ rb_enumeratorize_with_size_kw(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn), kw_splat) #endif +/** @endcond */ +/** + * This is an implementation detail of #RETURN_SIZED_ENUMERATOR(). You could + * use it directly, but can hardly be handy. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @param[in] size_fn Size calculator. + * @return A new instance of ::rb_cEnumerator which, when yielded, + * enumerates by calling the current method on `recv` with `argv`. + */ #define SIZED_ENUMERATOR(obj, argc, argv, size_fn) \ rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \ (argc), (argv), (size_fn)) +/** + * This is an implementation detail of #RETURN_SIZED_ENUMERATOR_KW(). You + * could use it directly, but can hardly be handy. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @param[in] size_fn Size calculator. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @return A new instance of ::rb_cEnumerator which, when yielded, + * enumerates by calling the current method on `recv` with `argv`. + */ #define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ rb_enumeratorize_with_size_kw((obj), ID2SYM(rb_frame_this_func()), \ (argc), (argv), (size_fn), (kw_splat)) +/** + * This roughly resembles `return enum_for(__callee__) unless block_given?`. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @param[in] size_fn Size calculator. + * @note This macro may return inside. + */ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) do { \ if (!rb_block_given_p()) \ return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \ } while (0) + +/** + * Identical to #RETURN_SIZED_ENUMERATOR(), except you can specify how to + * handle the last element of the given array. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @param[in] size_fn Size calculator. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @note This macro may return inside. + */ #define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \ if (!rb_block_given_p()) \ return SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat); \ } while (0) +/** + * Identical to #RETURN_SIZED_ENUMERATOR(), except its size is unknown. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @note This macro may return inside. + */ #define RETURN_ENUMERATOR(obj, argc, argv) \ RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0) +/** + * Identical to #RETURN_SIZED_ENUMERATOR_KW(), except its size is unknown. It + * can also be seen as a routine identical to #RETURN_ENUMERATOR(), except you + * can specify how to handle the last element of the given array. + * + * @param[in] obj A receiver. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Arguments passed to the current method. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @note This macro may return inside. + */ #define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) \ RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, 0, kw_splat) -- cgit v1.2.3