rice 4.0.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/Rakefile +1 -1
  4. data/include/rice/rice.hpp +2597 -1771
  5. data/include/rice/stl.hpp +1580 -271
  6. data/lib/mkmf-rice.rb +5 -2
  7. data/lib/version.rb +1 -1
  8. data/rice/Arg.hpp +6 -6
  9. data/rice/Arg.ipp +8 -9
  10. data/rice/Constructor.hpp +2 -2
  11. data/rice/Data_Object.ipp +69 -15
  12. data/rice/Data_Object_defn.hpp +1 -15
  13. data/rice/Data_Type.ipp +56 -86
  14. data/rice/Data_Type_defn.hpp +14 -17
  15. data/rice/Director.hpp +0 -1
  16. data/rice/Enum.ipp +31 -22
  17. data/rice/Exception.ipp +2 -3
  18. data/rice/Exception_defn.hpp +5 -5
  19. data/rice/HandlerRegistration.hpp +15 -0
  20. data/rice/Return.hpp +5 -4
  21. data/rice/Return.ipp +8 -3
  22. data/rice/detail/ExceptionHandler.hpp +8 -0
  23. data/rice/detail/ExceptionHandler.ipp +28 -0
  24. data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
  25. data/rice/detail/HandlerRegistry.hpp +51 -0
  26. data/rice/detail/HandlerRegistry.ipp +20 -0
  27. data/rice/detail/InstanceRegistry.hpp +34 -0
  28. data/rice/detail/InstanceRegistry.ipp +50 -0
  29. data/rice/detail/MethodInfo.ipp +1 -1
  30. data/rice/detail/NativeAttribute.hpp +26 -15
  31. data/rice/detail/NativeAttribute.ipp +76 -47
  32. data/rice/detail/NativeFunction.hpp +60 -13
  33. data/rice/detail/NativeFunction.ipp +103 -85
  34. data/rice/detail/NativeIterator.hpp +49 -0
  35. data/rice/detail/NativeIterator.ipp +102 -0
  36. data/rice/detail/NativeRegistry.hpp +31 -0
  37. data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
  38. data/rice/detail/Registries.hpp +26 -0
  39. data/rice/detail/Registries.ipp +23 -0
  40. data/rice/detail/RubyFunction.hpp +6 -11
  41. data/rice/detail/RubyFunction.ipp +10 -22
  42. data/rice/detail/Type.hpp +1 -1
  43. data/rice/detail/Type.ipp +3 -2
  44. data/rice/detail/TypeRegistry.hpp +8 -11
  45. data/rice/detail/TypeRegistry.ipp +3 -28
  46. data/rice/detail/Wrapper.hpp +0 -2
  47. data/rice/detail/Wrapper.ipp +73 -23
  48. data/rice/detail/cpp_protect.hpp +93 -0
  49. data/rice/detail/default_allocation_func.ipp +1 -1
  50. data/rice/detail/from_ruby.ipp +206 -2
  51. data/rice/detail/to_ruby.ipp +39 -5
  52. data/rice/detail/to_ruby_defn.hpp +1 -1
  53. data/rice/forward_declares.ipp +6 -0
  54. data/rice/global_function.hpp +0 -4
  55. data/rice/global_function.ipp +0 -6
  56. data/rice/rice.hpp +29 -24
  57. data/rice/stl.hpp +6 -1
  58. data/test/embed_ruby.cpp +0 -14
  59. data/test/test_Array.cpp +20 -24
  60. data/test/test_Class.cpp +8 -47
  61. data/test/test_Constructor.cpp +0 -2
  62. data/test/test_Data_Object.cpp +25 -11
  63. data/test/test_Data_Type.cpp +124 -28
  64. data/test/test_Director.cpp +12 -13
  65. data/test/test_Enum.cpp +65 -26
  66. data/test/test_Inheritance.cpp +9 -9
  67. data/test/test_Iterator.cpp +134 -5
  68. data/test/test_Keep_Alive.cpp +7 -7
  69. data/test/test_Memory_Management.cpp +1 -1
  70. data/test/test_Module.cpp +25 -62
  71. data/test/test_Object.cpp +66 -3
  72. data/test/test_Ownership.cpp +12 -13
  73. data/test/test_Self.cpp +12 -13
  74. data/test/test_Stl_Map.cpp +696 -0
  75. data/test/test_Stl_Optional.cpp +3 -3
  76. data/test/test_Stl_Pair.cpp +38 -2
  77. data/test/test_Stl_Reference_Wrapper.cpp +102 -0
  78. data/test/test_Stl_SmartPointer.cpp +5 -5
  79. data/test/test_Stl_Unordered_Map.cpp +697 -0
  80. data/test/test_Stl_Variant.cpp +301 -0
  81. data/test/test_Stl_Vector.cpp +200 -41
  82. data/test/test_Struct.cpp +3 -3
  83. data/test/test_To_From_Ruby.cpp +6 -0
  84. data/test/test_Tracking.cpp +239 -0
  85. data/test/unittest.hpp +13 -4
  86. metadata +23 -13
  87. data/rice/detail/Exception_Handler.hpp +0 -8
  88. data/rice/detail/Exception_Handler.ipp +0 -28
  89. data/rice/detail/Iterator.hpp +0 -23
  90. data/rice/detail/Iterator.ipp +0 -47
  91. data/rice/detail/function_traits.hpp +0 -124
  92. data/rice/detail/method_data.hpp +0 -29
  93. data/rice/detail/rice_traits.hpp +0 -116
  94. data/rice/ruby_try_catch.hpp +0 -86
@@ -0,0 +1,239 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+
4
+ #include <rice/rice.hpp>
5
+
6
+ using namespace Rice;
7
+
8
+ TESTSUITE(Tracking);
9
+
10
+ namespace
11
+ {
12
+ class MyClass
13
+ {
14
+ };
15
+
16
+ class Factory
17
+ {
18
+ public:
19
+ static void reset()
20
+ {
21
+ delete Factory::instance_;
22
+ Factory::instance_ = nullptr;
23
+ }
24
+
25
+ public:
26
+ Factory* factory()
27
+ {
28
+ return this;
29
+ }
30
+
31
+ MyClass* transferPointer()
32
+ {
33
+ return new MyClass();
34
+ }
35
+
36
+ MyClass* keepPointer()
37
+ {
38
+ return this->instance();
39
+ }
40
+
41
+ MyClass& keepReference()
42
+ {
43
+ return *this->instance();
44
+ }
45
+
46
+ MyClass value()
47
+ {
48
+ return MyClass();
49
+ }
50
+
51
+ MyClass moveValue()
52
+ {
53
+ return std::move(MyClass());
54
+ }
55
+
56
+ MyClass* instance()
57
+ {
58
+ if (!instance_)
59
+ {
60
+ instance_ = new MyClass();
61
+ }
62
+ return instance_;
63
+ }
64
+
65
+ public:
66
+ static inline MyClass* instance_ = nullptr;
67
+ };
68
+ }
69
+
70
+ SETUP(Tracking)
71
+ {
72
+ embed_ruby();
73
+
74
+ define_class<MyClass>("MyClass");
75
+
76
+ define_class<Factory>("Factory").
77
+ define_constructor(Constructor<Factory>()).
78
+ define_method("factory", &Factory::factory).
79
+ define_method("value", &Factory::value).
80
+ define_method("move_value", &Factory::moveValue).
81
+ define_method("transfer_pointer", &Factory::transferPointer, Return().takeOwnership()).
82
+ define_method("keep_pointer", &Factory::keepPointer).
83
+ define_method("copy_reference", &Factory::keepReference, Return().takeOwnership()).
84
+ define_method("keep_reference", &Factory::keepReference);
85
+ }
86
+
87
+ TEARDOWN(Tracking)
88
+ {
89
+ detail::Registries::instance.instances.isEnabled = true;
90
+ }
91
+
92
+ TESTCASE(TransferPointer)
93
+ {
94
+ detail::Registries::instance.instances.isEnabled = true;
95
+ Factory::reset();
96
+
97
+ Module m = define_module("TestingModule");
98
+ Object factory = m.module_eval("Factory.new");
99
+
100
+ Data_Object<MyClass> my_class1 = factory.call("transfer_pointer");
101
+ Data_Object<MyClass> my_class2 = factory.call("transfer_pointer");
102
+
103
+ ASSERT(!my_class1.is_equal(my_class2));
104
+ ASSERT_NOT_EQUAL(my_class1.get(), my_class2.get());
105
+ }
106
+
107
+ TESTCASE(KeepPointer)
108
+ {
109
+ detail::Registries::instance.instances.isEnabled = true;
110
+ Factory::reset();
111
+
112
+ Module m = define_module("TestingModule");
113
+
114
+ Object factory = m.module_eval("Factory.new");
115
+
116
+ Data_Object<MyClass> my_class1 = factory.call("keep_pointer");
117
+ Data_Object<MyClass> my_class2 = factory.call("keep_pointer");
118
+
119
+ ASSERT(my_class1.is_equal(my_class2));
120
+ ASSERT_EQUAL(my_class1.get(), my_class2.get());
121
+ }
122
+
123
+ TESTCASE(KeepPointerWithoutTracking)
124
+ {
125
+ detail::Registries::instance.instances.isEnabled = false;
126
+ Factory::reset();
127
+
128
+ Module m = define_module("TestingModule");
129
+
130
+ Object factory = m.module_eval("Factory.new");
131
+
132
+ Data_Object<MyClass> my_class1 = factory.call("keep_pointer");
133
+ Data_Object<MyClass> my_class2 = factory.call("keep_pointer");
134
+
135
+ ASSERT(!my_class1.is_equal(my_class2));
136
+ ASSERT_EQUAL(my_class1.get(), my_class2.get());
137
+ }
138
+
139
+ TESTCASE(KeepReference)
140
+ {
141
+ detail::Registries::instance.instances.isEnabled = true;
142
+ Factory::reset();
143
+
144
+ Module m = define_module("TestingModule");
145
+
146
+ Object factory = m.module_eval("Factory.new");
147
+
148
+ Data_Object<MyClass> my_class1 = factory.call("keep_reference");
149
+ Data_Object<MyClass> my_class2 = factory.call("keep_reference");
150
+
151
+ ASSERT(my_class1.is_equal(my_class2));
152
+ ASSERT_EQUAL(my_class1.get(), my_class2.get());
153
+ }
154
+
155
+ TESTCASE(KeepReferenceWithoutTracking)
156
+ {
157
+ detail::Registries::instance.instances.isEnabled = false;
158
+ Factory::reset();
159
+
160
+ Module m = define_module("TestingModule");
161
+
162
+ Object factory = m.module_eval("Factory.new");
163
+
164
+ Data_Object<MyClass> my_class1 = factory.call("keep_reference");
165
+ Data_Object<MyClass> my_class2 = factory.call("keep_reference");
166
+
167
+ ASSERT(!my_class1.is_equal(my_class2));
168
+ ASSERT_EQUAL(my_class1.get(), my_class2.get());
169
+ }
170
+
171
+ TESTCASE(CopyReference)
172
+ {
173
+ detail::Registries::instance.instances.isEnabled = true;
174
+ Factory::reset();
175
+
176
+ Module m = define_module("TestingModule");
177
+ Object factory = m.module_eval("Factory.new");
178
+
179
+ Data_Object<MyClass> my_class1 = factory.call("copy_reference");
180
+ Data_Object<MyClass> my_class2 = factory.call("copy_reference");
181
+
182
+ ASSERT(!my_class1.is_equal(my_class2));
183
+ ASSERT_NOT_EQUAL(my_class1.get(), my_class2.get());
184
+ }
185
+
186
+ TESTCASE(TransferValue)
187
+ {
188
+ detail::Registries::instance.instances.isEnabled = true;
189
+ Factory::reset();
190
+
191
+ Module m = define_module("TestingModule");
192
+ Object factory = m.module_eval("Factory.new");
193
+
194
+ Data_Object<MyClass> my_class1 = factory.call("value");
195
+ Data_Object<MyClass> my_class2 = factory.call("value");
196
+
197
+ ASSERT(!my_class1.is_equal(my_class2));
198
+ ASSERT_NOT_EQUAL(my_class1.get(), my_class2.get());
199
+ }
200
+
201
+ TESTCASE(MoveValue)
202
+ {
203
+ detail::Registries::instance.instances.isEnabled = true;
204
+ Factory::reset();
205
+
206
+ Module m = define_module("TestingModule");
207
+ Object factory = m.module_eval("Factory.new");
208
+
209
+ Data_Object<MyClass> my_class1 = factory.call("move_value");
210
+ Data_Object<MyClass> my_class2 = factory.call("move_value");
211
+
212
+ ASSERT(!my_class1.is_equal(my_class2));
213
+ ASSERT_NOT_EQUAL(my_class1.get(), my_class2.get());
214
+ }
215
+
216
+ TESTCASE(RubyObjectGced)
217
+ {
218
+ detail::Registries::instance.instances.isEnabled = true;
219
+ Factory::reset();
220
+
221
+ Module m = define_module("TestingModule");
222
+ Object factory = m.module_eval("Factory.new");
223
+
224
+ {
225
+ // Track the C++ object returned by keepPointer
226
+ Data_Object<MyClass> my_class1 = factory.call("keep_pointer");
227
+ rb_gc_start();
228
+ }
229
+
230
+ // Make my_class1 invalid
231
+ rb_gc_start();
232
+
233
+ // Get the object again - this should *not* return the previous value
234
+ Data_Object<MyClass> my_class2 = factory.call("keep_pointer");
235
+
236
+ // Call a method on the ruby object
237
+ String className = my_class2.class_name();
238
+ ASSERT_EQUAL(std::string("MyClass"), className.str());
239
+ }
data/test/unittest.hpp CHANGED
@@ -214,6 +214,12 @@ inline bool is_not_equal(T const & t, U const & u)
214
214
 
215
215
  extern size_t assertions;
216
216
 
217
+ template<typename S, typename T, typename = void>
218
+ struct is_streamable: std::false_type {};
219
+
220
+ template<typename S, typename T>
221
+ struct is_streamable<S, T, std::void_t<decltype(std::declval<S&>()<<std::declval<T>())>>: std::true_type {};
222
+
217
223
  template<typename T, typename U>
218
224
  void assert_equal(
219
225
  T const & t,
@@ -226,10 +232,13 @@ void assert_equal(
226
232
  if(!is_equal(t, u))
227
233
  {
228
234
  std::stringstream strm;
229
- strm << "Assertion failed: "
230
- << s_t << " != " << s_u
231
- << " (" << t << " != " << u << ")"
232
- << " at " << file << ":" << line;
235
+ strm << "Assertion failed: ";
236
+
237
+ if constexpr (is_streamable<std::stringstream, T>::value && is_streamable<std::stringstream, U>::value)
238
+ {
239
+ strm << s_t << " != " << s_u;
240
+ }
241
+ strm << " at " << file << ":" << line;
233
242
  throw Assertion_Failed(strm.str());
234
243
  }
235
244
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-01-15 00:00:00.000000000 Z
13
+ date: 2023-04-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -95,15 +95,18 @@ files:
95
95
  - rice/Exception.hpp
96
96
  - rice/Exception.ipp
97
97
  - rice/Exception_defn.hpp
98
+ - rice/HandlerRegistration.hpp
98
99
  - rice/Identifier.hpp
99
100
  - rice/Identifier.ipp
100
101
  - rice/Return.hpp
101
102
  - rice/Return.ipp
102
- - rice/detail/Exception_Handler.hpp
103
- - rice/detail/Exception_Handler.ipp
104
- - rice/detail/Exception_Handler_defn.hpp
105
- - rice/detail/Iterator.hpp
106
- - rice/detail/Iterator.ipp
103
+ - rice/detail/ExceptionHandler.hpp
104
+ - rice/detail/ExceptionHandler.ipp
105
+ - rice/detail/ExceptionHandler_defn.hpp
106
+ - rice/detail/HandlerRegistry.hpp
107
+ - rice/detail/HandlerRegistry.ipp
108
+ - rice/detail/InstanceRegistry.hpp
109
+ - rice/detail/InstanceRegistry.ipp
107
110
  - rice/detail/Jump_Tag.hpp
108
111
  - rice/detail/MethodInfo.hpp
109
112
  - rice/detail/MethodInfo.ipp
@@ -111,6 +114,12 @@ files:
111
114
  - rice/detail/NativeAttribute.ipp
112
115
  - rice/detail/NativeFunction.hpp
113
116
  - rice/detail/NativeFunction.ipp
117
+ - rice/detail/NativeIterator.hpp
118
+ - rice/detail/NativeIterator.ipp
119
+ - rice/detail/NativeRegistry.hpp
120
+ - rice/detail/NativeRegistry.ipp
121
+ - rice/detail/Registries.hpp
122
+ - rice/detail/Registries.ipp
114
123
  - rice/detail/RubyFunction.hpp
115
124
  - rice/detail/RubyFunction.ipp
116
125
  - rice/detail/Type.hpp
@@ -119,15 +128,12 @@ files:
119
128
  - rice/detail/TypeRegistry.ipp
120
129
  - rice/detail/Wrapper.hpp
121
130
  - rice/detail/Wrapper.ipp
131
+ - rice/detail/cpp_protect.hpp
122
132
  - rice/detail/default_allocation_func.hpp
123
133
  - rice/detail/default_allocation_func.ipp
124
134
  - rice/detail/from_ruby.hpp
125
135
  - rice/detail/from_ruby.ipp
126
136
  - rice/detail/from_ruby_defn.hpp
127
- - rice/detail/function_traits.hpp
128
- - rice/detail/method_data.hpp
129
- - rice/detail/method_data.ipp
130
- - rice/detail/rice_traits.hpp
131
137
  - rice/detail/ruby.hpp
132
138
  - rice/detail/to_ruby.hpp
133
139
  - rice/detail/to_ruby.ipp
@@ -137,7 +143,6 @@ files:
137
143
  - rice/global_function.ipp
138
144
  - rice/rice.hpp
139
145
  - rice/ruby_mark.hpp
140
- - rice/ruby_try_catch.hpp
141
146
  - rice/stl.hpp
142
147
  - sample/callbacks/extconf.rb
143
148
  - sample/callbacks/sample_callbacks.cpp
@@ -185,15 +190,20 @@ files:
185
190
  - test/test_Object.cpp
186
191
  - test/test_Ownership.cpp
187
192
  - test/test_Self.cpp
193
+ - test/test_Stl_Map.cpp
188
194
  - test/test_Stl_Optional.cpp
189
195
  - test/test_Stl_Pair.cpp
196
+ - test/test_Stl_Reference_Wrapper.cpp
190
197
  - test/test_Stl_SmartPointer.cpp
191
198
  - test/test_Stl_String.cpp
199
+ - test/test_Stl_Unordered_Map.cpp
200
+ - test/test_Stl_Variant.cpp
192
201
  - test/test_Stl_Vector.cpp
193
202
  - test/test_String.cpp
194
203
  - test/test_Struct.cpp
195
204
  - test/test_Symbol.cpp
196
205
  - test/test_To_From_Ruby.cpp
206
+ - test/test_Tracking.cpp
197
207
  - test/test_global_functions.cpp
198
208
  - test/unittest.cpp
199
209
  - test/unittest.hpp
@@ -220,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
230
  - !ruby/object:Gem::Version
221
231
  version: '0'
222
232
  requirements: []
223
- rubygems_version: 3.2.32
233
+ rubygems_version: 3.4.12
224
234
  signing_key:
225
235
  specification_version: 4
226
236
  summary: Ruby Interface for C++ Extensions
@@ -1,8 +0,0 @@
1
- #ifndef Rice__detail__Exception_Handler__hpp_
2
- #define Rice__detail__Exception_Handler__hpp_
3
-
4
- #include "Exception_Handler_defn.hpp"
5
- #include "Exception_Handler.ipp"
6
-
7
- #endif // Rice__detail__Exception_Handler__hpp_
8
-
@@ -1,28 +0,0 @@
1
- namespace Rice::detail
2
- {
3
- inline VALUE Rice::detail::Default_Exception_Handler::handle_exception() const
4
- {
5
- throw;
6
- }
7
-
8
- template <typename Exception_T, typename Functor_T>
9
- inline Rice::detail::Functor_Exception_Handler<Exception_T, Functor_T>::
10
- Functor_Exception_Handler(Functor_T handler, std::shared_ptr<Exception_Handler> next_exception_handler)
11
- : handler_(handler), next_exception_handler_(next_exception_handler)
12
- {
13
- }
14
-
15
- template <typename Exception_T, typename Functor_T>
16
- inline VALUE Rice::detail::Functor_Exception_Handler<Exception_T, Functor_T>::handle_exception() const
17
- {
18
- try
19
- {
20
- return this->next_exception_handler_->handle_exception();
21
- }
22
- catch (Exception_T const& ex)
23
- {
24
- handler_(ex);
25
- throw;
26
- }
27
- }
28
- }
@@ -1,23 +0,0 @@
1
- #ifndef Rice_Iterator__hpp_
2
- #define Rice_Iterator__hpp_
3
-
4
- namespace Rice::detail
5
- {
6
- template<typename T, typename Iterator_T>
7
- class Iterator
8
- {
9
- public:
10
- static VALUE call(VALUE self);
11
-
12
- public:
13
- Iterator(Iterator_T(T::* begin)(), Iterator_T(T::* end)());
14
- virtual ~Iterator() = default;
15
- VALUE operator()(VALUE self);
16
-
17
- private:
18
- Iterator_T(T::* begin_)();
19
- Iterator_T(T::* end_)();
20
- };
21
- }
22
-
23
- #endif // Rice_Iterator__hpp_
@@ -1,47 +0,0 @@
1
- #ifndef Rice_Iterator__ipp_
2
- #define Rice_Iterator__ipp_
3
-
4
- #include <iterator>
5
- #include <functional>
6
-
7
- #include "../Data_Object_defn.hpp"
8
- #include "method_data.hpp"
9
-
10
- namespace Rice::detail
11
- {
12
- template <typename T, typename Iterator_T>
13
- inline Iterator<T, Iterator_T>::
14
- Iterator(Iterator_T(T::* begin)(), Iterator_T(T::* end)()) :
15
- begin_(begin), end_(end)
16
- {
17
- }
18
-
19
- template<typename T, typename Iterator_T>
20
- inline VALUE Iterator<T, Iterator_T>::
21
- call(VALUE self)
22
- {
23
- using Iter_T = Iterator<T, Iterator_T>;
24
- Iter_T* iterator = detail::MethodData::data<Iter_T*>();
25
- return iterator->operator()(self);
26
- }
27
-
28
- template<typename T, typename Iterator_T>
29
- inline VALUE Iterator<T, Iterator_T>::
30
- operator()(VALUE self)
31
- {
32
- using Value_T = typename std::iterator_traits<Iterator_T>::value_type;
33
-
34
- Data_Object<T> obj(self);
35
- Iterator_T it = std::invoke(this->begin_, *obj);
36
- Iterator_T end = std::invoke(this->end_, *obj);
37
-
38
- for (; it != end; ++it)
39
- {
40
- protect(rb_yield, detail::To_Ruby<Value_T>().convert(*it));
41
- }
42
-
43
- return self;
44
- }
45
- }
46
-
47
- #endif // Rice_Iterator__ipp_
@@ -1,124 +0,0 @@
1
- #ifndef Rice__detail__function_traits__hpp_
2
- #define Rice__detail__function_traits__hpp_
3
-
4
- #include <tuple>
5
-
6
- namespace Rice::detail
7
- {
8
- // -------------- Function Traits --------------
9
- // Base class
10
- template<typename Function_T>
11
- struct function_traits;
12
-
13
- // Base definition that support functors and lambdas
14
- template<class Function_T>
15
- struct function_traits
16
- {
17
- private:
18
- using functor_t = function_traits<decltype(&Function_T::operator())>;
19
-
20
- public:
21
- using arg_types = typename functor_t::arg_types;
22
-
23
- static constexpr std::size_t arity = functor_t::arity - 1;
24
-
25
- template<std::size_t N>
26
- using nth_arg = typename std::tuple_element<N, typename functor_t::arg_types>::type;
27
-
28
- using return_type = typename functor_t::return_type;
29
- using class_type = std::nullptr_t;
30
- };
31
-
32
- // Specialization for functions, member functions and static member functions
33
- template<typename Return_T, typename Class_T, typename...Arg_Ts>
34
- struct function_traits<Return_T(Class_T, Arg_Ts...)>
35
- {
36
- using arg_types = std::tuple<Arg_Ts...>;
37
-
38
- static constexpr std::size_t arity = sizeof...(Arg_Ts);
39
-
40
- template<std::size_t N>
41
- using nth_arg = typename std::tuple_element<N, arg_types>::type;
42
-
43
- using return_type = Return_T;
44
- using class_type = Class_T;
45
- };
46
-
47
- // Free functions and static member functions passed by pointer or reference
48
- template<typename Return_T, typename ...Arg_Ts>
49
- struct function_traits<Return_T(*)(Arg_Ts...)> : public function_traits<Return_T(std::nullptr_t, Arg_Ts...)>
50
- {
51
- };
52
-
53
- template<typename Return_T, typename ...Arg_Ts>
54
- struct function_traits<Return_T(&)(Arg_Ts...)> : public function_traits<Return_T(std::nullptr_t, Arg_Ts...)>
55
- {
56
- };
57
-
58
- // Member Functions
59
- template<typename Return_T, typename Class_T, typename...Arg_Ts>
60
- struct function_traits<Return_T(Class_T::*)(Arg_Ts...)> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
61
- {
62
- };
63
-
64
- template<typename Return_T, typename Class_T, typename...Arg_Ts>
65
- struct function_traits<Return_T(Class_T::*)(Arg_Ts...) const> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
66
- {
67
- };
68
-
69
- template<typename Return_T, typename Class_T, typename...Arg_Ts>
70
- struct function_traits<Return_T(Class_T::*)(Arg_Ts...) noexcept> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
71
- {
72
- };
73
-
74
- template<typename Return_T, typename Class_T, typename...Arg_Ts>
75
- struct function_traits<Return_T(Class_T::*)(Arg_Ts...) const noexcept> : public function_traits<Return_T(Class_T*, Arg_Ts...)>
76
- {
77
- };
78
-
79
- // Functors and lambdas
80
- template<class Function_T>
81
- struct function_traits<Function_T&> : public function_traits<Function_T>
82
- {
83
- };
84
-
85
- template<class Function_T>
86
- struct function_traits<Function_T&&> : public function_traits<Function_T>
87
- {
88
- };
89
-
90
- // -------------- Method Traits --------------
91
- // Declare struct
92
- template<typename Function_T, bool IsMethod, typename = void>
93
- struct method_traits;
94
-
95
- // Functions that do not have a self parameter
96
- template<typename Function_T, bool IsMethod>
97
- struct method_traits<Function_T, IsMethod, std::enable_if_t<!IsMethod>>
98
- {
99
- using Self_T = std::nullptr_t;
100
- using Arg_Ts = typename function_traits<Function_T>::arg_types;
101
- static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
102
- };
103
-
104
- // Functions that do have a self parameter (thus we call them methods)
105
- template<typename Function_T, bool IsMethod>
106
- struct method_traits<Function_T, IsMethod, std::enable_if_t<IsMethod && std::is_same_v<typename function_traits<Function_T>::class_type, std::nullptr_t>>>
107
- {
108
- using Self_T = typename function_traits<Function_T>::template nth_arg<0>;
109
- using Arg_Ts = typename tuple_shift<typename function_traits<Function_T>::arg_types>::type;
110
- static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
111
- };
112
-
113
- // Member functions that have an implied self parameter of an object instance
114
- template<typename Function_T, bool IsMethod>
115
- struct method_traits<Function_T, IsMethod, std::enable_if_t<IsMethod && !std::is_same_v<typename function_traits<Function_T>::class_type, std::nullptr_t>>>
116
- {
117
- using Self_T = typename function_traits<Function_T>::class_type;
118
- using Arg_Ts = typename function_traits<Function_T>::arg_types;
119
- static constexpr std::size_t arity = std::tuple_size_v<Arg_Ts>;
120
- };
121
-
122
- }
123
-
124
- #endif // Rice__detail__function_traits__hpp_
@@ -1,29 +0,0 @@
1
- #ifndef Rice__detail__method_data__hpp
2
- #define Rice__detail__method_data__hpp
3
-
4
- #include <unordered_map>
5
- #include <any>
6
-
7
- #include "ruby.hpp"
8
-
9
- namespace Rice::detail
10
- {
11
- class MethodData
12
- {
13
- public:
14
- // Defines a new Ruby method and stores the Rice metadata about it
15
- template<typename Function_T>
16
- static void define_method(VALUE klass, ID id, Function_T func, int arity, std::any data);
17
-
18
- // Returns the Rice data for the currently active Ruby method
19
- template <typename Return_T>
20
- static Return_T data();
21
-
22
- private:
23
- static size_t key(VALUE klass, ID id);
24
- inline static std::unordered_map<size_t, std::any> methodWrappers_ = {};
25
- };
26
- }
27
- #include "method_data.ipp"
28
-
29
- #endif // Rice__detail__method_data__hpp