[前][次][番号順一覧][スレッド一覧]

ruby-changes:67829

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:02:29 +0900 (JST)
Subject: [ruby-changes:67829] 2c4dccad33 (master): include/ruby/random.h: add doxygen

https://git.ruby-lang.org/ruby.git/commit/?id=2c4dccad33

From 2c4dccad337b58b4d36cf489ebecd9c7da778e4c 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, 25 Jun 2021 09:53:40 +0900
Subject: include/ruby/random.h: add doxygen

Must not be a bad idea to improve documents. [ci skip]
---
 include/ruby/random.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 219 insertions(+), 7 deletions(-)

diff --git a/include/ruby/random.h b/include/ruby/random.h
index 56b2dd4..657b37f 100644
--- a/include/ruby/random.h
+++ b/include/ruby/random.h
@@ -1,4 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/random.h#L1
-#ifndef RUBY_RANDOM_H
+#ifndef RUBY_RANDOM_H                                /*-*-C++-*-vi:se ft=cpp:*/
 #define RUBY_RANDOM_H 1
 /**
  * @file
@@ -8,44 +8,167 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/random.h#L8
  *             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.
+ *
+ * This  is a  set of  APIs  to roll  your  own subclass  of ::rb_cRandom.   An
+ * illustrative    example     of    such     PRNG    can    be     found    at
+ * `ext/-test-/ramdom/loop.c`.
  */
 
 #include "ruby/ruby.h"
 
 RBIMPL_SYMBOL_EXPORT_BEGIN()
 
+/**
+ * Base components of the random interface.
+ *
+ * @internal
+ *
+ * Ideally this  could be an  empty class if  we could assume  C++, but in  C a
+ * struct must have at least one field.
+ */
 struct rb_random_struct {
+    /** Seed, passed through e.g. `Random.new` */
     VALUE seed;
 };
-typedef struct rb_random_struct rb_random_t;
+typedef struct rb_random_struct rb_random_t; /**< @see ::rb_random_struct */
 
-typedef void rb_random_init_func(rb_random_t *, const uint32_t *, size_t);
-typedef unsigned int rb_random_get_int32_func(rb_random_t *);
-typedef void rb_random_get_bytes_func(rb_random_t *, void *, size_t);
-typedef double rb_random_get_real_func(rb_random_t *, int);
+RBIMPL_ATTR_NONNULL(())
+/**
+ * This is the type of functions called when your random object is initialised.
+ * Passed buffer  is the seed  object basically.  But in  Ruby a number  can be
+ * really big.  This type of functions accept  such big integers as a series of
+ * machine words.
+ *
+ * @param[out]  rng  Your random struct to fill in.
+ * @param[in]   buf  Seed, maybe converted from a bignum.
+ * @param[in]   len  Number of words of `buf`.
+ * @post        `rng` is initialised using the passed seeds.
+ */
+typedef void rb_random_init_func(rb_random_t *rng, const uint32_t *buf, size_t len);
+
+RBIMPL_ATTR_NONNULL(())
+/**
+ * This is the type of functions  called from your object's `#rand` method.
+ *
+ * @param[out]  rng  Your random struct to extract an integer from.
+ * @return      A random number.
+ * @post        `rng` is consumed somehow.
+ */
+typedef unsigned int rb_random_get_int32_func(rb_random_t *rng);
+
+RBIMPL_ATTR_NONNULL(())
+/**
+ * This is the type of functions called from your object's `#bytes` method.
+ *
+ * @param[out]  rng  Your random struct to extract an integer from.
+ * @param[out]  buf  Return buffer of at least `len` bytes length.
+ * @param[in]   len  Number of bytes of `buf`.
+ * @post        `rng` is consumed somehow.
+ * @post        `buf` is filled with random bytes.
+ */
+typedef void rb_random_get_bytes_func(rb_random_t *rng, void *buf, size_t len);
+
+RBIMPL_ATTR_NONNULL(())
+/**
+ * This is the type of functions called from your object's `#rand` method.
+ *
+ * @param[out]  rng   Your random struct to extract an integer from.
+ * @param[in]   excl  Pass nonzero value here to indicate you don't want 1.0.
+ * @return      A random number of range 0.0 to 1.0.
+ * @post        `rng` is consumed somehow.
+ */
+typedef double rb_random_get_real_func(rb_random_t *rng, int excl);
 
+/** PRNG algorithmic interface, analogous to Ruby level classes. */
 typedef struct {
+    /** Number of bits of seed numbers. */
     size_t default_seed_bits;
+
+    /** Initialiser function. */
     rb_random_init_func *init;
+
+    /** Function to obtain a random integer. */
     rb_random_get_int32_func *get_int32;
+
+    /**
+     * Function to obtain a series of random bytes.  If your PRNG have a native
+     * method to  yield arbitrary number of  bytes use that to  implement this.
+     * But  in   case  you  lack   such  things,  you   can  do  so   by  using
+     * rb_rand_bytes_int32()
+     *
+     * ```CXX
+     * extern rb_random_get_int32_func your_get_int32_func;
+     *
+     * void
+     * your_get_byes_func(rb_random_t *rng, void *buf, size_t len)
+     * {
+     *     rb_rand_bytes_int32(your_get_int32_func, rng, buf, len);
+     * }
+     * ```
+     */
     rb_random_get_bytes_func *get_bytes;
+
+    /**
+     * Function to obtain  a random double.  If your PRNG  have a native method
+     * to yield a floating point random number use that to implement this.  But
+     * in   case   you  lack   such   things,   you   can   do  so   by   using
+     * rb_int_pair_to_real().
+     *
+     * ```CXX
+     * extern rb_random_get_int32_func your_get_int32_func;
+     *
+     * void
+     * your_get_real_func(rb_random_t *rng, int excl)
+     * {
+     *     auto a = your_get_int32_func(rng);
+     *     auto b = your_get_int32_func(rng);
+     *     return rb_int_pair_to_real(a, b, excl);
+     * }
+     * ```
+     */
     rb_random_get_real_func *get_real;
 } rb_random_interface_t;
 
+/**
+ * This utility macro defines  3 functions named prefix_init, prefix_get_int32,
+ * prefix_get_bytes.
+ */
 #define RB_RANDOM_INTERFACE_DECLARE(prefix) \
     static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
     static unsigned int prefix##_get_int32(rb_random_t *); \
     static void prefix##_get_bytes(rb_random_t *, void *, size_t)
 
+/**
+ * Identical   to   #RB_RANDOM_INTERFACE_DECLARE   except  it   also   declares
+ * prefix_get_real.
+ */
 #define RB_RANDOM_INTERFACE_DECLARE_WITH_REAL(prefix) \
     RB_RANDOM_INTERFACE_DECLARE(prefix); \
     static double prefix##_get_real(rb_random_t *, int)
 
+/**
+ * This    utility    macro   expands    to    the    names   declared    using
+ * #RB_RANDOM_INTERFACE_DECLARE.    Expected   to   be   used   inside   of   a
+ * ::rb_random_interface_t initialiser:
+ *
+ * ```CXX
+ * RB_RANDOM_INTERFACE_DECLARE(foo);
+ *
+ * static inline constexpr rb_random_interface_t foo_interface = {
+ *     32768, // bits
+ *     RB_RANDOM_INTERFACE_DEFINE(foo),
+ * };
+ * ```
+ */
 #define RB_RANDOM_INTERFACE_DEFINE(prefix) \
     prefix##_init, \
     prefix##_get_int32, \
     prefix##_get_bytes
 
+/**
+ * Identical   to   #RB_RANDOM_INTERFACE_DEFINE    except   it   also   defines
+ * prefix_get_real.
+ */
 #define RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(prefix) \
     RB_RANDOM_INTERFACE_DEFINE(prefix), \
     prefix##_get_real
@@ -54,23 +177,103 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/include/ruby/random.h#L177
 typedef rb_data_type_t rb_random_data_type_t;
 # define RB_RANDOM_PARENT 0
 #else
+
+/** This is the type of ::rb_random_data_type. */
 typedef const rb_data_type_t rb_random_data_type_t;
+
+/**
+ * This utility macro can be used when you define your own PRNG type:
+ *
+ * ```CXX
+ * static inline constexpr rb_random_interface_t your_if = {
+ *     0, RB_RANDOM_INTERFACE_DEFINE(your),
+ * };
+ *
+ * static inline constexpr your_prng = {
+ *     "your PRNG",
+ *     { rb_random_mark, },
+ *     RB_RANDOM_PARENT,                 // <<-- HERE
+ *     &your_if,
+ *     0,
+ * }
+ * ```
+ */
 # define RB_RANDOM_PARENT &rb_random_data_type
 #endif
 
+/**
+ * This macro  is expected  to be  called exactly  once at  the beginning  of a
+ * program, possibly from  inside of your `Init_Foo()`  function.  Depending on
+ * platforms #RB_RANDOM_PARENT  can require  a fixup.   This routine  does that
+ * when necessary.
+ */
 #define RB_RANDOM_DATA_INIT_PARENT(random_data) \
     rbimpl_random_data_init_parent(&random_data)
 
+/**
+ * This   is    the   implementation   of    ::rb_data_type_struct::dmark   for
+ * ::rb_random_data_type.  In case  your PRNG does not involve  Ruby objects at
+ * all (which is quite likely), you can simply reuse it.
+ *
+ * @param[out]  ptr  Target to mark, which is a ::rb_random_t this case.
+ */
 void rb_random_mark(void *ptr);
+
+/**
+ * Initialises  an allocated  ::rb_random_t instance.   Call it  from your  own
+ * initialiser appropriately.
+ *
+ * @param[out]  rnd  Your PRNG's base part.
+ * @post        `rnd` is filled with an initial state.
+ */
 void rb_random_base_init(rb_random_t *rnd);
+
+/**
+ * Generates a 64 bit floating point number by concatenating two 32bit unsigned
+ * integers.
+ *
+ * @param[in]  a     Most significant 32 bits of the result.
+ * @param[in]  b     Least significant 32 bits of the result.
+ * @param[in]  excl  Whether the result should exclude 1.0 or not.
+ * @return     A double, whose range is either `[0, 1)` or `[0, 1]`.
+ * @see        ::rb_random_interface_t::get_real()
+ *
+ * @internal
+ *
+ * This in fact has nothing to do with PRNGs.
+ */
 double rb_int_pair_to_real(uint32_t a, uint32_t b, int excl);
-void rb_rand_bytes_int32(rb_random_get_int32_func *, rb_random_t *, void *, size_t);
+
+/**
+ * Repeatedly calls  the passed function over  and over again until  the passed
+ * buffer is filled with random bytes.
+ *
+ * @param[in]   func  Generator function.
+ * @param[out]  prng  Passed as-is to `func`.
+ * @param[out]  buff  Return buffer.
+ * @param[in]   size  Number of words of `buff`.
+ * @post        `buff` is filled with random bytes.
+ * @post        `prng` is updated by `func`.
+ * @see        ::rb_random_interface_t::get_bytes()
+ */
+void rb_rand_bytes_int32(rb_random_get_int32_func *func, rb_random_t *prng, void *buff, size_t size);
+
+/**
+ * The data that  holds the backend type of ::rb_cRandom.   Us (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]