From 3c3eb418f9ce05740e5ca506b9cd5fe5cabc4bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Tue, 28 Jan 2020 17:02:30 +0900 Subject: [PATCH] improved support for rb_f_notimplement rb_f_notimplement should be accepted for all possible arities. Test provided for that. --- ext/-test-/cxxanyargs/cxxanyargs.cpp | 30 ++++++++++++++++++++++++++++ include/ruby/backward/cxxanyargs.hpp | 20 +++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ext/-test-/cxxanyargs/cxxanyargs.cpp b/ext/-test-/cxxanyargs/cxxanyargs.cpp index efe35fa359..eef2387650 100644 --- a/ext/-test-/cxxanyargs/cxxanyargs.cpp +++ b/ext/-test-/cxxanyargs/cxxanyargs.cpp @@ -383,6 +383,12 @@ namespace test_rb_define_method { rb_define_method(self, "ma", (VALUE (*)(...))(ma), -2); rb_define_method(self, "mv", (VALUE (*)(...))(mv), -1); + // rb_f_notimplement + rb_define_method(self, "m1", rb_f_notimplement, 1); + rb_define_method(self, "m2", rb_f_notimplement, 2); + rb_define_method(self, "ma", rb_f_notimplement, -2); + rb_define_method(self, "mv", rb_f_notimplement, -1); + return self; } } @@ -433,6 +439,12 @@ namespace test_rb_define_module_function { rb_define_module_function(self, "ma", (VALUE (*)(...))(ma), -2); rb_define_module_function(self, "mv", (VALUE (*)(...))(mv), -1); + // rb_f_notimplement + rb_define_module_function(self, "m1", rb_f_notimplement, 1); + rb_define_module_function(self, "m2", rb_f_notimplement, 2); + rb_define_module_function(self, "ma", rb_f_notimplement, -2); + rb_define_module_function(self, "mv", rb_f_notimplement, -1); + return self; } } @@ -483,6 +495,12 @@ namespace test_rb_define_singleton_method { rb_define_singleton_method(self, "ma", (VALUE (*)(...))(ma), -2); rb_define_singleton_method(self, "mv", (VALUE (*)(...))(mv), -1); + // rb_f_notimplement + rb_define_singleton_method(self, "m1", rb_f_notimplement, 1); + rb_define_singleton_method(self, "m2", rb_f_notimplement, 2); + rb_define_singleton_method(self, "ma", rb_f_notimplement, -2); + rb_define_singleton_method(self, "mv", rb_f_notimplement, -1); + return self; } } @@ -533,6 +551,12 @@ namespace test_rb_define_protected_method { rb_define_protected_method(self, "ma", (VALUE (*)(...))(ma), -2); rb_define_protected_method(self, "mv", (VALUE (*)(...))(mv), -1); + // rb_f_notimplement + rb_define_protected_method(self, "m1", rb_f_notimplement, 1); + rb_define_protected_method(self, "m2", rb_f_notimplement, 2); + rb_define_protected_method(self, "ma", rb_f_notimplement, -2); + rb_define_protected_method(self, "mv", rb_f_notimplement, -1); + return self; } } @@ -583,6 +607,12 @@ namespace test_rb_define_private_method { rb_define_private_method(self, "ma", (VALUE (*)(...))(ma), -2); rb_define_private_method(self, "mv", (VALUE (*)(...))(mv), -1); + // rb_f_notimplement + rb_define_private_method(self, "m1", rb_f_notimplement, 1); + rb_define_private_method(self, "m2", rb_f_notimplement, 2); + rb_define_private_method(self, "ma", rb_f_notimplement, -2); + rb_define_private_method(self, "mv", rb_f_notimplement, -1); + return self; } } diff --git a/include/ruby/backward/cxxanyargs.hpp b/include/ruby/backward/cxxanyargs.hpp index 16529f8db2..31758c14e5 100644 --- a/include/ruby/backward/cxxanyargs.hpp +++ b/include/ruby/backward/cxxanyargs.hpp @@ -446,6 +446,9 @@ rb_ivar_foreach(VALUE q, int_type *w, VALUE e) /// types and provide warnings for other cases. This is such attempt. namespace define_method { +/// @brief type of rb_f_notimplement +typedef VALUE notimpl_type(int, const VALUE *, VALUE, VALUE); + /// @brief Template metaprogramming to generate function prototypes. /// @tparam T Type of method id (`ID` or `const char*` in practice). /// @tparam F Definition driver e.g. ::rb_define_method. @@ -490,6 +493,16 @@ struct driver { { F(klass, mid, reinterpret_cast(func), N); } + + /// @brief Defines klass#mid as func, whose arity is N. + /// @param[in] klass Where the method lives. + /// @param[in] mid Name of the method to define. + /// @param[in] func Function that implements klass#mid. + static inline void + define(VALUE klass, T mid, notimpl_type func) + { + F(klass, mid, reinterpret_cast(func), N); + } }; /// @cond INTERNAL_MACRO @@ -513,7 +526,6 @@ struct driver { template struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> { using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define; static inline void define(VALUE c, T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(c, m, reinterpret_cast(f), -1); } - static inline void define(VALUE c, T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self, VALUE)) { F(c, m, reinterpret_cast(f), -1); } }; template struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {}; /// @endcond @@ -536,6 +548,11 @@ struct driver0 { { F(mid, reinterpret_cast(func), N); } + static inline void + define(T mid, notimpl_type func) + { + F(mid, reinterpret_cast(func), N); + } }; /// @cond INTERNAL_MACRO template struct specific : public engine {}; @@ -557,7 +574,6 @@ struct driver0 { template struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {}; template struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> { using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define; - static inline void define(T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(m, reinterpret_cast(f), -1); } static inline void define(T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self, VALUE)) { F(m, reinterpret_cast(f), -1); } }; template struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};