summaryrefslogtreecommitdiff
path: root/include/ruby/3/arithmetic
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2020-04-08 13:28:13 +0900
committerGitHub <noreply@github.com>2020-04-08 13:28:13 +0900
commit9e6e39c3512f7a962c44dc3729c98a0f8be90341 (patch)
tree901a22676d54d78240e450b64a8cd06eb1703910 /include/ruby/3/arithmetic
parent5ac4bf2cd87e1eb5779ca5ae7f96a1a22e8436d9 (diff)
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
Notes
Notes: Merged-By: shyouhei <shyouhei@ruby-lang.org>
Diffstat (limited to 'include/ruby/3/arithmetic')
-rw-r--r--include/ruby/3/arithmetic/char.h58
-rw-r--r--include/ruby/3/arithmetic/double.h39
-rw-r--r--include/ruby/3/arithmetic/fixnum.h44
-rw-r--r--include/ruby/3/arithmetic/gid_t.h30
-rw-r--r--include/ruby/3/arithmetic/int.h163
-rw-r--r--include/ruby/3/arithmetic/intptr_t.h42
-rw-r--r--include/ruby/3/arithmetic/long.h244
-rw-r--r--include/ruby/3/arithmetic/long_long.h53
-rw-r--r--include/ruby/3/arithmetic/mode_t.h30
-rw-r--r--include/ruby/3/arithmetic/off_t.h45
-rw-r--r--include/ruby/3/arithmetic/pid_t.h30
-rw-r--r--include/ruby/3/arithmetic/short.h54
-rw-r--r--include/ruby/3/arithmetic/size_t.h47
-rw-r--r--include/ruby/3/arithmetic/st_data_t.h59
-rw-r--r--include/ruby/3/arithmetic/uid_t.h30
15 files changed, 968 insertions, 0 deletions
diff --git a/include/ruby/3/arithmetic/char.h b/include/ruby/3/arithmetic/char.h
new file mode 100644
index 0000000000..94329b7a9e
--- /dev/null
+++ b/include/ruby/3/arithmetic/char.h
@@ -0,0 +1,58 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `char` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMETIC_CHAR_H
+#define RUBY3_ARITHMETIC_CHAR_H
+#include "ruby/3/arithmetic/int.h" /* NUM2INT is here, but */
+#include "ruby/3/arithmetic/long.h" /* INT2FIX is here.*/
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/const.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/core/rstring.h"
+#include "ruby/3/value_type.h"
+
+#define RB_NUM2CHR rb_num2char_inline
+#define NUM2CHR RB_NUM2CHR
+#define CHR2FIX RB_CHR2FIX
+
+/** @cond INTERNAL_MACRO */
+#define RB_CHR2FIX RB_CHR2FIX
+/** @endcond */
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_CHR2FIX(unsigned char c)
+{
+ return RB_INT2FIX(c);
+}
+
+static inline char
+rb_num2char_inline(VALUE x)
+{
+ if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
+ return RSTRING_PTR(x)[0];
+ else
+ return RUBY3_CAST((char)RB_NUM2INT(x));
+}
+
+#endif /* RUBY3_ARITHMETIC_CHAR_H */
diff --git a/include/ruby/3/arithmetic/double.h b/include/ruby/3/arithmetic/double.h
new file mode 100644
index 0000000000..82e9fdc3b1
--- /dev/null
+++ b/include/ruby/3/arithmetic/double.h
@@ -0,0 +1,39 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `double` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMETIC_DOUBLE_H
+#define RUBY3_ARITHMETIC_DOUBLE_H
+#include "ruby/3/attr/pure.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/value.h"
+
+#define NUM2DBL rb_num2dbl
+#define RFLOAT_VALUE rb_float_value
+#define DBL2NUM rb_float_new
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+double rb_num2dbl(VALUE);
+RUBY3_ATTR_PURE()
+double rb_float_value(VALUE);
+VALUE rb_float_new(double);
+VALUE rb_float_new_in_heap(double);
+RUBY3_SYMBOL_EXPORT_END()
+
+#endif /* RUBY3_ARITHMETIC_DOUBLE_H */
diff --git a/include/ruby/3/arithmetic/fixnum.h b/include/ruby/3/arithmetic/fixnum.h
new file mode 100644
index 0000000000..e995b5f3f8
--- /dev/null
+++ b/include/ruby/3/arithmetic/fixnum.h
@@ -0,0 +1,44 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Handling of integers formerly known as Fixnums.
+ */
+#ifndef RUBY3_ARITHMETIC_FIXNUM_H
+#define RUBY3_ARITHMETIC_FIXNUM_H
+#include "ruby/backward/2/limits.h"
+
+#define FIXABLE RB_FIXABLE
+#define FIXNUM_MAX RUBY_FIXNUM_MAX
+#define FIXNUM_MIN RUBY_FIXNUM_MIN
+#define NEGFIXABLE RB_NEGFIXABLE
+#define POSFIXABLE RB_POSFIXABLE
+
+/*
+ * FIXABLE can be applied to anything, from double to intmax_t. The problem is
+ * double. On a 64bit system RUBY_FIXNUM_MAX is 4,611,686,018,427,387,903,
+ * which is not representable by a double. The nearest value that a double can
+ * represent is 4,611,686,018,427,387,904, which is not fixable. The
+ * seemingly-stragne "< FIXNUM_MAX + 1" expression below is due to this.
+ */
+#define RB_POSFIXABLE(_) ((_) < RUBY_FIXNUM_MAX + 1)
+#define RB_NEGFIXABLE(_) ((_) >= RUBY_FIXNUM_MIN)
+#define RB_FIXABLE(_) (RB_POSFIXABLE(_) && RB_NEGFIXABLE(_))
+#define RUBY_FIXNUM_MAX (LONG_MAX / 2)
+#define RUBY_FIXNUM_MIN (LONG_MIN / 2)
+
+#endif /* RUBY3_ARITHMETIC_FIXNUM_H */
diff --git a/include/ruby/3/arithmetic/gid_t.h b/include/ruby/3/arithmetic/gid_t.h
new file mode 100644
index 0000000000..ebdd4d21f6
--- /dev/null
+++ b/include/ruby/3/arithmetic/gid_t.h
@@ -0,0 +1,30 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `gid_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/long.h"
+
+#ifndef GIDT2NUM
+# define GIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2GIDT
+# define NUM2GIDT RB_NUM2LONG
+#endif
diff --git a/include/ruby/3/arithmetic/int.h b/include/ruby/3/arithmetic/int.h
new file mode 100644
index 0000000000..f6af085a53
--- /dev/null
+++ b/include/ruby/3/arithmetic/int.h
@@ -0,0 +1,163 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `int` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMETIC_INT_H
+#define RUBY3_ARITHMETIC_INT_H
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/fixnum.h"
+#include "ruby/3/arithmetic/intptr_t.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/const.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/compiler_is.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/special_consts.h"
+#include "ruby/3/value.h"
+#include "ruby/3/warning_push.h"
+#include "ruby/assert.h"
+
+#define RB_INT2NUM rb_int2num_inline
+#define RB_NUM2INT rb_num2int_inline
+#define RB_UINT2NUM rb_uint2num_inline
+
+#define FIX2INT RB_FIX2INT
+#define FIX2UINT RB_FIX2UINT
+#define INT2NUM RB_INT2NUM
+#define NUM2INT RB_NUM2INT
+#define NUM2UINT RB_NUM2UINT
+#define UINT2NUM RB_UINT2NUM
+
+/** @cond INTERNAL_MACRO */
+#define RB_FIX2INT RB_FIX2INT
+#define RB_NUM2UINT RB_NUM2UINT
+#define RB_FIX2UINT RB_FIX2UINT
+/** @endcond */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+long rb_num2int(VALUE);
+long rb_fix2int(VALUE);
+unsigned long rb_num2uint(VALUE);
+unsigned long rb_fix2uint(VALUE);
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline int
+RB_FIX2INT(VALUE x)
+{
+ /* "FIX2INT raises a TypeError if passed nil", says rubyspec. Not sure if
+ * that is a desired behaviour but just preserve backwards compatilibily.
+ */
+#if 0
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+#endif
+ long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_fix2int(x);
+ }
+ else {
+ ret = RB_FIX2LONG(x);
+ }
+
+ return RUBY3_CAST((int)ret);
+}
+
+static inline int
+rb_num2int_inline(VALUE x)
+{
+ long ret;
+
+ if /* constexpr */ (sizeof(int) == sizeof(long)) {
+ ret = RB_NUM2LONG(x);
+ }
+ else if (RB_FIXNUM_P(x)) {
+ ret = rb_fix2int(x);
+ }
+ else {
+ ret = rb_num2int(x);
+ }
+
+ return RUBY3_CAST((int)ret);
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline unsigned int
+RB_NUM2UINT(VALUE x)
+{
+ unsigned long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_num2uint(x);
+ }
+ else {
+ ret = RB_NUM2ULONG(x);
+ }
+
+ return RUBY3_CAST((unsigned int)ret);
+}
+
+RUBY3_ATTR_ARTIFICIAL()
+static inline unsigned int
+RB_FIX2UINT(VALUE x)
+{
+#if 0 /* Ditto for RB_FIX2INT. */
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+#endif
+ unsigned long ret;
+
+ if /* constexpr */ (sizeof(int) < sizeof(long)) {
+ ret = rb_fix2uint(x);
+ }
+ else {
+ ret = RB_FIX2ULONG(x);
+ }
+
+ return RUBY3_CAST((unsigned int)ret);
+}
+
+RUBY3_WARNING_PUSH()
+#if RUBY3_COMPILER_IS(GCC)
+RUBY3_WARNING_IGNORED(-Wtype-limits) /* We can ignore them here. */
+#elif RUBY3_HAS_WARNING("-Wtautological-constant-out-of-range-compare")
+RUBY3_WARNING_IGNORED(-Wtautological-constant-out-of-range-compare)
+#endif
+
+static inline VALUE
+rb_int2num_inline(int v)
+{
+ if (RB_FIXABLE(v))
+ return RB_INT2FIX(v);
+ else
+ return rb_int2big(v);
+}
+
+static inline VALUE
+rb_uint2num_inline(unsigned int v)
+{
+ if (RB_POSFIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_uint2big(v);
+}
+
+RUBY3_WARNING_POP()
+
+#endif /* RUBY3_ARITHMETIC_INT_H */
diff --git a/include/ruby/3/arithmetic/intptr_t.h b/include/ruby/3/arithmetic/intptr_t.h
new file mode 100644
index 0000000000..fd8043a10d
--- /dev/null
+++ b/include/ruby/3/arithmetic/intptr_t.h
@@ -0,0 +1,42 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `intptr_t` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMETIC_INTPTR_T_H
+#define RUBY3_ARITHMETIC_INTPTR_T_H
+#include "ruby/3/config.h"
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "ruby/3/value.h"
+#include "ruby/3/dllexport.h"
+
+#define rb_int_new rb_int2inum
+#define rb_uint_new rb_uint2inum
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_int2big(intptr_t i);
+VALUE rb_int2inum(intptr_t i);
+VALUE rb_uint2big(uintptr_t i);
+VALUE rb_uint2inum(uintptr_t i);
+RUBY3_SYMBOL_EXPORT_END()
+
+#endif /* RUBY3_ARITHMETIC_INTPTR_T_H */
diff --git a/include/ruby/3/arithmetic/long.h b/include/ruby/3/arithmetic/long.h
new file mode 100644
index 0000000000..7925669baf
--- /dev/null
+++ b/include/ruby/3/arithmetic/long.h
@@ -0,0 +1,244 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `long` and Ruby's.
+ *
+ * ### Q&A ###
+ *
+ * - Q: Why are INT2FIX etc. here, not in `int.h`?
+ *
+ * - A: Because they are in fact handling `long`. It seems someone did not
+ * understand the difference of `int` and `long` when they designed those
+ * macros.
+ */
+#ifndef RUBY3_ARITHMETIC_LONG_H
+#define RUBY3_ARITHMETIC_LONG_H
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/fixnum.h" /* FIXABLE */
+#include "ruby/3/arithmetic/intptr_t.h" /* rb_int2big etc.*/
+#include "ruby/3/assume.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/cold.h"
+#include "ruby/3/attr/const.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/attr/noreturn.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/special_consts.h" /* FIXNUM_FLAG */
+#include "ruby/3/value.h"
+#include "ruby/assert.h"
+
+#define FIX2LONG RB_FIX2LONG
+#define FIX2ULONG RB_FIX2ULONG
+#define INT2FIX RB_INT2FIX
+#define LONG2FIX RB_INT2FIX
+#define LONG2NUM RB_LONG2NUM
+#define NUM2LONG RB_NUM2LONG
+#define NUM2ULONG RB_NUM2ULONG
+#define RB_FIX2LONG rb_fix2long
+#define RB_FIX2ULONG rb_fix2ulong
+#define RB_LONG2FIX RB_INT2FIX
+#define RB_LONG2NUM rb_long2num_inline
+#define RB_NUM2LONG rb_num2long_inline
+#define RB_NUM2ULONG rb_num2ulong_inline
+#define RB_ULONG2NUM rb_ulong2num_inline
+#define ULONG2NUM RB_ULONG2NUM
+#define rb_fix_new RB_INT2FIX
+#define rb_long2int rb_long2int_inline
+
+/** @cond INTERNAL_MACRO */
+#define RB_INT2FIX RB_INT2FIX
+/** @endcond */
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+
+RUBY3_ATTR_NORETURN()
+RUBY3_ATTR_COLD()
+void rb_out_of_int(SIGNED_VALUE num);
+
+long rb_num2long(VALUE num);
+unsigned long rb_num2ulong(VALUE num);
+RUBY3_SYMBOL_EXPORT_END()
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+RUBY3_ATTR_ARTIFICIAL()
+static inline VALUE
+RB_INT2FIX(long i)
+{
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXABLE(i));
+
+ /* :NOTE: VALUE can be wider than long. As j being unsigned, 2j+1 is fully
+ * defined. Also it can be compiled into a single LEA instruction. */
+ const unsigned long j = i;
+ const unsigned long k = 2 * j + RUBY_FIXNUM_FLAG;
+ const long l = k;
+ const SIGNED_VALUE m = l; /* Sign extend */
+ const VALUE n = m;
+
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(n));
+ return n;
+}
+
+static inline int
+rb_long2int_inline(long n)
+{
+ int i = RUBY3_CAST((int)n);
+
+ if /* constexpr */ (sizeof(long) <= sizeof(int)) {
+ RUBY3_ASSUME(i == n);
+ }
+
+ if (i != n)
+ rb_out_of_int(n);
+
+ return i;
+}
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+static inline long
+ruby3_fix2long_by_idiv(VALUE x)
+{
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+
+ /* :NOTE: VALUE can be wider than long. (x-1)/2 never overflows because
+ * RB_FIXNUM_P(x) holds. Also it has no portability issue like y>>1
+ * below. */
+ const SIGNED_VALUE y = x - RUBY_FIXNUM_FLAG;
+ const SIGNED_VALUE z = y / 2;
+ const long w = RUBY3_CAST((long)z);
+
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXABLE(w));
+ return w;
+}
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+static inline long
+ruby3_fix2long_by_shift(VALUE x)
+{
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+
+ /* :NOTE: VALUE can be wider than long. If right shift is arithmetic, this
+ * is noticably faster than above. */
+ const SIGNED_VALUE y = x;
+ const SIGNED_VALUE z = y >> 1;
+ const long w = RUBY3_CAST((long)z);
+
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXABLE(w));
+ return w;
+}
+
+RUBY3_ATTR_CONST()
+RUBY3_ATTR_CONSTEXPR(CXX11)
+static inline bool
+ruby3_right_shift_is_arithmetic_p(void)
+{
+ return (-1 >> 1) == -1;
+}
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+static inline long
+rb_fix2long(VALUE x)
+{
+ if /* constexpr */ (ruby3_right_shift_is_arithmetic_p()) {
+ return ruby3_fix2long_by_shift(x);
+ }
+ else {
+ return ruby3_fix2long_by_idiv(x);
+ }
+}
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+static inline unsigned long
+rb_fix2ulong(VALUE x)
+{
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
+ return rb_fix2long(x);
+}
+
+static inline long
+rb_num2long_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2LONG(x);
+ else
+ return rb_num2long(x);
+}
+
+static inline unsigned long
+rb_num2ulong_inline(VALUE x)
+{
+ /* This (negative fixnum would become a large unsigned long while negative
+ * bignum is an exception) has been THE behaviour of NUM2ULONG since the
+ * beginning. It is strange, but we can no longer change how it works at
+ * this moment. We have to get by with it. See also:
+ * https://bugs.ruby-lang.org/issues/9089 */
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2ULONG(x);
+ else
+ return rb_num2ulong(x);
+}
+
+static inline VALUE
+rb_long2num_inline(long v)
+{
+ if (RB_FIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_int2big(v);
+}
+
+static inline VALUE
+rb_ulong2num_inline(unsigned long v)
+{
+ if (RB_POSFIXABLE(v))
+ return RB_LONG2FIX(v);
+ else
+ return rb_uint2big(v);
+}
+
+/**
+ * @cond INTERNAL_MACRO
+ *
+ * Following overload is necessary because sometimes INT2FIX is used as a enum
+ * value (e.g. `enum { FOO = INT2FIX(0) };`). THIS IS NG in theory because a
+ * VALUE does not fit into an enum (which must be a signed int). But we cannot
+ * break existing codes.
+ */
+#if RUBY3_HAS_ATTR_CONSTEXPR_CXX14
+# /* C++ can write constexpr as enum values. */
+
+#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
+# undef INT2FIX
+# define INT2FIX(i) (RUBY3_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG)
+
+#else
+# undef INT2FIX
+# define INT2FIX(i) \
+ __builtin_choose_expr( \
+ __builtin_constant_p(i), \
+ RUBY3_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG, \
+ RB_INT2FIX(i))
+#endif
+/** @endcond */
+
+#endif /* RUBY3_ARITHMETIC_LONG_H */
diff --git a/include/ruby/3/arithmetic/long_long.h b/include/ruby/3/arithmetic/long_long.h
new file mode 100644
index 0000000000..571edfe8c4
--- /dev/null
+++ b/include/ruby/3/arithmetic/long_long.h
@@ -0,0 +1,53 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `long long` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMETIC_LONG_LONG_H
+#define RUBY3_ARITHMETIC_LONG_LONG_H
+#include "ruby/3/value.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/special_consts.h"
+#include "ruby/backward/2/long_long.h"
+
+#define RB_LL2NUM rb_ll2inum
+#define RB_ULL2NUM rb_ull2inum
+#define LL2NUM RB_LL2NUM
+#define ULL2NUM RB_ULL2NUM
+#define RB_NUM2LL rb_num2ll_inline
+#define RB_NUM2ULL rb_num2ull
+#define NUM2LL RB_NUM2LL
+#define NUM2ULL RB_NUM2ULL
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+VALUE rb_ll2inum(LONG_LONG);
+VALUE rb_ull2inum(unsigned LONG_LONG);
+LONG_LONG rb_num2ll(VALUE);
+unsigned LONG_LONG rb_num2ull(VALUE);
+RUBY3_SYMBOL_EXPORT_END()
+
+static inline LONG_LONG
+rb_num2ll_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return RB_FIX2LONG(x);
+ else
+ return rb_num2ll(x);
+}
+
+#endif /* RUBY3_ARITHMETIC_LONG_LONG_H */
diff --git a/include/ruby/3/arithmetic/mode_t.h b/include/ruby/3/arithmetic/mode_t.h
new file mode 100644
index 0000000000..54ccd376f8
--- /dev/null
+++ b/include/ruby/3/arithmetic/mode_t.h
@@ -0,0 +1,30 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `mode_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/int.h"
+
+#ifndef NUM2MODET
+# define NUM2MODET RB_NUM2INT
+#endif
+
+#ifndef MODET2NUM
+# define MODET2NUM RB_INT2NUM
+#endif
diff --git a/include/ruby/3/arithmetic/off_t.h b/include/ruby/3/arithmetic/off_t.h
new file mode 100644
index 0000000000..dd964b5446
--- /dev/null
+++ b/include/ruby/3/arithmetic/off_t.h
@@ -0,0 +1,45 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `off_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/int.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/arithmetic/long_long.h"
+#include "ruby/backward/2/long_long.h"
+
+#ifdef OFFT2NUM
+# /* take that. */
+#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
+# define OFFT2NUM RB_LL2NUM
+#elif SIZEOF_OFF_T == SIZEOF_LONG
+# define OFFT2NUM RB_LONG2NUM
+#else
+# define OFFT2NUM RB_INT2NUM
+#endif
+
+#ifdef NUM2OFFT
+# /* take that. */
+#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
+# define NUM2OFFT RB_NUM2LL
+#elif SIZEOF_OFF_T == SIZEOF_LONG
+# define NUM2OFFT RB_NUM2LONG
+#else
+# define NUM2OFFT RB_NUM2INT
+#endif
diff --git a/include/ruby/3/arithmetic/pid_t.h b/include/ruby/3/arithmetic/pid_t.h
new file mode 100644
index 0000000000..bca0248d2a
--- /dev/null
+++ b/include/ruby/3/arithmetic/pid_t.h
@@ -0,0 +1,30 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `pid_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/long.h"
+
+#ifndef PIDT2NUM
+# define PIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2PIDT
+# define NUM2PIDT RB_NUM2LONG
+#endif
diff --git a/include/ruby/3/arithmetic/short.h b/include/ruby/3/arithmetic/short.h
new file mode 100644
index 0000000000..fd2106c216
--- /dev/null
+++ b/include/ruby/3/arithmetic/short.h
@@ -0,0 +1,54 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `short` and Ruby's.
+ *
+ * Shyouhei wonders: why there is no SHORT2NUM, given there are both
+ * #USHORT2NUM and #CHR2FIX?
+ */
+#ifndef RUBY3_ARITHMETIC_SHORT_H
+#define RUBY3_ARITHMETIC_SHORT_H
+#include "ruby/3/value.h"
+#include "ruby/3/dllexport.h"
+#include "ruby/3/special_consts.h"
+
+#define RB_NUM2SHORT rb_num2short_inline
+#define RB_NUM2USHORT rb_num2ushort
+#define NUM2SHORT RB_NUM2SHORT
+#define NUM2USHORT RB_NUM2USHORT
+#define USHORT2NUM RB_INT2FIX
+#define RB_FIX2SHORT rb_fix2short
+#define FIX2SHORT RB_FIX2SHORT
+
+RUBY3_SYMBOL_EXPORT_BEGIN()
+short rb_num2short(VALUE);
+unsigned short rb_num2ushort(VALUE);
+short rb_fix2short(VALUE);
+unsigned short rb_fix2ushort(VALUE);
+RUBY3_SYMBOL_EXPORT_END()
+
+static inline short
+rb_num2short_inline(VALUE x)
+{
+ if (RB_FIXNUM_P(x))
+ return rb_fix2short(x);
+ else
+ return rb_num2short(x);
+}
+
+#endif /* RUBY3_ARITHMETIC_SOHRT_H */
diff --git a/include/ruby/3/arithmetic/size_t.h b/include/ruby/3/arithmetic/size_t.h
new file mode 100644
index 0000000000..70161c3ab0
--- /dev/null
+++ b/include/ruby/3/arithmetic/size_t.h
@@ -0,0 +1,47 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `size_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/int.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/arithmetic/long_long.h"
+#include "ruby/backward/2/long_long.h"
+
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define SIZET2NUM RB_ULL2NUM
+# define SSIZET2NUM RB_LL2NUM
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define SIZET2NUM RB_ULONG2NUM
+# define SSIZET2NUM RB_LONG2NUM
+#else
+# define SIZET2NUM RB_UINT2NUM
+# define SSIZET2NUM RB_INT2NUM
+#endif
+
+#if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define NUM2SIZET RB_NUM2ULL
+# define NUM2SSIZET RB_NUM2LL
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define NUM2SIZET RB_NUM2ULONG
+# define NUM2SSIZET RB_NUM2LONG
+#else
+# define NUM2SIZET RB_NUM2UINT
+# define NUM2SSIZET RB_NUM2INT
+#endif
diff --git a/include/ruby/3/arithmetic/st_data_t.h b/include/ruby/3/arithmetic/st_data_t.h
new file mode 100644
index 0000000000..a4917a42f4
--- /dev/null
+++ b/include/ruby/3/arithmetic/st_data_t.h
@@ -0,0 +1,59 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `st_data_t` and Ruby's.
+ */
+#ifndef RUBY3_ARITHMERIC_ST_DATA_T_H
+#define RUBY3_ARITHMERIC_ST_DATA_T_H
+#include "ruby/3/arithmetic/fixnum.h"
+#include "ruby/3/arithmetic/long.h"
+#include "ruby/3/attr/artificial.h"
+#include "ruby/3/attr/const.h"
+#include "ruby/3/attr/constexpr.h"
+#include "ruby/3/cast.h"
+#include "ruby/3/value.h"
+#include "ruby/assert.h"
+#include "ruby/st.h"
+
+#define ST2FIX RB_ST2FIX
+/** @cond INTERNAL_MACRO */
+#define RB_ST2FIX RB_ST2FIX
+/** @endcond */
+
+RUBY3_ATTR_CONST_ON_NDEBUG()
+RUBY3_ATTR_CONSTEXPR_ON_NDEBUG(CXX14)
+RUBY3_ATTR_ARTIFICIAL()
+/* See also [ruby-core:84395] [Bug #14218] [ruby-core:82687] [Bug #13877] */
+static inline VALUE
+RB_ST2FIX(st_data_t i)
+{
+ SIGNED_VALUE x = i;
+
+ if (x >= 0) {
+ x &= RUBY_FIXNUM_MAX;
+ }
+ else {
+ x |= RUBY_FIXNUM_MIN;
+ }
+
+ RUBY3_ASSERT_OR_ASSUME(RB_FIXABLE(x));
+ unsigned long y = RUBY3_CAST((unsigned long)x);
+ return RB_LONG2FIX(y);
+}
+
+#endif /* RUBY3_ARITHMERIC_ST_DATA_T_H */
diff --git a/include/ruby/3/arithmetic/uid_t.h b/include/ruby/3/arithmetic/uid_t.h
new file mode 100644
index 0000000000..45b1f5a9ca
--- /dev/null
+++ b/include/ruby/3/arithmetic/uid_t.h
@@ -0,0 +1,30 @@
+/** \noop-*-C++-*-vi:ft=cpp
+ * @file
+ * @author Ruby developers <ruby-core@ruby-lang.org>
+ * @copyright This file is a part of the programming language Ruby.
+ * 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.
+ * @warning Symbols prefixed with either `RUBY3` or `ruby3` are
+ * implementation details. Don't take them as canon. They could
+ * rapidly appear then vanish. The name (path) of this header file
+ * is also an implementation detail. Do not expect it to persist
+ * at the place it is now. Developers are free to move it anywhere
+ * anytime at will.
+ * @note To ruby-core: remember that this header can be possibly
+ * recursively included from extension libraries written in C++.
+ * Do not expect for instance `__VA_ARGS__` is always available.
+ * We assume C99 for ruby itself but we don't assume languages of
+ * extension libraries. They could be written in C++98.
+ * @brief Arithmetic conversion between C's `uid_t` and Ruby's.
+ */
+#include "ruby/3/config.h"
+#include "ruby/3/arithmetic/long.h"
+
+#ifndef UIDT2NUM
+# define UIDT2NUM RB_LONG2NUM
+#endif
+
+#ifndef NUM2UIDT
+# define NUM2UIDT RB_NUM2LONG
+#endif