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/