rice 4.11.4 → 4.12.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/CMakePresets.json +3 -3
  4. data/bin/rice-doc.rb +2 -0
  5. data/include/rice/rice.hpp +162 -113
  6. data/include/rice/stl.hpp +229 -69
  7. data/lib/mkmf-rice.rb +2 -2
  8. data/lib/rice/version.rb +1 -1
  9. data/rice/Constructor.ipp +3 -3
  10. data/rice/Data_Object.ipp +0 -42
  11. data/rice/JumpException.ipp +1 -0
  12. data/rice/Reference.hpp +2 -2
  13. data/rice/Reference.ipp +1 -1
  14. data/rice/cpp_api/Encoding.ipp +0 -48
  15. data/rice/cpp_api/Hash.ipp +19 -0
  16. data/rice/cpp_api/Object.hpp +2 -2
  17. data/rice/cpp_api/Object.ipp +3 -3
  18. data/rice/cpp_api/String.ipp +19 -0
  19. data/rice/detail/Anchor.hpp +1 -1
  20. data/rice/detail/Anchor.ipp +16 -10
  21. data/rice/detail/Parameter.ipp +11 -0
  22. data/rice/detail/Proc.ipp +19 -0
  23. data/rice/detail/Wrapper.ipp +3 -3
  24. data/rice/detail/from_ruby.hpp +1 -0
  25. data/rice/detail/to_ruby.ipp +58 -1
  26. data/rice/stl/function.ipp +142 -2
  27. data/rice/stl/map.ipp +2 -10
  28. data/rice/stl/multimap.ipp +2 -10
  29. data/rice/stl/optional.ipp +18 -0
  30. data/rice/stl/reference_wrapper.ipp +18 -0
  31. data/rice/stl/set.ipp +24 -25
  32. data/rice/stl/unique_ptr.ipp +3 -0
  33. data/rice/stl/unordered_map.ipp +2 -10
  34. data/rice/stl/vector.ipp +18 -15
  35. data/rice/traits/rice_traits.hpp +3 -0
  36. data/test/test_Attribute.cpp +6 -6
  37. data/test/test_Constructor.cpp +140 -1
  38. data/test/test_File.cpp +2 -3
  39. data/test/test_From_Ruby.cpp +3 -3
  40. data/test/test_Hash.cpp +8 -0
  41. data/test/test_Object.cpp +76 -0
  42. data/test/test_Overloads.cpp +74 -1
  43. data/test/test_Proc.cpp +11 -1
  44. data/test/test_Reference.cpp +20 -1
  45. data/test/test_Stl_Exception.cpp +2 -5
  46. data/test/test_Stl_Function.cpp +72 -7
  47. data/test/test_Stl_Map.cpp +10 -1
  48. data/test/test_Stl_Multimap.cpp +11 -2
  49. data/test/test_Stl_Optional.cpp +9 -0
  50. data/test/test_Stl_Reference_Wrapper.cpp +11 -0
  51. data/test/test_Stl_Set.cpp +12 -0
  52. data/test/test_Stl_Unordered_Map.cpp +10 -1
  53. data/test/test_Stl_Vector.cpp +130 -11
  54. data/test/test_String.cpp +7 -0
  55. data/test/test_To_Ruby.cpp +24 -1
  56. metadata +1 -1
data/include/rice/stl.hpp CHANGED
@@ -151,9 +151,9 @@ namespace Rice::stl
151
151
  klass_.define_method("initialize", [](VALUE self, VALUE callable) -> void
152
152
  {
153
153
  // Create std::function that wraps the Ruby callable
154
- Function_T* data = new Function_T([callable](auto... args)
154
+ Function_T* data = new Function_T([callable](auto&&... args)
155
155
  {
156
- Object result = Object(callable).call("call", args...);
156
+ Object result = Object(callable).call("call", std::forward<decltype(args)>(args)...);
157
157
 
158
158
  using Return_T = typename Function_T::result_type;
159
159
  if constexpr (!std::is_void_v<Return_T>)
@@ -211,6 +211,146 @@ namespace Rice
211
211
 
212
212
  namespace Rice::detail
213
213
  {
214
+ template<typename Return_T, typename ...Parameter_Ts>
215
+ inline std::function<Return_T(Parameter_Ts...)> makeRubyFunction(VALUE value)
216
+ {
217
+ Pin proc(value);
218
+
219
+ return [proc = std::move(proc)](Parameter_Ts... args) -> Return_T
220
+ {
221
+ Object result = Object(proc.value()).call("call", std::forward<Parameter_Ts>(args)...);
222
+
223
+ if constexpr (!std::is_void_v<Return_T>)
224
+ {
225
+ return From_Ruby<std::remove_cv_t<Return_T>>().convert(result);
226
+ }
227
+ };
228
+ }
229
+
230
+ template<typename Return_T, typename ...Parameter_Ts>
231
+ class From_Ruby<std::function<Return_T(Parameter_Ts...)>>
232
+ {
233
+ public:
234
+ using Function_T = std::function<Return_T(Parameter_Ts...)>;
235
+
236
+ From_Ruby() = default;
237
+
238
+ explicit From_Ruby(Arg* arg) : arg_(arg)
239
+ {
240
+ }
241
+
242
+ double is_convertible(VALUE value)
243
+ {
244
+ switch (rb_type(value))
245
+ {
246
+ case RUBY_T_DATA:
247
+ return Data_Type<Function_T>::is_descendant(value) ? Convertible::Exact : Convertible::None;
248
+ default:
249
+ return protect(rb_obj_is_proc, value) == Qtrue ? Convertible::ConstMismatch : Convertible::None;
250
+ }
251
+ }
252
+
253
+ Function_T convert(VALUE value)
254
+ {
255
+ if (Data_Type<Function_T>::is_descendant(value))
256
+ {
257
+ return *detail::unwrap<Function_T>(value, Data_Type<Function_T>::ruby_data_type(), false);
258
+ }
259
+ else if (protect(rb_obj_is_proc, value) == Qtrue)
260
+ {
261
+ return makeRubyFunction<Return_T, Parameter_Ts...>(value);
262
+ }
263
+ else
264
+ {
265
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
266
+ detail::protect(rb_obj_classname, value), "std::function");
267
+ }
268
+ }
269
+
270
+ private:
271
+ Arg* arg_ = nullptr;
272
+ };
273
+
274
+ template<typename Return_T, typename ...Parameter_Ts>
275
+ class From_Ruby<std::function<Return_T(Parameter_Ts...)>&>
276
+ {
277
+ public:
278
+ using Function_T = std::function<Return_T(Parameter_Ts...)>;
279
+
280
+ From_Ruby() = default;
281
+
282
+ explicit From_Ruby(Arg* arg) : arg_(arg)
283
+ {
284
+ }
285
+
286
+ double is_convertible(VALUE value)
287
+ {
288
+ return From_Ruby<Function_T>(arg_).is_convertible(value);
289
+ }
290
+
291
+ Function_T& convert(VALUE value)
292
+ {
293
+ if (Data_Type<Function_T>::is_descendant(value))
294
+ {
295
+ return *detail::unwrap<Function_T>(value, Data_Type<Function_T>::ruby_data_type(), false);
296
+ }
297
+ else if (protect(rb_obj_is_proc, value) == Qtrue)
298
+ {
299
+ converted_ = makeRubyFunction<Return_T, Parameter_Ts...>(value);
300
+ return converted_;
301
+ }
302
+ else
303
+ {
304
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
305
+ detail::protect(rb_obj_classname, value), "std::function");
306
+ }
307
+ }
308
+
309
+ private:
310
+ Arg* arg_ = nullptr;
311
+ Function_T converted_;
312
+ };
313
+
314
+ template<typename Return_T, typename ...Parameter_Ts>
315
+ class From_Ruby<std::function<Return_T(Parameter_Ts...)>&&>
316
+ {
317
+ public:
318
+ using Function_T = std::function<Return_T(Parameter_Ts...)>;
319
+
320
+ From_Ruby() = default;
321
+
322
+ explicit From_Ruby(Arg* arg) : arg_(arg)
323
+ {
324
+ }
325
+
326
+ double is_convertible(VALUE value)
327
+ {
328
+ return From_Ruby<Function_T>(arg_).is_convertible(value);
329
+ }
330
+
331
+ Function_T&& convert(VALUE value)
332
+ {
333
+ if (Data_Type<Function_T>::is_descendant(value))
334
+ {
335
+ return std::move(*detail::unwrap<Function_T>(value, Data_Type<Function_T>::ruby_data_type(), false));
336
+ }
337
+ else if (protect(rb_obj_is_proc, value) == Qtrue)
338
+ {
339
+ converted_ = makeRubyFunction<Return_T, Parameter_Ts...>(value);
340
+ return std::move(converted_);
341
+ }
342
+ else
343
+ {
344
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s)",
345
+ detail::protect(rb_obj_classname, value), "std::function");
346
+ }
347
+ }
348
+
349
+ private:
350
+ Arg* arg_ = nullptr;
351
+ Function_T converted_;
352
+ };
353
+
214
354
  template<typename Signature_T>
215
355
  struct Type<std::function<Signature_T>>
216
356
  {
@@ -867,6 +1007,24 @@ namespace Rice::detail
867
1007
  Arg* arg_ = nullptr;
868
1008
  };
869
1009
 
1010
+ template<>
1011
+ class To_Ruby<std::nullopt_t&>
1012
+ {
1013
+ public:
1014
+ To_Ruby() = default;
1015
+
1016
+ explicit To_Ruby(Arg* arg) : arg_(arg)
1017
+ {}
1018
+
1019
+ VALUE convert(const std::nullopt_t&)
1020
+ {
1021
+ return Qnil;
1022
+ }
1023
+
1024
+ private:
1025
+ Arg* arg_ = nullptr;
1026
+ };
1027
+
870
1028
  template<typename T>
871
1029
  class To_Ruby<std::optional<T>>
872
1030
  {
@@ -1463,6 +1621,24 @@ namespace Rice::detail
1463
1621
  Arg* arg_ = nullptr;
1464
1622
  };
1465
1623
 
1624
+ template<typename T>
1625
+ class To_Ruby<std::reference_wrapper<T>&>
1626
+ {
1627
+ public:
1628
+ To_Ruby() = default;
1629
+
1630
+ explicit To_Ruby(Arg* arg) : arg_(arg)
1631
+ {}
1632
+
1633
+ VALUE convert(const std::reference_wrapper<T>& data)
1634
+ {
1635
+ return To_Ruby<T&>().convert(data.get());
1636
+ }
1637
+
1638
+ private:
1639
+ Arg* arg_ = nullptr;
1640
+ };
1641
+
1466
1642
  template<typename T>
1467
1643
  class From_Ruby<std::reference_wrapper<T>>
1468
1644
  {
@@ -1626,16 +1802,8 @@ namespace Rice
1626
1802
  return it != map.end();
1627
1803
  }, Arg("value"));
1628
1804
  rb_define_alias(klass_, "eql?", "==");
1805
+ rb_define_alias(klass_, "has_value", "value?");
1629
1806
  }
1630
- else
1631
- {
1632
- klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
1633
- {
1634
- return false;
1635
- }, Arg("value"));
1636
- }
1637
-
1638
- rb_define_alias(klass_, "has_value", "value?");
1639
1807
  }
1640
1808
 
1641
1809
  void define_modify_methods()
@@ -1969,6 +2137,7 @@ namespace Rice
1969
2137
  }
1970
2138
  }
1971
2139
 
2140
+
1972
2141
  // ========= monostate.hpp =========
1973
2142
 
1974
2143
 
@@ -2230,16 +2399,8 @@ namespace Rice
2230
2399
  return it != multimap.end();
2231
2400
  }, Arg("value"));
2232
2401
  rb_define_alias(klass_, "eql?", "==");
2402
+ rb_define_alias(klass_, "has_value", "value?");
2233
2403
  }
2234
- else
2235
- {
2236
- klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
2237
- {
2238
- return false;
2239
- }, Arg("value"));
2240
- }
2241
-
2242
- rb_define_alias(klass_, "has_value", "value?");
2243
2404
  }
2244
2405
 
2245
2406
  void define_modify_methods()
@@ -2554,6 +2715,7 @@ namespace Rice
2554
2715
  }
2555
2716
  }
2556
2717
 
2718
+
2557
2719
  // ========= set.hpp =========
2558
2720
 
2559
2721
  namespace Rice
@@ -2667,23 +2829,23 @@ namespace Rice
2667
2829
 
2668
2830
  void define_operators()
2669
2831
  {
2670
- klass_
2671
- .define_method("<<", [](T& self, Parameter_T value) -> T&
2672
- {
2673
- self.insert(value);
2674
- return self;
2675
- }, Arg("value").keepAlive())
2676
- .define_method("==", [](const T& self, const T& other) -> bool
2832
+ klass_.define_method("<<", [](T& self, Parameter_T value) -> T&
2833
+ {
2834
+ self.insert(value);
2835
+ return self;
2836
+ }, Arg("value").keepAlive());
2837
+
2838
+ if constexpr (detail::is_comparable_v<Value_T>)
2839
+ {
2840
+ klass_.define_method("==", [](const T& self, const T& other) -> bool
2677
2841
  {
2678
- if constexpr (detail::is_comparable_v<Value_T>)
2679
- {
2680
- return self == other;
2681
- }
2682
- else
2683
- {
2684
- return false;
2685
- }
2686
- }, Arg("other"))
2842
+ return self == other;
2843
+ }, Arg("other"));
2844
+
2845
+ rb_define_alias(klass_, "eql?", "==");
2846
+ }
2847
+
2848
+ klass_
2687
2849
  .define_method("&", [](const T& self, const T& other) -> T
2688
2850
  {
2689
2851
  T result;
@@ -2730,15 +2892,14 @@ namespace Rice
2730
2892
  return std::includes(self.begin(), self.end(),
2731
2893
  other.begin(), other.end());
2732
2894
  }, Arg("other"));
2733
-
2734
- rb_define_alias(klass_, "eql?", "==");
2735
- rb_define_alias(klass_, "intersection", "&");
2736
- rb_define_alias(klass_, "union", "|");
2737
- rb_define_alias(klass_, "difference", "-");
2738
- rb_define_alias(klass_, "proper_subset?", "<");
2739
- rb_define_alias(klass_, "subset?", "<");
2740
- rb_define_alias(klass_, "proper_superset?", ">");
2741
- rb_define_alias(klass_, "superset?", ">");
2895
+
2896
+ rb_define_alias(klass_, "intersection", "&");
2897
+ rb_define_alias(klass_, "union", "|");
2898
+ rb_define_alias(klass_, "difference", "-");
2899
+ rb_define_alias(klass_, "proper_subset?", "<");
2900
+ rb_define_alias(klass_, "subset?", "<");
2901
+ rb_define_alias(klass_, "proper_superset?", ">");
2902
+ rb_define_alias(klass_, "superset?", ">");
2742
2903
  }
2743
2904
 
2744
2905
  void define_enumerable()
@@ -3865,6 +4026,9 @@ namespace Rice
3865
4026
  template<typename T>
3866
4027
  Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName)
3867
4028
  {
4029
+ static_assert(detail::is_complete_v<T>,
4030
+ "Rice does not support binding std::unique_ptr<T> when T is incomplete.");
4031
+
3868
4032
  using UniquePtr_T = std::unique_ptr<T>;
3869
4033
  using Data_Type_T = Data_Type<UniquePtr_T>;
3870
4034
 
@@ -4151,16 +4315,8 @@ namespace Rice
4151
4315
  return it != unordered_map.end();
4152
4316
  }, Arg("value"));
4153
4317
  rb_define_alias(klass_, "eql?", "==");
4318
+ rb_define_alias(klass_, "has_value", "value?");
4154
4319
  }
4155
- else
4156
- {
4157
- klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
4158
- {
4159
- return false;
4160
- }, Arg("value"));
4161
- }
4162
-
4163
- rb_define_alias(klass_, "has_value", "value?");
4164
4320
  }
4165
4321
 
4166
4322
  void define_modify_methods()
@@ -4494,6 +4650,7 @@ namespace Rice
4494
4650
  }
4495
4651
  }
4496
4652
 
4653
+
4497
4654
  // ========= vector.hpp =========
4498
4655
 
4499
4656
  namespace Rice
@@ -4802,21 +4959,6 @@ namespace Rice
4802
4959
  }, Arg("value"));
4803
4960
  rb_define_alias(klass_, "eql?", "==");
4804
4961
  }
4805
- else
4806
- {
4807
- klass_.define_method("delete", [](T&, Parameter_T) -> std::optional<Value_T>
4808
- {
4809
- return std::nullopt;
4810
- }, Arg("value"))
4811
- .define_method("include?", [](const T&, Parameter_T)
4812
- {
4813
- return false;
4814
- }, Arg("value"))
4815
- .define_method("index", [](const T&, Parameter_T) -> std::optional<Difference_T>
4816
- {
4817
- return std::nullopt;
4818
- }, Arg("value"));
4819
- }
4820
4962
  }
4821
4963
 
4822
4964
  void define_modify_methods()
@@ -5227,6 +5369,24 @@ namespace Rice
5227
5369
  private:
5228
5370
  Arg* arg_ = nullptr;
5229
5371
  };
5372
+
5373
+ template<>
5374
+ class To_Ruby<std::vector<bool>::reference&>
5375
+ {
5376
+ public:
5377
+ To_Ruby() = default;
5378
+
5379
+ explicit To_Ruby(Arg* arg) : arg_(arg)
5380
+ {}
5381
+
5382
+ VALUE convert(const std::vector<bool>::reference& value)
5383
+ {
5384
+ return value ? Qtrue : Qfalse;
5385
+ }
5386
+
5387
+ private:
5388
+ Arg* arg_ = nullptr;
5389
+ };
5230
5390
  }
5231
5391
  }
5232
5392
 
data/lib/mkmf-rice.rb CHANGED
@@ -31,9 +31,9 @@ if IS_MSWIN
31
31
  $CXXFLAGS += " /std:c++#{std} /EHs /permissive- /bigobj /utf-8 /Zc:__cplusplus"
32
32
  $CPPFLAGS += " -D_ALLOW_KEYWORD_MACROS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE"
33
33
  elsif IS_MINGW
34
- $CXXFLAGS += " -std=c++#{std} -Wa,-mbig-obj"
34
+ $CXXFLAGS += " -std=c++#{std} -Wa,-mbig-obj -Wno-array-bounds"
35
35
  else
36
- $CXXFLAGS += " -std=c++#{std}"
36
+ $CXXFLAGS += " -std=c++#{std} -Wno-array-bounds"
37
37
  end
38
38
 
39
39
  # Rice needs to include its header. Let's setup the include path
data/lib/rice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rice
2
- VERSION = "4.11.4"
2
+ VERSION = "4.12.0"
3
3
  end
data/rice/Constructor.ipp CHANGED
@@ -41,7 +41,7 @@ namespace Rice
41
41
  static void initialize(VALUE self, Parameter_Ts...args)
42
42
  {
43
43
  // Call C++ constructor
44
- T* data = new T(args...);
44
+ T* data = new T(std::forward<Parameter_Ts>(args)...);
45
45
  detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data);
46
46
  }
47
47
 
@@ -75,8 +75,8 @@ namespace Rice
75
75
  static void initialize(Object self, Parameter_Ts...args)
76
76
  {
77
77
  // Call C++ constructor
78
- T* data = new T(self, args...);
78
+ T* data = new T(self, std::forward<Parameter_Ts>(args)...);
79
79
  detail::wrapConstructed<T>(self.value(), Data_Type<T>::ruby_data_type(), data);
80
80
  }
81
81
  };
82
- }
82
+ }
data/rice/Data_Object.ipp CHANGED
@@ -330,16 +330,6 @@ namespace Rice::detail
330
330
  Arg* arg_ = nullptr;
331
331
  };
332
332
 
333
- template<typename T>
334
- class To_Ruby<Data_Object<T>>
335
- {
336
- public:
337
- VALUE convert(const Object& x)
338
- {
339
- return x.value();
340
- }
341
- };
342
-
343
333
  template <typename T>
344
334
  class From_Ruby
345
335
  {
@@ -685,36 +675,4 @@ namespace Rice::detail
685
675
  Arg* arg_ = nullptr;
686
676
  std::vector<Intrinsic_T*> vector_;
687
677
  };
688
-
689
- template<typename T>
690
- class From_Ruby<Data_Object<T>>
691
- {
692
- static_assert(!std::is_fundamental_v<intrinsic_type<T>>,
693
- "Data_Object cannot be used with fundamental types");
694
-
695
- static_assert(!std::is_same_v<T, std::map<T, T>> && !std::is_same_v<T, std::unordered_map<T, T>> &&
696
- !std::is_same_v<T, std::monostate> && !std::is_same_v<T, std::multimap<T, T>> &&
697
- !std::is_same_v<T, std::optional<T>> && !std::is_same_v<T, std::pair<T, T>> &&
698
- !std::is_same_v<T, std::set<T>> && !std::is_same_v<T, std::string> &&
699
- !std::is_same_v<T, std::vector<T>>,
700
- "Please include rice/stl.hpp header for STL support");
701
-
702
- public:
703
- double is_convertible(VALUE value)
704
- {
705
- switch (rb_type(value))
706
- {
707
- case RUBY_T_DATA:
708
- return Data_Type<T>::is_descendant(value) ? Convertible::Exact : Convertible::None;
709
- break;
710
- default:
711
- return Convertible::None;
712
- }
713
- }
714
-
715
- static Data_Object<T> convert(VALUE value)
716
- {
717
- return Data_Object<T>(value);
718
- }
719
- };
720
678
  }
@@ -34,6 +34,7 @@ namespace Rice
34
34
  break;
35
35
  case RUBY_TAG_THROW:
36
36
  this->message_ = "Unexpected throw";
37
+ break;
37
38
  case RUBY_TAG_RAISE:
38
39
  this->message_ = "Ruby exception was thrown";
39
40
  break;
data/rice/Reference.hpp CHANGED
@@ -11,7 +11,7 @@ namespace Rice
11
11
 
12
12
  public:
13
13
  Reference();
14
- Reference(T& data);
14
+ Reference(const T& data);
15
15
  Reference(VALUE value);
16
16
  T& get();
17
17
 
@@ -20,7 +20,7 @@ namespace Rice
20
20
  };
21
21
 
22
22
  // Specialization needed when VALUE type matches T, causing constructor ambiguity
23
- // between Reference(T&) and Reference(VALUE). VALUE is unsigned long when
23
+ // between Reference(const T&) and Reference(VALUE). VALUE is unsigned long when
24
24
  // SIZEOF_LONG == SIZEOF_VOIDP (Linux/macOS) and unsigned long long when
25
25
  // SIZEOF_LONG_LONG == SIZEOF_VOIDP (Windows x64).
26
26
  #if SIZEOF_LONG == SIZEOF_VOIDP
data/rice/Reference.ipp CHANGED
@@ -6,7 +6,7 @@ namespace Rice
6
6
  }
7
7
 
8
8
  template<typename T>
9
- inline Reference<T>::Reference(T& data) : data_(data)
9
+ inline Reference<T>::Reference(const T& data) : data_(data)
10
10
  {
11
11
  }
12
12
 
@@ -9,51 +9,3 @@ namespace Rice
9
9
  {
10
10
  }
11
11
  }
12
-
13
- /*namespace Rice::detail
14
- {
15
- template<>
16
- struct Type<Encoding>
17
- {
18
- static bool verify()
19
- {
20
- return true;
21
- }
22
- };
23
-
24
- template<>
25
- class To_Ruby<Encoding>
26
- {
27
- public:
28
- VALUE convert(const Encoding& encoding)
29
- {
30
- // return x.value();
31
- }
32
- };
33
-
34
- template<>
35
- class From_Ruby<Encoding>
36
- {
37
- public:
38
- Convertible is_convertible(VALUE value)
39
- {
40
- switch (rb_type(value))
41
- {
42
- case RUBY_T_SYMBOL:
43
- return Convertible::Exact;
44
- break;
45
- case RUBY_T_STRING:
46
- return Convertible::Cast;
47
- break;
48
- default:
49
- return Convertible::None;
50
- }
51
- }
52
-
53
- Encoding convert(VALUE value)
54
- {
55
- // return Symbol(value);
56
- }
57
- };
58
- }
59
- */
@@ -248,6 +248,25 @@ namespace Rice::detail
248
248
  Arg* arg_ = nullptr;
249
249
  };
250
250
 
251
+ template<>
252
+ class To_Ruby<Hash&>
253
+ {
254
+ public:
255
+ To_Ruby() = default;
256
+
257
+ explicit To_Ruby(Arg* arg) : arg_(arg)
258
+ {
259
+ }
260
+
261
+ VALUE convert(Hash const& x)
262
+ {
263
+ return x.value();
264
+ }
265
+
266
+ private:
267
+ Arg* arg_ = nullptr;
268
+ };
269
+
251
270
  template<>
252
271
  class From_Ruby<Hash>
253
272
  {
@@ -183,7 +183,7 @@ namespace Rice
183
183
  * \endcode
184
184
  */
185
185
  template<typename ...Parameter_Ts>
186
- Object call(Identifier id, Parameter_Ts... args) const;
186
+ Object call(Identifier id, Parameter_Ts&&... args) const;
187
187
 
188
188
  //! Call the Ruby method specified by 'id' on object 'obj'.
189
189
  /*! Pass in arguments (arg1, arg2, ...). The arguments will be converted to
@@ -206,7 +206,7 @@ namespace Rice
206
206
  * \endcode
207
207
  */
208
208
  template<typename ...Parameter_Ts>
209
- Object call_kw(Identifier id, Parameter_Ts... args) const;
209
+ Object call_kw(Identifier id, Parameter_Ts&&... args) const;
210
210
 
211
211
  //! Vectorized call.
212
212
  /*! Calls the method identified by id with the list of arguments
@@ -42,7 +42,7 @@ namespace Rice
42
42
  }
43
43
 
44
44
  template<typename ...Parameter_Ts>
45
- inline Object Object::call(Identifier id, Parameter_Ts... args) const
45
+ inline Object Object::call(Identifier id, Parameter_Ts&&... args) const
46
46
  {
47
47
  /* IMPORTANT - We store VALUEs in an array that is a local variable.
48
48
  That allows the Ruby garbage collector to find them when scanning
@@ -56,10 +56,10 @@ namespace Rice
56
56
  }
57
57
 
58
58
  template<typename ...Parameter_Ts>
59
- inline Object Object::call_kw(Identifier id, Parameter_Ts... args) const
59
+ inline Object Object::call_kw(Identifier id, Parameter_Ts&&... args) const
60
60
  {
61
61
  /* IMPORTANT - See call() above */
62
- std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(args)... };
62
+ std::array<VALUE, sizeof...(Parameter_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Parameter_Ts>>().convert(std::forward<Parameter_Ts>(args))... };
63
63
  return detail::protect(rb_funcallv_kw, this->validated_value(), id.id(), (int)values.size(), (const VALUE*)values.data(), RB_PASS_KEYWORDS);
64
64
  }
65
65
 
@@ -108,6 +108,25 @@ namespace Rice::detail
108
108
  return x.value();
109
109
  }
110
110
 
111
+ private:
112
+ Arg* arg_ = nullptr;
113
+ };
114
+
115
+ template<>
116
+ class To_Ruby<String&>
117
+ {
118
+ public:
119
+ To_Ruby() = default;
120
+
121
+ explicit To_Ruby(Arg* arg) : arg_(arg)
122
+ {
123
+ }
124
+
125
+ VALUE convert(String const& x)
126
+ {
127
+ return x.value();
128
+ }
129
+
111
130
  private:
112
131
  Arg* arg_ = nullptr;
113
132
  };
@@ -2,6 +2,7 @@
2
2
  #define Rice__detail__Anchor__hpp_
3
3
 
4
4
  #include <ruby.h>
5
+ #include <ruby/vm.h>
5
6
 
6
7
  namespace Rice
7
8
  {
@@ -36,7 +37,6 @@ namespace Rice
36
37
  VALUE get() const;
37
38
 
38
39
  private:
39
- static void disable(VALUE);
40
40
  static void registerExitHandler();
41
41
 
42
42
  inline static bool enabled_ = true;