1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Define UNDEF_P and NIL_OR_UNDEF_P [EXPERIMENTAL]

This commit is contained in:
Nobuyoshi Nakada 2022-10-20 14:42:08 +09:00
parent f55212bce9
commit 192bc72529
Notes: git 2022-10-20 13:05:47 +00:00
2 changed files with 61 additions and 0 deletions

View file

@ -76,6 +76,8 @@
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P #define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define RB_STATIC_SYM_P RB_STATIC_SYM_P #define RB_STATIC_SYM_P RB_STATIC_SYM_P
#define RB_TEST RB_TEST #define RB_TEST RB_TEST
#define RB_UNDEF_P RB_UNDEF_P
#define RB_NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
/** @endcond */ /** @endcond */
/** special constants - i.e. non-zero and non-fixnum constants */ /** special constants - i.e. non-zero and non-fixnum constants */
@ -173,6 +175,62 @@ RB_NIL_P(VALUE obj)
return obj == RUBY_Qnil; 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_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11) RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL() RBIMPL_ATTR_ARTIFICIAL()

View file

@ -25,6 +25,9 @@
/* Prevent compiler from reordering access */ /* Prevent compiler from reordering access */
#define ACCESS_ONCE(type,x) (*((volatile type *)&(x))) #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" #include "ruby/ruby.h"
/* Following macros were formerly defined in this header but moved to somewhere /* Following macros were formerly defined in this header but moved to somewhere