ruby-changes:59888
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 31 Jan 2020 13:14:04 +0900 (JST)
Subject: [ruby-changes:59888] cdd75d4e7f (master): support C++ std::nullptr_t
https://git.ruby-lang.org/ruby.git/commit/?id=cdd75d4e7f From cdd75d4e7f0402a0537c516b7331a036347b0fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Fri, 31 Jan 2020 12:01:39 +0900 Subject: support C++ std::nullptr_t C++ keyword `nullptr` represents a null pointer (note also that NULL is an integer in C++ due to its design flaw). Its type is `std::nullptr_t`, defined in <cstddef> standard header. Why not support it when the backend implementation can take a null pointer as an argument. diff --git a/configure.ac b/configure.ac index 548849d..b0e09a5 100644 --- a/configure.ac +++ b/configure.ac @@ -1437,6 +1437,17 @@ AS_IF([test "$rb_cv_CentOS6_CXX_workaround" != no],[ https://github.com/ruby/ruby/blob/trunk/configure.ac#L1437 AC_DEFINE([RUBY_CXX_DEPRECATED(msg)], [__attribute__((__deprecated__(msg)))])]) +AC_CACHE_CHECK([for std::nullptr_t], rb_cv_CXX_nullptr, [ + AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [@%:@include <cstddef>], + [static std::nullptr_t const *const conftest = nullptr;])], + [rb_cv_CXX_nullptr=yes], + [rb_cv_CXX_nullptr=no]) + AC_LANG_POP()]) +AS_IF([test "$rb_cv_CXX_nullptr" != no],[AC_DEFINE(HAVE_NULLPTR)]) + if_i386=${universal_binary+[defined __i386__]} RUBY_FUNC_ATTRIBUTE(__stdcall__, FUNC_STDCALL, rb_cv_func_stdcall, ${if_i386}) RUBY_FUNC_ATTRIBUTE(__cdecl__, FUNC_CDECL, rb_cv_func_cdecl, ${if_i386}) diff --git a/ext/-test-/cxxanyargs/cxxanyargs.cpp b/ext/-test-/cxxanyargs/cxxanyargs.cpp index 812c6d7..b0d48e0 100644 --- a/ext/-test-/cxxanyargs/cxxanyargs.cpp +++ b/ext/-test-/cxxanyargs/cxxanyargs.cpp @@ -36,6 +36,18 @@ namespace test_rb_define_virtual_variable { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L36 RUBY_METHOD_FUNC(getter), reinterpret_cast<void(*)(ANYARGS)>(setter)); // old rb_define_virtual_variable("test", getter, setter); // new + +#ifdef HAVE_NULLPTR + rb_define_virtual_variable("test", nullptr, reinterpret_cast<void(*)(ANYARGS)>(setter)); + rb_define_virtual_variable("test", nullptr, setter); + + rb_define_virtual_variable("test", RUBY_METHOD_FUNC(getter), nullptr); + rb_define_virtual_variable("test", getter, nullptr); + + // It doesn't make any sense for both function pointers be nullptr at + // the same time. +#endif + return self; } } @@ -62,6 +74,18 @@ struct test_rb_define_hooked_variable { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L74 RUBY_METHOD_FUNC(getter), reinterpret_cast<void(*)(ANYARGS)>(setter)); // old rb_define_hooked_variable("test", &v, getter, setter); // new + +#ifdef HAVE_NULLPTR + rb_define_hooked_variable("test", &v, nullptr, reinterpret_cast<void(*)(ANYARGS)>(setter)); + rb_define_hooked_variable("test", &v, nullptr, setter); + + rb_define_hooked_variable("test", &v, RUBY_METHOD_FUNC(getter), nullptr); + rb_define_hooked_variable("test", &v, getter, nullptr); + + // It doesn't make any sense for both function pointers be nullptr at + // the same time. +#endif + return self; } }; @@ -83,6 +107,10 @@ namespace test_rb_iterate { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L107 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + rb_iterate(iter, self, nullptr, self); +#endif + rb_iterate(iter, self, RUBY_METHOD_FUNC(block), self); // old return rb_iterate(iter, self, block, self); // new } @@ -100,6 +128,11 @@ namespace test_rb_block_call { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L128 { const ID mid = rb_intern("each"); const VALUE argv[] = { Qundef }; + +#ifdef HAVE_NULLPTR + rb_block_call(self, mid, 0, argv, nullptr, self); +#endif + rb_block_call(self, mid, 0, argv, RUBY_METHOD_FUNC(block), self); // old return rb_block_call(self, mid, 0, argv, block, self); // new } @@ -121,6 +154,11 @@ namespace test_rb_rescue { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L154 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + rb_rescue(RUBY_METHOD_FUNC(begin), self, nullptr, self); + return rb_rescue(begin, self, nullptr, self); +#endif + rb_rescue(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(rescue), self); // old return rb_rescue(begin, self, rescue, self); // new } @@ -142,6 +180,11 @@ namespace test_rb_rescue2 { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L180 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + rb_rescue2(RUBY_METHOD_FUNC(begin), self, nullptr, self, rb_eStandardError, rb_eFatal, 0); + rb_rescue2(begin, self, nullptr, self, rb_eStandardError, rb_eFatal, 0); +#endif + rb_rescue2(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(rescue), self, rb_eStandardError, rb_eFatal, 0); // old return rb_rescue2(begin, self, rescue, self, rb_eStandardError, rb_eFatal, 0); // new @@ -164,6 +207,11 @@ namespace test_rb_ensure { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L207 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + rb_ensure(RUBY_METHOD_FUNC(begin), self, nullptr, self); + rb_ensure(begin, self, nullptr, self); +#endif + rb_ensure(RUBY_METHOD_FUNC(begin), self, RUBY_METHOD_FUNC(ensure), self); // old return rb_ensure(begin, self, ensure, self); // new } @@ -180,6 +228,11 @@ namespace test_rb_catch { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L228 test(VALUE self) { static const char *zero = 0; + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as a catcher. +#endif + rb_catch(zero, RUBY_METHOD_FUNC(catcher), self); // old return rb_catch(zero, catcher, self); // new } @@ -195,6 +248,10 @@ namespace test_rb_catch_obj { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L248 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as a catcher. +#endif + rb_catch_obj(self, RUBY_METHOD_FUNC(catcher), self); // old return rb_catch_obj(self, catcher, self); // new } @@ -210,6 +267,10 @@ namespace test_rb_fiber_new { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L267 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as a fiber. +#endif + rb_fiber_new(RUBY_METHOD_FUNC(fiber), self); // old return rb_fiber_new(fiber, self); // new } @@ -225,6 +286,10 @@ namespace test_rb_proc_new { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L286 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as a proc. +#endif + rb_fiber_new(RUBY_METHOD_FUNC(proc), self); // old return rb_fiber_new(proc, self); // new } @@ -244,6 +309,11 @@ struct test_rb_thread_create { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L309 test(VALUE self) { v = self; + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as a thread. +#endif + rb_thread_create(RUBY_METHOD_FUNC(thread), &v); // old return rb_thread_create(thread, &v); // new } @@ -262,6 +332,11 @@ namespace test_st_foreach { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L332 { st_data_t data = 0; st_table *st = st_init_numtable(); + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as an iterator. +#endif + st_foreach(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data); // old st_foreach(st, iter, data); // new return self; @@ -280,6 +355,11 @@ namespace test_st_foreach_check { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L355 { st_data_t data = 0; st_table *st = st_init_numtable(); + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as an iterator. +#endif + st_foreach_check(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data, data); // old st_foreach_check(st, iter, data, data); // new return self; @@ -298,6 +378,11 @@ namespace test_st_foreach_safe { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L378 { st_data_t data = 0; st_table *st = st_init_numtable(); + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as an iterator. +#endif + st_foreach_safe(st, reinterpret_cast<int(*)(ANYARGS)>(iter), data); // old st_foreach_safe(st, iter, data); // new return self; @@ -315,6 +400,11 @@ namespace test_rb_hash_foreach { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L400 test(VALUE self) { VALUE h = rb_hash_new(); + +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as an iterator. +#endif + rb_hash_foreach(h, reinterpret_cast<int(*)(ANYARGS)>(iter), self); // old rb_hash_foreach(h, iter, self); // new return self; @@ -331,6 +421,10 @@ namespace test_rb_ivar_foreach { https://github.com/ruby/ruby/blob/trunk/ext/-test-/cxxanyargs/cxxanyargs.cpp#L421 VALUE test(VALUE self) { +#ifdef HAVE_NULLPTR + // It doesn't make any sense at all to pass nullptr as an iterator. +#endif + rb_ivar_foreach(self, reinterpret_cast<int(*)(ANYARGS)>(iter), self); // old rb_i (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/