rice 4.7.1 → 4.9.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 (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/CMakeLists.txt +14 -22
  4. data/CMakePresets.json +203 -75
  5. data/FindRuby.cmake +358 -123
  6. data/bin/rice-doc.rb +58 -141
  7. data/include/rice/api.hpp +261 -0
  8. data/include/rice/rice.hpp +2459 -1693
  9. data/include/rice/stl.hpp +450 -546
  10. data/lib/rice/doc/config.rb +70 -0
  11. data/lib/rice/doc/cpp_reference.rb +1 -4
  12. data/lib/rice/doc/mkdocs.rb +58 -20
  13. data/lib/rice/doc/rice.rb +21 -0
  14. data/lib/rice/doc.rb +1 -0
  15. data/lib/rice/make_rice_headers.rb +7 -0
  16. data/lib/rice/native_registry.rb +5 -10
  17. data/lib/rice/rbs.rb +6 -6
  18. data/lib/rice/version.rb +1 -1
  19. data/lib/rubygems_plugin.rb +12 -9
  20. data/rice/Arg.hpp +12 -6
  21. data/rice/Arg.ipp +14 -7
  22. data/rice/Buffer.ipp +44 -40
  23. data/rice/Callback.hpp +1 -1
  24. data/rice/Callback.ipp +2 -7
  25. data/rice/Constructor.hpp +1 -1
  26. data/rice/Constructor.ipp +11 -11
  27. data/rice/Data_Object.ipp +15 -15
  28. data/rice/Data_Type.hpp +9 -10
  29. data/rice/Data_Type.ipp +33 -31
  30. data/rice/Director.hpp +1 -0
  31. data/rice/Enum.ipp +58 -39
  32. data/rice/Exception.hpp +4 -4
  33. data/rice/Exception.ipp +7 -7
  34. data/rice/NoGVL.hpp +13 -0
  35. data/rice/Reference.hpp +56 -0
  36. data/rice/Reference.ipp +96 -0
  37. data/rice/Return.hpp +4 -1
  38. data/rice/Return.ipp +0 -6
  39. data/rice/cpp_api/Array.hpp +41 -4
  40. data/rice/cpp_api/Array.ipp +105 -9
  41. data/rice/cpp_api/Class.hpp +7 -2
  42. data/rice/cpp_api/Class.ipp +9 -4
  43. data/rice/cpp_api/Hash.ipp +7 -4
  44. data/rice/cpp_api/Module.hpp +4 -4
  45. data/rice/cpp_api/Module.ipp +12 -10
  46. data/rice/cpp_api/Object.hpp +10 -4
  47. data/rice/cpp_api/Object.ipp +20 -12
  48. data/rice/cpp_api/String.hpp +2 -2
  49. data/rice/cpp_api/String.ipp +11 -8
  50. data/rice/cpp_api/Symbol.ipp +7 -7
  51. data/rice/cpp_api/shared_methods.hpp +5 -9
  52. data/rice/detail/Forwards.hpp +18 -0
  53. data/rice/detail/Forwards.ipp +60 -0
  54. data/rice/detail/InstanceRegistry.hpp +0 -2
  55. data/rice/detail/Native.hpp +31 -21
  56. data/rice/detail/Native.ipp +282 -130
  57. data/rice/detail/NativeAttributeGet.hpp +5 -7
  58. data/rice/detail/NativeAttributeGet.ipp +26 -26
  59. data/rice/detail/NativeAttributeSet.hpp +2 -4
  60. data/rice/detail/NativeAttributeSet.ipp +20 -16
  61. data/rice/detail/NativeCallback.hpp +77 -0
  62. data/rice/detail/NativeCallback.ipp +280 -0
  63. data/rice/detail/NativeFunction.hpp +11 -21
  64. data/rice/detail/NativeFunction.ipp +58 -119
  65. data/rice/detail/NativeInvoker.hpp +4 -4
  66. data/rice/detail/NativeInvoker.ipp +7 -7
  67. data/rice/detail/NativeIterator.hpp +2 -4
  68. data/rice/detail/NativeIterator.ipp +18 -14
  69. data/rice/detail/NativeMethod.hpp +10 -20
  70. data/rice/detail/NativeMethod.ipp +54 -114
  71. data/rice/detail/NativeProc.hpp +5 -7
  72. data/rice/detail/NativeProc.ipp +39 -28
  73. data/rice/detail/NativeRegistry.hpp +1 -1
  74. data/rice/detail/NativeRegistry.ipp +29 -0
  75. data/rice/detail/Parameter.hpp +15 -8
  76. data/rice/detail/Parameter.ipp +102 -43
  77. data/rice/detail/Proc.ipp +14 -28
  78. data/rice/detail/RubyType.ipp +2 -53
  79. data/rice/detail/Type.hpp +23 -7
  80. data/rice/detail/Type.ipp +77 -93
  81. data/rice/detail/TypeRegistry.ipp +5 -4
  82. data/rice/detail/Wrapper.hpp +13 -12
  83. data/rice/detail/Wrapper.ipp +97 -44
  84. data/rice/detail/from_ruby.hpp +8 -6
  85. data/rice/detail/from_ruby.ipp +306 -173
  86. data/rice/detail/ruby.hpp +23 -0
  87. data/rice/libc/file.hpp +4 -4
  88. data/rice/rice.hpp +9 -8
  89. data/rice/rice_api/Native.ipp +5 -1
  90. data/rice/rice_api/NativeRegistry.ipp +14 -1
  91. data/rice/rice_api/Parameter.ipp +1 -1
  92. data/rice/ruby_mark.hpp +2 -1
  93. data/rice/stl/complex.ipp +12 -8
  94. data/rice/stl/map.ipp +27 -22
  95. data/rice/stl/monostate.ipp +16 -12
  96. data/rice/stl/multimap.hpp +0 -2
  97. data/rice/stl/multimap.ipp +27 -22
  98. data/rice/stl/optional.ipp +27 -11
  99. data/rice/stl/pair.ipp +5 -5
  100. data/rice/stl/reference_wrapper.ipp +5 -4
  101. data/rice/stl/set.ipp +16 -16
  102. data/rice/stl/shared_ptr.hpp +9 -9
  103. data/rice/stl/shared_ptr.ipp +52 -185
  104. data/rice/stl/string.ipp +18 -18
  105. data/rice/stl/string_view.ipp +1 -1
  106. data/rice/stl/tuple.ipp +15 -36
  107. data/rice/stl/unique_ptr.hpp +9 -3
  108. data/rice/stl/unique_ptr.ipp +86 -120
  109. data/rice/stl/unordered_map.ipp +20 -15
  110. data/rice/stl/variant.ipp +37 -21
  111. data/rice/stl/vector.ipp +41 -36
  112. data/rice/traits/function_traits.hpp +19 -19
  113. data/rice/traits/method_traits.hpp +4 -4
  114. data/rice/traits/rice_traits.hpp +162 -39
  115. data/rice.gemspec +1 -3
  116. data/test/test_Array.cpp +261 -3
  117. data/test/test_Attribute.cpp +6 -3
  118. data/test/test_Buffer.cpp +6 -42
  119. data/test/test_Callback.cpp +77 -23
  120. data/test/test_Data_Object.cpp +1 -1
  121. data/test/test_Data_Type.cpp +21 -22
  122. data/test/test_Director.cpp +2 -4
  123. data/test/test_Enum.cpp +34 -5
  124. data/test/test_File.cpp +9 -5
  125. data/test/test_From_Ruby.cpp +4 -3
  126. data/test/test_GVL.cpp +3 -3
  127. data/test/test_Hash.cpp +1 -1
  128. data/test/test_Inheritance.cpp +14 -14
  129. data/test/test_Iterator.cpp +54 -22
  130. data/test/test_Keep_Alive.cpp +1 -1
  131. data/test/test_Keep_Alive_No_Wrapper.cpp +7 -3
  132. data/test/test_Module.cpp +5 -5
  133. data/test/test_Overloads.cpp +345 -48
  134. data/test/test_Proc.cpp +54 -0
  135. data/test/test_Reference.cpp +181 -0
  136. data/test/test_Self.cpp +2 -2
  137. data/test/test_Stl_Set.cpp +6 -6
  138. data/test/test_Stl_SharedPtr.cpp +172 -33
  139. data/test/test_Stl_String_View.cpp +4 -2
  140. data/test/test_Stl_Tuple.cpp +1 -1
  141. data/test/test_Stl_UniquePtr.cpp +48 -3
  142. data/test/test_Stl_Variant.cpp +6 -14
  143. data/test/test_Stl_Vector.cpp +61 -30
  144. data/test/test_String.cpp +4 -2
  145. data/test/test_Struct.cpp +1 -1
  146. data/test/test_Symbol.cpp +1 -1
  147. data/test/test_To_Ruby.cpp +1 -0
  148. data/test/test_Type.cpp +36 -35
  149. data/test/test_global_functions.cpp +1 -1
  150. data/test/unittest.cpp +1 -1
  151. data/test/unittest.hpp +5 -5
  152. metadata +12 -10
  153. data/rice/Function.hpp +0 -17
  154. data/rice/Function.ipp +0 -13
  155. data/rice/detail/MethodInfo.hpp +0 -48
  156. data/rice/detail/MethodInfo.ipp +0 -99
  157. data/rice/detail/NativeCallbackFFI.hpp +0 -55
  158. data/rice/detail/NativeCallbackFFI.ipp +0 -152
  159. data/rice/detail/NativeCallbackSimple.hpp +0 -30
  160. data/rice/detail/NativeCallbackSimple.ipp +0 -29
data/rice/stl/string.ipp CHANGED
@@ -68,7 +68,7 @@ namespace Rice::detail
68
68
  public:
69
69
  To_Ruby() = default;
70
70
 
71
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
71
+ explicit To_Ruby(Arg* arg) : arg_(arg)
72
72
  {
73
73
  }
74
74
 
@@ -78,7 +78,7 @@ namespace Rice::detail
78
78
  }
79
79
 
80
80
  private:
81
- Return* returnInfo_ = nullptr;
81
+ Arg* arg_ = nullptr;
82
82
  };
83
83
 
84
84
  template<>
@@ -87,7 +87,7 @@ namespace Rice::detail
87
87
  public:
88
88
  To_Ruby() = default;
89
89
 
90
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
90
+ explicit To_Ruby(Arg* arg) : arg_(arg)
91
91
  {
92
92
  }
93
93
 
@@ -97,7 +97,7 @@ namespace Rice::detail
97
97
  }
98
98
 
99
99
  private:
100
- Return* returnInfo_ = nullptr;
100
+ Arg* arg_ = nullptr;
101
101
  };
102
102
 
103
103
  template<int N>
@@ -106,7 +106,7 @@ namespace Rice::detail
106
106
  public:
107
107
  To_Ruby() = default;
108
108
 
109
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
109
+ explicit To_Ruby(Arg* arg) : arg_(arg)
110
110
  {
111
111
  }
112
112
 
@@ -117,7 +117,7 @@ namespace Rice::detail
117
117
  return dataObject.value();
118
118
  }
119
119
  private:
120
- Return* returnInfo_ = nullptr;
120
+ Arg* arg_ = nullptr;
121
121
  };
122
122
 
123
123
  template<>
@@ -126,14 +126,14 @@ namespace Rice::detail
126
126
  public:
127
127
  To_Ruby() = default;
128
128
 
129
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
129
+ explicit To_Ruby(Arg* arg) : arg_(arg)
130
130
  {
131
131
  }
132
132
 
133
133
  VALUE convert(const std::string* value)
134
134
  {
135
- bool isOwner = this->returnInfo_ && this->returnInfo_->isOwner();
136
- bool isBuffer = this->returnInfo_ && this->returnInfo_->isBuffer();
135
+ bool isOwner = this->arg_ && this->arg_->isOwner();
136
+ bool isBuffer = dynamic_cast<ReturnBuffer*>(this->arg_) ? true : false;
137
137
 
138
138
  if (isBuffer)
139
139
  {
@@ -147,7 +147,7 @@ namespace Rice::detail
147
147
  }
148
148
 
149
149
  private:
150
- Return* returnInfo_ = nullptr;
150
+ Arg* arg_ = nullptr;
151
151
  };
152
152
 
153
153
  template<>
@@ -156,7 +156,7 @@ namespace Rice::detail
156
156
  public:
157
157
  To_Ruby() = default;
158
158
 
159
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
159
+ explicit To_Ruby(Arg* arg) : arg_(arg)
160
160
  {
161
161
  }
162
162
 
@@ -166,7 +166,7 @@ namespace Rice::detail
166
166
  }
167
167
 
168
168
  private:
169
- Return* returnInfo_ = nullptr;
169
+ Arg* arg_ = nullptr;
170
170
  };
171
171
 
172
172
  /*template<>
@@ -175,7 +175,7 @@ namespace Rice::detail
175
175
  public:
176
176
  To_Ruby() = default;
177
177
 
178
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
178
+ explicit To_Ruby(Arg* arg) : arg_(arg)
179
179
  {
180
180
  }
181
181
 
@@ -187,7 +187,7 @@ namespace Rice::detail
187
187
  }
188
188
 
189
189
  private:
190
- Return* returnInfo_ = nullptr;
190
+ Arg* arg_ = nullptr;
191
191
  };*/
192
192
 
193
193
  template<>
@@ -200,7 +200,7 @@ namespace Rice::detail
200
200
  {
201
201
  }
202
202
 
203
- Convertible is_convertible(VALUE value)
203
+ double is_convertible(VALUE value)
204
204
  {
205
205
  switch (rb_type(value))
206
206
  {
@@ -232,7 +232,7 @@ namespace Rice::detail
232
232
  {
233
233
  }
234
234
 
235
- Convertible is_convertible(VALUE value)
235
+ double is_convertible(VALUE value)
236
236
  {
237
237
  switch (rb_type(value))
238
238
  {
@@ -266,7 +266,7 @@ namespace Rice::detail
266
266
  {
267
267
  }
268
268
 
269
- Convertible is_convertible(VALUE value)
269
+ double is_convertible(VALUE value)
270
270
  {
271
271
  switch (rb_type(value))
272
272
  {
@@ -300,7 +300,7 @@ namespace Rice::detail
300
300
  {
301
301
  }
302
302
 
303
- Convertible is_convertible(VALUE value)
303
+ double is_convertible(VALUE value)
304
304
  {
305
305
  switch (rb_type(value))
306
306
  {
@@ -64,7 +64,7 @@ namespace Rice::detail
64
64
  {
65
65
  }
66
66
 
67
- Convertible is_convertible(VALUE value)
67
+ double is_convertible(VALUE value)
68
68
  {
69
69
  switch (rb_type(value))
70
70
  {
data/rice/stl/tuple.ipp CHANGED
@@ -8,7 +8,7 @@ namespace Rice::detail
8
8
  using Tuple_T = std::tuple<Types...>;
9
9
 
10
10
  template<std::size_t... I>
11
- constexpr static bool verifyTypes(std::index_sequence<I...>& indices)
11
+ constexpr static bool verifyTypes(std::index_sequence<I...>&)
12
12
  {
13
13
  return (Type<std::tuple_element_t<I, Tuple_T>>::verify() && ...);
14
14
  }
@@ -32,7 +32,7 @@ namespace Rice::detail
32
32
  public:
33
33
  To_Ruby() = default;
34
34
 
35
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
35
+ explicit To_Ruby(Arg* arg) : arg_(arg)
36
36
  {
37
37
  }
38
38
 
@@ -49,7 +49,7 @@ namespace Rice::detail
49
49
  }
50
50
 
51
51
  private:
52
- Return* returnInfo_ = nullptr;
52
+ Arg* arg_ = nullptr;
53
53
  };
54
54
 
55
55
  template<typename...Types>
@@ -58,7 +58,7 @@ namespace Rice::detail
58
58
  public:
59
59
  To_Ruby() = default;
60
60
 
61
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
61
+ explicit To_Ruby(Arg* arg) : arg_(arg)
62
62
  {
63
63
  }
64
64
 
@@ -66,7 +66,7 @@ namespace Rice::detail
66
66
  {
67
67
  Array result;
68
68
 
69
- bool isOwner = (this->returnInfo_ && this->returnInfo_->isOwner());
69
+ bool isOwner = (this->arg_ && this->arg_->isOwner());
70
70
 
71
71
  for_each_tuple(data, [&](auto& element)
72
72
  {
@@ -77,7 +77,7 @@ namespace Rice::detail
77
77
  }
78
78
 
79
79
  private:
80
- Return* returnInfo_ = nullptr;
80
+ Arg* arg_ = nullptr;
81
81
  };
82
82
 
83
83
  template<typename...Types>
@@ -86,35 +86,28 @@ namespace Rice::detail
86
86
  public:
87
87
  using Tuple_T = std::tuple<Types...>;
88
88
 
89
- template<std::size_t... I>
90
- constexpr static bool verifyTypes(Array& array, std::index_sequence<I...>& indices)
91
- {
92
- return (Type<std::tuple_element_t<I, Tuple_T>>::verify() && ...);
93
- }
94
-
95
89
  From_Ruby() = default;
96
90
 
97
- explicit From_Ruby(Arg* arg)
91
+ explicit From_Ruby(Arg* arg) : arg_(arg)
98
92
  {
99
93
  }
100
94
 
101
- Convertible is_convertible(VALUE value)
95
+ double is_convertible(VALUE value)
102
96
  {
103
- Convertible result = Convertible::None;
104
-
105
97
  // The ruby value must be an array of the correct size
106
98
  if (rb_type(value) != RUBY_T_ARRAY || Array(value).size() != std::tuple_size_v<Tuple_T>)
107
99
  {
108
- return result;
100
+ return Convertible::None;
109
101
  }
110
-
111
- // Now check that each tuple type is convertible
102
+
103
+ // Now check that each tuple type is convertible - use minimum score
104
+ double result = Convertible::Exact;
112
105
  Array array(value);
113
106
  int i = 0;
114
107
  for_each_tuple(this->fromRubys_,
115
108
  [&](auto& fromRuby)
116
109
  {
117
- result = result | fromRuby.is_convertible(array[i].value());
110
+ result = (std::min)(result, fromRuby.is_convertible(array[i].value()));
118
111
  i++;
119
112
  });
120
113
 
@@ -122,7 +115,7 @@ namespace Rice::detail
122
115
  }
123
116
 
124
117
  template <std::size_t... I>
125
- std::tuple<Types...> convertInternal(Array array, std::index_sequence<I...>& indices)
118
+ std::tuple<Types...> convertInternal(Array array, std::index_sequence<I...>&)
126
119
  {
127
120
  return std::forward_as_tuple(std::get<I>(this->fromRubys_).convert(array[I].value())...);
128
121
  }
@@ -135,23 +128,9 @@ namespace Rice::detail
135
128
  }
136
129
 
137
130
  private:
131
+ Arg* arg_ = nullptr;
138
132
  // Possible converters we could use for this variant
139
133
  using From_Ruby_Ts = std::tuple<From_Ruby<Types>...>;
140
134
  From_Ruby_Ts fromRubys_;
141
135
  };
142
-
143
- /* template<typename...Types>
144
- class From_Ruby<std::tuple<Types...>&> : public From_Ruby<std::tuple<Types...>>
145
- {
146
- public:
147
- std::tuple<Types...>& convert(VALUE value)
148
- {
149
- int index = this->figureIndex(value);
150
- this->converted_ = this->convertInternal(value, index);
151
- return this->converted_;
152
- }
153
-
154
- private:
155
- std::tuple<Types...> converted_;
156
- };*/
157
136
  }
@@ -1,19 +1,25 @@
1
1
  #ifndef Rice__stl__unique_ptr__hpp_
2
2
  #define Rice__stl__unique_ptr__hpp_
3
3
 
4
+ namespace Rice
5
+ {
6
+ template<typename T>
7
+ Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName = "");
8
+ }
9
+
4
10
  namespace Rice::detail
5
11
  {
6
12
  template<typename T>
7
13
  class Wrapper<std::unique_ptr<T>> : public WrapperBase
8
14
  {
9
15
  public:
10
- Wrapper(std::unique_ptr<T>&& data);
16
+ Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data);
11
17
  ~Wrapper();
12
- void* get() override;
13
- std::unique_ptr<T>& data();
18
+ void* get(rb_data_type_t* requestedType) override;
14
19
 
15
20
  private:
16
21
  std::unique_ptr<T> data_;
22
+ rb_data_type_t* inner_rb_data_type_;
17
23
  };
18
24
  }
19
25
 
@@ -1,141 +1,131 @@
1
1
  #include <memory>
2
2
 
3
- namespace Rice::detail
3
+ namespace Rice
4
4
  {
5
5
  template<typename T>
6
- inline Wrapper<std::unique_ptr<T>>::Wrapper(std::unique_ptr<T>&& data)
7
- : data_(std::move(data))
8
- {
9
- }
10
-
11
- template<typename T>
12
- inline Wrapper<std::unique_ptr<T>>::~Wrapper()
13
- {
14
- Registries::instance.instances.remove(this->get());
15
- }
16
-
17
- template<typename T>
18
- inline void* Wrapper<std::unique_ptr<T>>::get()
19
- {
20
- return (void*)this->data_.get();
21
- }
22
-
23
- template<typename T>
24
- inline std::unique_ptr<T>& Wrapper<std::unique_ptr<T>>::data()
25
- {
26
- return data_;
27
- }
28
-
29
- template <typename T>
30
- class To_Ruby<std::unique_ptr<T>>
6
+ Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName)
31
7
  {
32
- public:
33
- To_Ruby() = default;
8
+ using UniquePtr_T = std::unique_ptr<T>;
9
+ using Data_Type_T = Data_Type<UniquePtr_T>;
34
10
 
35
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
11
+ if (klassName.empty())
36
12
  {
13
+ detail::TypeMapper<UniquePtr_T> typeMapper;
14
+ klassName = typeMapper.rubyName();
37
15
  }
38
16
 
39
- VALUE convert(std::unique_ptr<T>& data)
17
+ Module rb_mStd = define_module("Std");
18
+ if (Data_Type_T::check_defined(klassName, rb_mStd))
40
19
  {
41
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
42
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
20
+ return Data_Type_T();
43
21
  }
44
22
 
45
- VALUE convert(std::unique_ptr<T>&& data)
23
+ Identifier id(klassName);
24
+ Data_Type_T result = define_class_under<detail::intrinsic_type<UniquePtr_T>>(rb_mStd, id).
25
+ define_method("get", &UniquePtr_T::get).
26
+ define_method("release", &UniquePtr_T::release).
27
+ define_method("reset", &UniquePtr_T::reset).
28
+ define_method("swap", &UniquePtr_T::swap).
29
+ define_method("empty?", [](UniquePtr_T& self)->bool
30
+ {
31
+ return !self;
32
+ });
33
+
34
+ // Setup delegation to forward T's methods via get (only for non-fundamental, non-void types)
35
+ if constexpr (!std::is_void_v<T> && !std::is_fundamental_v<T>)
46
36
  {
47
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
48
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
37
+ detail::define_forwarding(result.klass(), Data_Type<T>::klass());
49
38
  }
50
39
 
51
- private:
52
- Return* returnInfo_ = nullptr;
53
- };
40
+ return result;
41
+ }
42
+ }
54
43
 
55
- template <typename T>
56
- class To_Ruby<std::unique_ptr<T>&>
44
+ // --------- Wrapper ---------
45
+ namespace Rice::detail
46
+ {
47
+ template<typename T>
48
+ Wrapper<std::unique_ptr<T>>::Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data)
49
+ : WrapperBase(rb_data_type), data_(std::move(data))
57
50
  {
58
- public:
59
- To_Ruby() = default;
51
+ using Intrinsic_T = intrinsic_type<T>;
60
52
 
61
- explicit To_Ruby(Return* returnInfo) : returnInfo_(returnInfo)
53
+ if constexpr (std::is_fundamental_v<Intrinsic_T>)
62
54
  {
55
+ inner_rb_data_type_ = Data_Type<Pointer<Intrinsic_T>>::ruby_data_type();
63
56
  }
64
-
65
- VALUE convert(std::unique_ptr<T>& data)
57
+ else
66
58
  {
67
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
68
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
59
+ inner_rb_data_type_ = Data_Type<Intrinsic_T>::ruby_data_type();
69
60
  }
61
+ }
70
62
 
71
- private:
72
- Return* returnInfo_ = nullptr;
73
- };
63
+ template<typename T>
64
+ Wrapper<std::unique_ptr<T>>::~Wrapper()
65
+ {
66
+ Registries::instance.instances.remove(this->get(this->rb_data_type_));
67
+ }
74
68
 
75
- template <typename T>
76
- class From_Ruby<std::unique_ptr<T>>
69
+ template<typename T>
70
+ void* Wrapper<std::unique_ptr<T>>::get(rb_data_type_t* requestedType)
77
71
  {
78
- public:
79
- Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
72
+ if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
80
73
  {
81
- WrapperBase* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
82
- return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
74
+ return &this->data_;
83
75
  }
84
-
85
- From_Ruby() = default;
86
-
87
- explicit From_Ruby(Arg* arg)
76
+ else if (rb_typeddata_inherited_p(this->inner_rb_data_type_, requestedType))
88
77
  {
78
+ return this->data_.get();
89
79
  }
90
-
91
- Convertible is_convertible(VALUE value)
80
+ else
92
81
  {
93
- if (!is_same_smart_ptr(value))
94
- return Convertible::None;
82
+ throw Exception(rb_eTypeError, "wrong argument type (expected %s)",
83
+ requestedType->wrap_struct_name);
84
+ }
85
+ }
95
86
 
96
- switch (rb_type(value))
87
+ }
88
+
89
+ // --------- Type ---------
90
+ namespace Rice::detail
91
+ {
92
+ template<typename T>
93
+ struct Type<std::unique_ptr<T>>
94
+ {
95
+ static bool verify()
96
+ {
97
+ bool result = true;
98
+ if constexpr (std::is_fundamental_v<T>)
97
99
  {
98
- case RUBY_T_DATA:
99
- return Convertible::Exact;
100
- break;
101
- default:
102
- return Convertible::None;
100
+ result = result && Type<Pointer<T>>::verify();
101
+ }
102
+ else
103
+ {
104
+ result = result && Type<T>::verify();
103
105
  }
104
- }
105
106
 
106
- std::unique_ptr<T> convert(VALUE value)
107
- {
108
- Wrapper<std::unique_ptr<T>>* wrapper = is_same_smart_ptr(value);
109
- if (!wrapper)
107
+ if (result)
110
108
  {
111
- std::string message = "Invalid smart pointer wrapper";
112
- throw std::runtime_error(message.c_str());
109
+ define_unique_ptr<T>();
113
110
  }
114
- return std::move(wrapper->data());
111
+
112
+ return result;
115
113
  }
116
114
  };
117
115
 
116
+ // --------- From_Ruby ---------
118
117
  template <typename T>
119
- class From_Ruby<std::unique_ptr<T>&>
118
+ class From_Ruby<std::unique_ptr<T>>
120
119
  {
121
120
  public:
122
- Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
123
- {
124
- WrapperBase* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
125
- return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
126
- }
127
-
128
121
  From_Ruby() = default;
129
122
 
130
- explicit From_Ruby(Arg* arg)
123
+ explicit From_Ruby(Arg* arg) : arg_(arg)
131
124
  {
132
125
  }
133
126
 
134
- Convertible is_convertible(VALUE value)
127
+ double is_convertible(VALUE value)
135
128
  {
136
- if (!is_same_smart_ptr(value))
137
- return Convertible::None;
138
-
139
129
  switch (rb_type(value))
140
130
  {
141
131
  case RUBY_T_DATA:
@@ -146,38 +136,14 @@ namespace Rice::detail
146
136
  }
147
137
  }
148
138
 
149
- std::unique_ptr<T>& convert(VALUE value)
150
- {
151
- Wrapper<std::unique_ptr<T>>* wrapper = is_same_smart_ptr(value);
152
- if (!wrapper)
153
- {
154
- std::string message = "Invalid smart pointer wrapper";
155
- throw std::runtime_error(message.c_str());
156
- }
157
- return wrapper->data();
158
- }
159
- };
160
-
161
- template<typename T>
162
- struct Type<std::unique_ptr<T>>
163
- {
164
- static bool verify()
139
+ std::unique_ptr<T> convert(VALUE value)
165
140
  {
166
- if constexpr (std::is_fundamental_v<T>)
167
- {
168
- return Type<Pointer<T>>::verify();
169
- return Type<Buffer<T>>::verify();
170
- }
171
- else
172
- {
173
- return Type<T>::verify();
174
- }
141
+ std::unique_ptr<T>* result = detail::unwrap<std::unique_ptr<T>>(value, Data_Type<std::unique_ptr<T>>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
142
+ // The reason we need this overriden From_Ruby is to do this std::move.
143
+ return std::move(*result);
175
144
  }
176
145
 
177
- static VALUE rubyKlass()
178
- {
179
- TypeMapper<T> typeMapper;
180
- return typeMapper.rubyKlass();
181
- }
146
+ private:
147
+ Arg* arg_ = nullptr;
182
148
  };
183
149
  }