ruby-changes:67785
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:01:57 +0900 (JST)
Subject: [ruby-changes:67785] 990a6c789a (master): include/ruby/internal/intern/hash.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=990a6c789a From 990a6c789a4e7cddaea4831de90b9a5e451444f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Fri, 16 Apr 2021 14:54:31 +0900 Subject: include/ruby/internal/intern/hash.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/intern/hash.h | 298 +++++++++++++++++++++++++++++++++--- 1 file changed, 279 insertions(+), 19 deletions(-) diff --git a/include/ruby/internal/intern/hash.h b/include/ruby/internal/intern/hash.h index f568918..9d2ce82 100644 --- a/include/ruby/internal/intern/hash.h +++ b/include/ruby/internal/intern/hash.h @@ -20,6 +20,7 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/intern/hash.h#L20 * extension libraries. They could be written in C++98. * @brief Public APIs related to ::rb_cHash. */ +#include "ruby/internal/attr/nonnull.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/value.h" #include "ruby/st.h" @@ -27,31 +28,290 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/intern/hash.h#L28 RBIMPL_SYMBOL_EXPORT_BEGIN() /* hash.c */ -void rb_st_foreach_safe(struct st_table *, int (*)(st_data_t, st_data_t, st_data_t), st_data_t); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_st_foreach(), except it raises exceptions when the callback + * function tampers the table during iterating over it. + * + * @param[in] st Table to iterate over. + * @param[in] func Callback function to apply. + * @param[in] arg Passed as-is to `func`. + * @exception rb_eRuntimeError `st` was tampered during iterating. + * + * @internal + * + * This is declared here because exceptions are Ruby level concept. + * + * This is in fact a very thin wrapper of rb_st_foreach_check(). + */ +void rb_st_foreach_safe(struct st_table *st, st_foreach_callback_func *func, st_data_t arg); + +/** @alias{rb_st_foreach_safe} */ #define st_foreach_safe rb_st_foreach_safe -VALUE rb_check_hash_type(VALUE); -void rb_hash_foreach(VALUE, int (*)(VALUE, VALUE, VALUE), VALUE); -VALUE rb_hash(VALUE); + +/** + * Try converting an object to its hash representation using its `to_hash` + * method, if any. If there is no such thing, returns ::RUBY_Qnil. + * + * @param[in] obj Arbitrary ruby object to convert. + * @exception rb_eTypeError `obj.to_hash` returned something non-Hash. + * @retval RUBY_Qnil No conversion from `obj` to hash defined. + * @retval otherwise Converted hash representation of `obj`. + * @see rb_io_check_io + * @see rb_check_array_type + * @see rb_check_string_type + * + * @internal + * + * There is no rb_hash_to_hash() that analogous to rb_str_to_str(). + * Intentional or ...? + */ +VALUE rb_check_hash_type(VALUE obj); + +RBIMPL_ATTR_NONNULL(()) +/** + * Iterates over a hash. This basically does the same thing as + * rb_st_foreach(). But because the passed hash is a Ruby object, its keys and + * values are both Ruby objects. + * + * @param[in] hash An instance of ::rb_cHash to iterate over. + * @param[in] func Callback function to yield. + * @param[in] arg Passed as-is to `func`. + * @exception rb_eRuntimeError `hash` was tampered during iterating. + */ +void rb_hash_foreach(VALUE hash, int (*func)(VALUE key, VALUE val, VALUE arg), VALUE arg); + +/** + * Calculates a message authentication code of the passed object. The return + * value is a very small integer used as an index of a key of a table. In + * order to calculate the value this function calls `#hash` method of the + * passed object. Ruby provides you a default implementation. But if you + * implement your class in C, that default implementation cannot know the + * underlying data structure. You must implement your own `#hash` method then, + * which must return an integer of uniform distribution in a sufficiently + * instant manner. + * + * @param[in] obj Arbitrary Ruby object. + * @exception rb_eTypeError `obj.hash` returned something non-Integer. + * @return A small integer. + * @note `#hash` can return very big integers, but they get truncated. + */ +VALUE rb_hash(VALUE obj); + +/** + * Creates a new, empty hash object. + * + * @return An allocated new instance of ::rb_cHash. + */ VALUE rb_hash_new(void); -VALUE rb_hash_dup(VALUE); -VALUE rb_hash_freeze(VALUE); -VALUE rb_hash_aref(VALUE, VALUE); -VALUE rb_hash_lookup(VALUE, VALUE); -VALUE rb_hash_lookup2(VALUE, VALUE, VALUE); -VALUE rb_hash_fetch(VALUE, VALUE); -VALUE rb_hash_aset(VALUE, VALUE, VALUE); -VALUE rb_hash_clear(VALUE); -VALUE rb_hash_delete_if(VALUE); -VALUE rb_hash_delete(VALUE,VALUE); -VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone); -void rb_hash_bulk_insert(long, const VALUE *, VALUE); + +/** + * Duplicates a hash. + * + * @param[in] hash An instance of ::rb_cHash. + * @return An allocated new instance of ::rb_cHash, whose contents are + * a verbatim copy of from `hash`. + */ +VALUE rb_hash_dup(VALUE hash); + +/** @alias{rb_obj_freeze} */ +VALUE rb_hash_freeze(VALUE obj); + +/** + * Queries the given key in the given hash table. If there is the key in the + * hash, returns the value associated with the key. Otherwise it returns the + * "default" value (defined per hash table). + * + * @param[in] hash Hash table to look into. + * @param[in] key Hash key to look for. + * @return Either the value associated with the key, or the default one if + * absent. + */ +VALUE rb_hash_aref(VALUE hash, VALUE key); + +/** + * Identical to rb_hash_aref(), except it always returns ::RUBY_Qnil for + * misshits. + * + * @param[in] hash Hash table to look into. + * @param[in] key Hash key to look for. + * @return Either the value associated with the key, or ::RUBY_Qnil if + * absent. + * @note A hash can store ::RUBY_Qnil as an ordinary value. You cannot + * distinguish whether the key is missing, or just its associated + * value happens to be ::RUBY_Qnil, as far as you use this API. + */ +VALUE rb_hash_lookup(VALUE hash, VALUE key); + +/** + * Identical to rb_hash_lookup(), except you can specify what to return on + * misshits. This is much like 2-arguments version of `Hash#fetch`. + * + * ```CXX + * VALUE hash; + * VALUE key; + * VALUE tmp = rb_obj_alloc(rb_cObject); + * VALUE val = rb_hash_lookup2(hash, key, tmp); + * if (val == tmp) { + * printf("misshit"); + * } + * else { + * printf("hit"); + * } + * ``` + * + * @param[in] hash Hash table to look into. + * @param[in] key Hash key to look for. + * @param[in] def Default value. + * @retval def `hash` does not have `key`. + * @retval otherwise The value associated with `key`. + */ +VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def); + +/** + * Identical to rb_hash_lookup(), except it yields the (implicitly) passed + * block instead of returning ::RUBY_Qnil. + * + * @param[in] hash Hash table to look into. + * @param[in] key Hash key to look for. + * @exception rb_eKeyError No block given. + * @return Either the value associated with the key, or what the block + * evaluates to if absent. + */ +VALUE rb_hash_fetch(VALUE hash, VALUE key); + +/** + * Inserts or replaces ("upsert"s) the objects into the given hash table. This + * basically associates the given value with the given key. On duplicate key + * this function updates its associated value with the given one. Otherwise it + * inserts the association at the end of the table. + * + * @param[out] hash Target hash table to modify. + * @param[in] key Arbitrary Ruby object. + * @param[in] val A value to be associated with `key`. + * @exception rb_eFrozenError `hash` is frozen. + * @return The passed `val` + * @post `val` is associated with `key` in `hash`. + */ +VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val); + +/** + * Swipes everything out of the passed hash table. + * + * @param[out] hash Target to clear. + * @exception rb_eFrozenError `hash`is frozen. + * @return The passed `hash` + * @post `hash` has no contents. + */ +VALUE rb_hash_clear(VALUE hash); + +/** + * Deletes each entry for which the block returns a truthy value. If there is + * no block given, it returns an enumerator that does the thing. + * + * @param[out] hash Target hash to modify. + * @exception rb_eFrozenError `hash` is frozen. + * @retval hash The hash is modified. + * @retval otherwise An instance of ::rb_cEnumerator that does it. + */ +VALUE rb_hash_delete_if(VALUE hash); + +/** + * Deletes the passed key from the passed hash table, if any. + * + * @param[out] hash Target hash to modify. + * @param[in] key Key to delete. + * @retval RUBY_Qnil `hash` has no such key as `key`. + * @retval otherwise What was associated with `key`. + * @post `hash` has no such key as `key`. + */ +VALUE rb_hash_delete(VALUE hash, VALUE key); + +/** + * Inserts a list of key-value pairs into a hash table at once. It is + * semantically identical to repeatedly calling rb_hash_aset(), but can be + * faster than that. + * + * @param[in] argc Length of `argv`, must be even. + * @param[in] argv A list of key, value, key, value, ... + * @param[out] hash Target hash table to modify. + * @post `hash` has contents from `argv`. + * @note `argv` is allowed to be NULL as long as `argc` is zero. + * + * @internal + * + * What happens for duplicated keys? Well it silently discards older ones to + * accept the newest (rightmost) one. This behaviour also mimics repeated call + * of rb_hash_aset(). + */ +void rb_hash_bulk_i (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/