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

ruby-changes:74144

From: Nobuyoshi <ko1@a...>
Date: Thu, 20 Oct 2022 22:05:53 +0900 (JST)
Subject: [ruby-changes:74144] 192bc72529 (master): Define `UNDEF_P` and `NIL_OR_UNDEF_P` [EXPERIMENTAL]

https://git.ruby-lang.org/ruby.git/commit/?id=192bc72529

From 192bc725290ca4b271bff2bae6123d84c25f7173 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 20 Oct 2022 14:42:08 +0900
Subject: Define `UNDEF_P` and `NIL_OR_UNDEF_P` [EXPERIMENTAL]

---
 include/ruby/internal/special_consts.h | 58 ++++++++++++++++++++++++++++++++++
 internal.h                             |  3 ++
 2 files changed, 61 insertions(+)

diff --git a/include/ruby/internal/special_consts.h b/include/ruby/internal/special_consts.h
index a8c992ef5e..6943ef9b94 100644
--- a/include/ruby/internal/special_consts.h
+++ b/include/ruby/internal/special_consts.h
@@ -76,6 +76,8 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/special_consts.h#L76
 #define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
 #define RB_STATIC_SYM_P    RB_STATIC_SYM_P
 #define RB_TEST            RB_TEST
+#define RB_UNDEF_P         RB_UNDEF_P
+#define RB_NIL_OR_UNDEF_P  RB_NIL_OR_UNDEF_P
 /** @endcond */
 
 /** special constants - i.e. non-zero and non-fixnum constants */
@@ -173,6 +175,62 @@ RB_NIL_P(VALUE obj) https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/special_consts.h#L175
     return obj == RUBY_Qnil;
 }
 
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Checks if the given object is undef.
+ *
+ * @param[in]  obj    An arbitrary ruby object.
+ * @retval     true   `obj` is ::RUBY_Qundef.
+ * @retval     false  Anything else.
+ */
+static inline bool
+RB_UNDEF_P(VALUE obj)
+{
+    return obj == RUBY_Qundef;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Checks if the given object is nil or undef.  Can be used to see if
+ * a keyword argument is not given or given `nil`.
+ *
+ * @param[in]  obj    An arbitrary ruby object.
+ * @retval     true   `obj` is ::RUBY_Qnil or ::RUBY_Qundef.
+ * @retval     false  Anything else.
+ */
+static inline bool
+RB_NIL_OR_UNDEF_P(VALUE obj)
+{
+    /*
+     * if USE_FLONUM
+     *  Qundef:       ....0010 0100
+     *  Qnil:         ....0000 0100
+     *  mask:         ....1101 1111
+     *  common_bits:  ....0000 0100
+     * ---------------------------------
+     *  Qnil & mask   ....0000 0100
+     *  Qundef & mask ....0000 0100
+     *
+     * if ! USE_FLONUM
+     *  Qundef:       ....0000 1010
+     *  Qnil:         ....0000 0010
+     *  mask:         ....1111 0111
+     *  common_bits:  ....0000 0010
+     * ----------------------------
+     *  Qnil & mask   ....0000 0010
+     *  Qundef & mask ....0000 0010
+     *
+     *  NIL_OR_UNDEF_P(v) can be true only when v is Qundef or Qnil.
+     */
+    const VALUE mask = ~(RUBY_Qundef ^ RUBY_Qnil);
+    const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
+    return (obj & mask) == common_bits;
+}
+
 RBIMPL_ATTR_CONST()
 RBIMPL_ATTR_CONSTEXPR(CXX11)
 RBIMPL_ATTR_ARTIFICIAL()
diff --git a/internal.h b/internal.h
index 695c9cfb7e..b63af50616 100644
--- a/internal.h
+++ b/internal.h
@@ -25,6 +25,9 @@ https://github.com/ruby/ruby/blob/trunk/internal.h#L25
 /* Prevent compiler from reordering access */
 #define ACCESS_ONCE(type,x) (*((volatile type *)&(x)))
 
+#define UNDEF_P         RB_UNDEF_P
+#define NIL_OR_UNDEF_P  RB_NIL_OR_UNDEF_P
+
 #include "ruby/ruby.h"
 
 /* Following macros were formerly defined in this header but moved to somewhere
-- 
cgit v1.2.3


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

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