diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-10-20 14:42:08 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-10-20 22:05:27 +0900 |
commit | 192bc725290ca4b271bff2bae6123d84c25f7173 (patch) | |
tree | 9f50fcf171aa5f73c2bb944aa05b4d10e5dc614f | |
parent | f55212bce939f736559709a8cd16c409772389c8 (diff) |
Define `UNDEF_P` and `NIL_OR_UNDEF_P` [EXPERIMENTAL]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6599
-rw-r--r-- | include/ruby/internal/special_consts.h | 58 | ||||
-rw-r--r-- | internal.h | 3 |
2 files changed, 61 insertions, 0 deletions
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 @@ #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 */ @@ -177,6 +179,62 @@ 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() +/** * Checks if the given object is a so-called Fixnum. * * @param[in] obj An arbitrary ruby object. diff --git a/internal.h b/internal.h index 695c9cfb7e..b63af50616 100644 --- a/internal.h +++ b/internal.h @@ -25,6 +25,9 @@ /* 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 |