rice 4.7.0 → 4.8.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -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 +56 -142
  7. data/bin/rice-rbs.rb +1 -2
  8. data/include/rice/api.hpp +248 -0
  9. data/include/rice/rice.hpp +2281 -1668
  10. data/include/rice/stl.hpp +364 -443
  11. data/lib/rice/doc/config.rb +70 -0
  12. data/lib/rice/doc/cpp_reference.rb +1 -4
  13. data/lib/rice/doc/mkdocs.rb +58 -20
  14. data/lib/rice/doc/rice.rb +20 -0
  15. data/lib/rice/doc.rb +1 -0
  16. data/lib/rice/make_rice_headers.rb +7 -0
  17. data/lib/rice/native_registry.rb +2 -2
  18. data/lib/rice/rbs.rb +4 -4
  19. data/lib/rice/version.rb +1 -1
  20. data/lib/rubygems_plugin.rb +12 -9
  21. data/rice/Arg.hpp +12 -6
  22. data/rice/Arg.ipp +14 -7
  23. data/rice/Buffer.ipp +44 -40
  24. data/rice/Callback.hpp +1 -1
  25. data/rice/Callback.ipp +2 -7
  26. data/rice/Constructor.hpp +1 -1
  27. data/rice/Constructor.ipp +11 -11
  28. data/rice/Data_Object.ipp +59 -30
  29. data/rice/Data_Type.hpp +9 -10
  30. data/rice/Data_Type.ipp +22 -25
  31. data/rice/Director.hpp +1 -0
  32. data/rice/Enum.ipp +58 -39
  33. data/rice/Exception.hpp +4 -4
  34. data/rice/Exception.ipp +7 -7
  35. data/rice/NoGVL.hpp +13 -0
  36. data/rice/Reference.hpp +56 -0
  37. data/rice/Reference.ipp +96 -0
  38. data/rice/Return.hpp +4 -1
  39. data/rice/Return.ipp +0 -6
  40. data/rice/cpp_api/Array.hpp +44 -7
  41. data/rice/cpp_api/Array.ipp +105 -9
  42. data/rice/cpp_api/Class.hpp +2 -2
  43. data/rice/cpp_api/Class.ipp +4 -4
  44. data/rice/cpp_api/Hash.ipp +7 -4
  45. data/rice/cpp_api/Module.hpp +4 -4
  46. data/rice/cpp_api/Module.ipp +12 -10
  47. data/rice/cpp_api/Object.hpp +4 -4
  48. data/rice/cpp_api/Object.ipp +15 -12
  49. data/rice/cpp_api/String.hpp +2 -2
  50. data/rice/cpp_api/String.ipp +11 -8
  51. data/rice/cpp_api/Symbol.ipp +16 -7
  52. data/rice/cpp_api/shared_methods.hpp +5 -9
  53. data/rice/detail/InstanceRegistry.hpp +0 -2
  54. data/rice/detail/Native.hpp +31 -21
  55. data/rice/detail/Native.ipp +281 -133
  56. data/rice/detail/NativeAttributeGet.hpp +5 -7
  57. data/rice/detail/NativeAttributeGet.ipp +26 -26
  58. data/rice/detail/NativeAttributeSet.hpp +2 -4
  59. data/rice/detail/NativeAttributeSet.ipp +20 -16
  60. data/rice/detail/NativeCallback.hpp +77 -0
  61. data/rice/detail/NativeCallback.ipp +280 -0
  62. data/rice/detail/NativeFunction.hpp +11 -21
  63. data/rice/detail/NativeFunction.ipp +58 -119
  64. data/rice/detail/NativeInvoker.hpp +4 -4
  65. data/rice/detail/NativeInvoker.ipp +7 -7
  66. data/rice/detail/NativeIterator.hpp +2 -4
  67. data/rice/detail/NativeIterator.ipp +18 -14
  68. data/rice/detail/NativeMethod.hpp +10 -20
  69. data/rice/detail/NativeMethod.ipp +54 -114
  70. data/rice/detail/NativeProc.hpp +5 -7
  71. data/rice/detail/NativeProc.ipp +39 -28
  72. data/rice/detail/NativeRegistry.hpp +0 -1
  73. data/rice/detail/NativeRegistry.ipp +0 -1
  74. data/rice/detail/Parameter.hpp +15 -8
  75. data/rice/detail/Parameter.ipp +102 -43
  76. data/rice/detail/Proc.ipp +14 -28
  77. data/rice/detail/RubyType.ipp +2 -53
  78. data/rice/detail/Type.hpp +23 -7
  79. data/rice/detail/Type.ipp +73 -93
  80. data/rice/detail/TypeRegistry.ipp +5 -4
  81. data/rice/detail/Wrapper.hpp +1 -1
  82. data/rice/detail/Wrapper.ipp +18 -10
  83. data/rice/detail/from_ruby.hpp +8 -6
  84. data/rice/detail/from_ruby.ipp +306 -173
  85. data/rice/detail/ruby.hpp +23 -0
  86. data/rice/libc/file.hpp +4 -4
  87. data/rice/rice.hpp +6 -8
  88. data/rice/rice_api/Native.ipp +5 -1
  89. data/rice/rice_api/Parameter.ipp +1 -1
  90. data/rice/ruby_mark.hpp +2 -1
  91. data/rice/stl/complex.ipp +12 -8
  92. data/rice/stl/map.ipp +27 -22
  93. data/rice/stl/monostate.ipp +16 -12
  94. data/rice/stl/multimap.hpp +0 -2
  95. data/rice/stl/multimap.ipp +27 -22
  96. data/rice/stl/optional.ipp +27 -11
  97. data/rice/stl/pair.ipp +5 -5
  98. data/rice/stl/reference_wrapper.ipp +5 -4
  99. data/rice/stl/set.ipp +16 -16
  100. data/rice/stl/shared_ptr.hpp +0 -16
  101. data/rice/stl/shared_ptr.ipp +34 -190
  102. data/rice/stl/string.ipp +18 -18
  103. data/rice/stl/string_view.ipp +19 -1
  104. data/rice/stl/tuple.ipp +15 -36
  105. data/rice/stl/unique_ptr.ipp +18 -8
  106. data/rice/stl/unordered_map.ipp +20 -15
  107. data/rice/stl/variant.ipp +37 -21
  108. data/rice/stl/vector.ipp +41 -36
  109. data/rice/traits/function_traits.hpp +19 -19
  110. data/rice/traits/method_traits.hpp +4 -4
  111. data/rice/traits/rice_traits.hpp +162 -39
  112. data/rice.gemspec +1 -4
  113. data/test/test_Array.cpp +261 -3
  114. data/test/test_Attribute.cpp +6 -3
  115. data/test/test_Buffer.cpp +6 -42
  116. data/test/test_Callback.cpp +77 -23
  117. data/test/test_Data_Object.cpp +2 -2
  118. data/test/test_Data_Type.cpp +23 -23
  119. data/test/test_Director.cpp +2 -4
  120. data/test/test_Enum.cpp +34 -5
  121. data/test/test_File.cpp +9 -5
  122. data/test/test_From_Ruby.cpp +7 -6
  123. data/test/test_GVL.cpp +3 -3
  124. data/test/test_Hash.cpp +1 -1
  125. data/test/test_Iterator.cpp +54 -22
  126. data/test/test_Keep_Alive.cpp +1 -1
  127. data/test/test_Keep_Alive_No_Wrapper.cpp +1 -1
  128. data/test/test_Module.cpp +5 -5
  129. data/test/test_Overloads.cpp +395 -50
  130. data/test/test_Proc.cpp +54 -0
  131. data/test/test_Reference.cpp +181 -0
  132. data/test/test_Self.cpp +2 -2
  133. data/test/test_Stl_Set.cpp +6 -6
  134. data/test/test_Stl_SharedPtr.cpp +54 -30
  135. data/test/test_Stl_String_View.cpp +12 -0
  136. data/test/test_Stl_Tuple.cpp +1 -1
  137. data/test/test_Stl_Variant.cpp +6 -14
  138. data/test/test_Stl_Vector.cpp +61 -30
  139. data/test/test_String.cpp +4 -2
  140. data/test/test_Struct.cpp +1 -1
  141. data/test/test_Symbol.cpp +12 -0
  142. data/test/test_To_Ruby.cpp +1 -0
  143. data/test/test_Type.cpp +36 -35
  144. data/test/test_global_functions.cpp +1 -1
  145. data/test/unittest.cpp +1 -1
  146. data/test/unittest.hpp +5 -5
  147. metadata +10 -24
  148. data/rice/Function.hpp +0 -17
  149. data/rice/Function.ipp +0 -13
  150. data/rice/detail/MethodInfo.hpp +0 -48
  151. data/rice/detail/MethodInfo.ipp +0 -99
  152. data/rice/detail/NativeCallbackFFI.hpp +0 -55
  153. data/rice/detail/NativeCallbackFFI.ipp +0 -152
  154. data/rice/detail/NativeCallbackSimple.hpp +0 -30
  155. data/rice/detail/NativeCallbackSimple.ipp +0 -29
data/rice/Buffer.ipp CHANGED
@@ -102,11 +102,11 @@ namespace Rice
102
102
  }
103
103
  default:
104
104
  {
105
- if (RubyType_T::Exact.find(valueType) != RubyType_T::Exact.end() ||
106
- RubyType_T::Castable.find(valueType) != RubyType_T::Castable.end() ||
107
- RubyType_T::Narrowable.find(valueType) != RubyType_T::Narrowable.end())
105
+ if (detail::From_Ruby<detail::remove_cv_recursive_t<T>>().is_convertible(value))
108
106
  {
109
- T data = detail::protect(RubyType_T::fromRuby, value);
107
+ // The Ruby method may return a different type - for example Ruby floats
108
+ // are converted to double and not float - so we need a typecast.
109
+ T data = (T)detail::protect(RubyType_T::fromRuby, value);
110
110
  this->m_size = 1;
111
111
  this->m_buffer = new T[this->m_size]();
112
112
  memcpy((void*)this->m_buffer, &data, sizeof(T));
@@ -115,9 +115,9 @@ namespace Rice
115
115
  }
116
116
  else
117
117
  {
118
- detail::TypeMapper<T> typeMapper;
119
- std::string typeName = typeMapper.name();
120
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
118
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
119
+ std::string typeName = typeIndexParser.name();
120
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
121
121
  detail::protect(rb_obj_classname, value), typeName.c_str());
122
122
  }
123
123
  }
@@ -137,8 +137,8 @@ namespace Rice
137
137
  this->m_size = array.size();
138
138
 
139
139
  // Use operator new[] to allocate memory but not call constructors.
140
- size_t size = sizeof(T) * this->m_size;
141
- this->m_buffer = static_cast<T*>(operator new[](size));
140
+ size_t memsize = sizeof(T) * this->m_size;
141
+ this->m_buffer = static_cast<T*>(operator new[](memsize));
142
142
 
143
143
  detail::From_Ruby<Intrinsic_T> fromRuby;
144
144
 
@@ -147,7 +147,7 @@ namespace Rice
147
147
  // Construct objects in allocated memory using move or copy construction
148
148
  if constexpr (std::is_move_constructible_v<T>)
149
149
  {
150
- new (&this->m_buffer[i]) T(std::move(fromRuby.convert(array[i].value())));
150
+ new (&this->m_buffer[i]) T(std::move(fromRuby.convert(array[(long)i].value())));
151
151
  }
152
152
  else if constexpr (std::is_copy_constructible_v<T>)
153
153
  {
@@ -155,8 +155,9 @@ namespace Rice
155
155
  }
156
156
  else
157
157
  {
158
+ detail::TypeIndexParser typeIndexParser(typeid(Intrinsic_T), std::is_fundamental_v<Intrinsic_T>);
158
159
  throw Exception(rb_eTypeError, "Cannot construct object of type %s - type is not move or copy constructible",
159
- detail::TypeMapper<Intrinsic_T>().name().c_str());
160
+ typeIndexParser.name().c_str());
160
161
  }
161
162
  }
162
163
  break;
@@ -196,9 +197,9 @@ namespace Rice
196
197
  }
197
198
  default:
198
199
  {
199
- detail::TypeMapper<T> typeMapper;
200
- std::string typeName = typeMapper.name();
201
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
200
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
201
+ std::string typeName = typeIndexParser.name();
202
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
202
203
  detail::protect(rb_obj_classname, value), typeName.c_str());
203
204
  }
204
205
  }
@@ -267,8 +268,8 @@ namespace Rice
267
268
  template<typename T>
268
269
  inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::toString() const
269
270
  {
270
- detail::TypeMapper<T*> typeMapper;
271
- std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
271
+ detail::TypeIndexParser typeIndexParser(typeid(T*), std::is_fundamental_v<detail::intrinsic_type<T>>);
272
+ std::string description = "Buffer<type: " + typeIndexParser.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
272
273
 
273
274
  // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
274
275
  return detail::protect(rb_utf8_str_new_cstr, description.c_str());
@@ -345,7 +346,7 @@ namespace Rice
345
346
  }
346
347
 
347
348
  template<typename T>
348
- inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
349
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_size(size), m_buffer(pointer)
349
350
  {
350
351
  }
351
352
 
@@ -373,7 +374,7 @@ namespace Rice
373
374
  for (size_t i = 0; i < this->m_size; i++)
374
375
  {
375
376
  // Check the inner value is also an array
376
- Array inner(outer[i].value());
377
+ Array inner(outer[(long)i].value());
377
378
 
378
379
  // Allocate inner buffer
379
380
  this->m_buffer[i] = new T[inner.size()]();
@@ -383,13 +384,16 @@ namespace Rice
383
384
  String packed = inner.pack<Intrinsic_T>();
384
385
  memcpy((void*)this->m_buffer[i], RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
385
386
  }
387
+ // This is for std::string, should be a 1 length array
386
388
  else
387
389
  {
388
390
  detail::From_Ruby<Intrinsic_T*> fromRuby;
389
- for (int i = 0; i < inner.size(); i++)
391
+ if (inner.size() != 1)
390
392
  {
391
- this->m_buffer[0] = fromRuby.convert(inner[i].value());
393
+ throw Exception(rb_eTypeError, "Expected inner array size 1 for type %s* but got %ld",
394
+ detail::TypeIndexParser(typeid(T)).name().c_str(), inner.size());
392
395
  }
396
+ this->m_buffer[i] = fromRuby.convert(inner[0].value());
393
397
  }
394
398
  }
395
399
 
@@ -409,9 +413,9 @@ namespace Rice
409
413
  }
410
414
  default:
411
415
  {
412
- detail::TypeMapper<T> typeMapper;
413
- std::string typeName = typeMapper.name();
414
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
416
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
417
+ std::string typeName = typeIndexParser.name();
418
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
415
419
  detail::protect(rb_obj_classname, value), typeName.c_str());
416
420
  }
417
421
  }
@@ -495,8 +499,8 @@ namespace Rice
495
499
  template<typename T>
496
500
  inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toString() const
497
501
  {
498
- detail::TypeMapper<T*> typeMapper;
499
- std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
502
+ detail::TypeIndexParser typeIndexParser(typeid(T*), std::is_fundamental_v<detail::intrinsic_type<T>>);
503
+ std::string description = "Buffer<type: " + typeIndexParser.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
500
504
 
501
505
  // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
502
506
  return detail::protect(rb_utf8_str_new_cstr, description.c_str());
@@ -559,7 +563,7 @@ namespace Rice
559
563
  }
560
564
 
561
565
  template<typename T>
562
- inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
566
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_size(size), m_buffer(pointer)
563
567
  {
564
568
  }
565
569
 
@@ -584,7 +588,7 @@ namespace Rice
584
588
 
585
589
  for (size_t i = 0; i < this->m_size; i++)
586
590
  {
587
- this->m_buffer[i] = fromRuby.convert(array[i].value());
591
+ this->m_buffer[i] = fromRuby.convert(array[(long)i].value());
588
592
  }
589
593
 
590
594
  this->m_owner = true;
@@ -602,9 +606,9 @@ namespace Rice
602
606
  }
603
607
  default:
604
608
  {
605
- detail::TypeMapper<T> typeMapper;
606
- std::string typeName = typeMapper.name();
607
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
609
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
610
+ std::string typeName = typeIndexParser.name();
611
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
608
612
  detail::protect(rb_obj_classname, value), typeName.c_str());
609
613
  }
610
614
  }
@@ -687,8 +691,8 @@ namespace Rice
687
691
  template<typename T>
688
692
  inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toString() const
689
693
  {
690
- detail::TypeMapper<T*> typeMapper;
691
- std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
694
+ detail::TypeIndexParser typeIndexParser(typeid(T*), std::is_fundamental_v<detail::intrinsic_type<T>>);
695
+ std::string description = "Buffer<type: " + typeIndexParser.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
692
696
 
693
697
  // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
694
698
  return detail::protect(rb_utf8_str_new_cstr, description.c_str());
@@ -750,7 +754,7 @@ namespace Rice
750
754
  }
751
755
 
752
756
  template<typename T>
753
- inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(VALUE value, size_t size)
757
+ inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(VALUE value, size_t)
754
758
  {
755
759
  ruby_value_type valueType = rb_type(value);
756
760
 
@@ -767,9 +771,9 @@ namespace Rice
767
771
  }
768
772
  default:
769
773
  {
770
- detail::TypeMapper<void> typeMapper;
771
- std::string typeName = typeMapper.name();
772
- throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
774
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
775
+ std::string typeName = typeIndexParser.name();
776
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected %s*)",
773
777
  detail::protect(rb_obj_classname, value), typeName.c_str());
774
778
  }
775
779
  }
@@ -863,8 +867,8 @@ namespace Rice
863
867
  define_method("size", &Buffer_T::size).
864
868
  template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
865
869
  template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
866
- define_method("data", &Buffer_T::ptr, Return().setBuffer()).
867
- define_method("release", &Buffer_T::release, Return().setBuffer());
870
+ define_method("data", &Buffer_T::ptr, ReturnBuffer()).
871
+ define_method("release", &Buffer_T::release, ReturnBuffer());
868
872
  }
869
873
  else
870
874
  {
@@ -878,8 +882,8 @@ namespace Rice
878
882
  template define_method<Array(Buffer_T::*)(size_t) const>("to_ary", &Buffer_T::toArray, Return().setValue()).
879
883
  template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue()).
880
884
  define_method("[]", &Buffer_T::operator[], Arg("index")).
881
- define_method("data", &Buffer_T::ptr, Return().setBuffer()).
882
- define_method("release", &Buffer_T::release, Return().setBuffer());
885
+ define_method("data", &Buffer_T::ptr, ReturnBuffer()).
886
+ define_method("release", &Buffer_T::release, ReturnBuffer());
883
887
 
884
888
  if constexpr (!std::is_pointer_v<T> && !std::is_void_v<T> && !std::is_const_v<T> && std::is_copy_assignable_v<T>)
885
889
  {
data/rice/Callback.hpp CHANGED
@@ -16,6 +16,6 @@ namespace Rice
16
16
  * \return nothing
17
17
  */
18
18
  template<typename Callback_T, typename...Arg_Ts>
19
- void define_callback(const Arg_Ts&...args);
19
+ void define_callback(Arg_Ts&&...args);
20
20
  }
21
21
  #endif // Rice__Callback__hpp_
data/rice/Callback.ipp CHANGED
@@ -1,13 +1,8 @@
1
1
  namespace Rice
2
2
  {
3
3
  template<typename Callback_T, typename...Arg_Ts>
4
- void define_callback(const Arg_Ts&...args)
4
+ inline void define_callback(Arg_Ts&&...args)
5
5
  {
6
- MethodInfo* methodInfo = new MethodInfo(detail::function_traits<Callback_T>::arity, args...);
7
- #ifdef HAVE_LIBFFI
8
- detail::NativeCallbackFFI<Callback_T>::setMethodInfo(methodInfo);
9
- #else
10
- detail::NativeCallbackSimple<Callback_T>::setMethodInfo(methodInfo);
11
- #endif
6
+ detail::NativeCallback<Callback_T>::define(std::forward<Arg_Ts>(args)...);
12
7
  }
13
8
  }
data/rice/Constructor.hpp CHANGED
@@ -16,7 +16,7 @@ namespace Rice
16
16
  *
17
17
  * For more information, see Rice::Data_Type::define_constructor.
18
18
  */
19
- template<typename T, typename...Arg_Ts>
19
+ template<typename T, typename...Parameter_Ts>
20
20
  class Constructor;
21
21
  }
22
22
  #endif // Rice__Constructor__hpp_
data/rice/Constructor.ipp CHANGED
@@ -1,16 +1,16 @@
1
1
  namespace Rice
2
2
  {
3
- template<typename T, typename...Arg_Ts>
3
+ template<typename T, typename...Parameter_Ts>
4
4
  class Constructor
5
5
  {
6
6
  public:
7
- static constexpr std::size_t arity = sizeof...(Arg_Ts);
7
+ static constexpr std::size_t arity = sizeof...(Parameter_Ts);
8
8
 
9
9
  static constexpr bool isCopyConstructor()
10
10
  {
11
11
  if constexpr (arity == 1)
12
12
  {
13
- using Arg_Types = std::tuple<Arg_Ts...>;
13
+ using Arg_Types = std::tuple<Parameter_Ts...>;
14
14
  using First_Arg_T = std::tuple_element_t<0, Arg_Types>;
15
15
  return (arity == 1 &&
16
16
  std::is_lvalue_reference_v<First_Arg_T> &&
@@ -26,7 +26,7 @@ namespace Rice
26
26
  {
27
27
  if constexpr (arity == 1)
28
28
  {
29
- using Arg_Types = std::tuple<Arg_Ts...>;
29
+ using Arg_Types = std::tuple<Parameter_Ts...>;
30
30
  using First_Arg_T = std::tuple_element_t<0, Arg_Types>;
31
31
  return (arity == 1 &&
32
32
  std::is_rvalue_reference_v<First_Arg_T> &&
@@ -38,25 +38,25 @@ namespace Rice
38
38
  }
39
39
  }
40
40
 
41
- static void initialize(VALUE self, Arg_Ts...args)
41
+ static void initialize(VALUE self, Parameter_Ts...args)
42
42
  {
43
43
  // Call C++ constructor
44
44
  T* data = new T(args...);
45
- detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data, true);
45
+ detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data);
46
46
  }
47
47
 
48
48
  static void initialize_copy(VALUE self, const T& other)
49
49
  {
50
50
  // Call C++ copy constructor
51
51
  T* data = new T(other);
52
- detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data, true);
52
+ detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data);
53
53
  }
54
54
 
55
55
  };
56
56
 
57
57
  //! Special-case Constructor used when defining Directors.
58
- template<typename T, typename...Arg_Ts>
59
- class Constructor<T, Object, Arg_Ts...>
58
+ template<typename T, typename...Parameter_Ts>
59
+ class Constructor<T, Object, Parameter_Ts...>
60
60
  {
61
61
  public:
62
62
  static constexpr bool isCopyConstructor()
@@ -69,11 +69,11 @@ namespace Rice
69
69
  return false;
70
70
  }
71
71
 
72
- static void initialize(Object self, Arg_Ts...args)
72
+ static void initialize(Object self, Parameter_Ts...args)
73
73
  {
74
74
  // Call C++ constructor
75
75
  T* data = new T(self, args...);
76
- detail::wrapConstructed<T>(self.value(), Data_Type<T>::ruby_data_type(), data, true);
76
+ detail::wrapConstructed<T>(self.value(), Data_Type<T>::ruby_data_type(), data);
77
77
  }
78
78
  };
79
79
  }
data/rice/Data_Object.ipp CHANGED
@@ -6,16 +6,17 @@ namespace Rice
6
6
  template <typename T>
7
7
  Exception create_type_exception(VALUE value)
8
8
  {
9
- if constexpr (std::is_pointer_v<T>)
9
+ if (Data_Type<T>::is_bound())
10
10
  {
11
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
12
- detail::protect(rb_class2name, Data_Type<Pointer<std::remove_cv_t<std::remove_pointer_t<T>>>>::klass().value()),
11
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
12
+ detail::protect(rb_class2name, Data_Type<T>::klass().value()),
13
13
  detail::protect(rb_obj_classname, value));
14
14
  }
15
15
  else
16
16
  {
17
- return Exception(rb_eTypeError, "Wrong argument type. Expected: %s. Received: %s.",
18
- detail::protect(rb_class2name, Data_Type<detail::intrinsic_type<T>>::klass().value()),
17
+ detail::TypeIndexParser typeIndexParser(typeid(T), std::is_fundamental_v<detail::intrinsic_type<T>>);
18
+ return Exception(rb_eTypeError, "Wrong argument type. Expected %s. Received %s.",
19
+ typeIndexParser.simplifiedName().c_str(),
19
20
  detail::protect(rb_obj_classname, value));
20
21
  }
21
22
  }
@@ -227,7 +228,7 @@ namespace Rice::detail
227
228
  VALUE convert(U* data)
228
229
  {
229
230
  bool isOwner = this->arg_ && this->arg_->isOwner();
230
- bool isBuffer = this->arg_ && this->arg_->isBuffer();
231
+ bool isBuffer = dynamic_cast<ReturnBuffer*>(this->arg_) ? true : false;
231
232
 
232
233
  if (data == nullptr)
233
234
  {
@@ -272,7 +273,7 @@ namespace Rice::detail
272
273
  VALUE convert(U* data)
273
274
  {
274
275
  bool isOwner = this->arg_ && this->arg_->isOwner();
275
- bool isBuffer = this->arg_ && this->arg_->isBuffer();
276
+ bool isBuffer = dynamic_cast<ReturnBuffer*>(this->arg_) ? true : false;
276
277
 
277
278
  if (data == nullptr)
278
279
  {
@@ -360,7 +361,7 @@ namespace Rice::detail
360
361
  {
361
362
  }
362
363
 
363
- Convertible is_convertible(VALUE value)
364
+ double is_convertible(VALUE value)
364
365
  {
365
366
  switch (rb_type(value))
366
367
  {
@@ -411,7 +412,7 @@ namespace Rice::detail
411
412
  {
412
413
  }
413
414
 
414
- Convertible is_convertible(VALUE value)
415
+ double is_convertible(VALUE value)
415
416
  {
416
417
  switch (rb_type(value))
417
418
  {
@@ -454,7 +455,7 @@ namespace Rice::detail
454
455
  {
455
456
  }
456
457
 
457
- Convertible is_convertible(VALUE value)
458
+ double is_convertible(VALUE value)
458
459
  {
459
460
  switch (rb_type(value))
460
461
  {
@@ -491,6 +492,7 @@ namespace Rice::detail
491
492
  "Please include rice/stl.hpp header for STL support");
492
493
 
493
494
  using Intrinsic_T = intrinsic_type<T>;
495
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>>;
494
496
 
495
497
  public:
496
498
  From_Ruby() = default;
@@ -499,19 +501,21 @@ namespace Rice::detail
499
501
  {
500
502
  }
501
503
 
502
- Convertible is_convertible(VALUE value)
504
+ double is_convertible(VALUE value)
503
505
  {
506
+ bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
507
+
504
508
  switch (rb_type(value))
505
509
  {
506
510
  case RUBY_T_NIL:
507
511
  return Convertible::Exact;
508
512
  break;
509
513
  case RUBY_T_DATA:
510
- if (Data_Type<T>::is_descendant(value))
514
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
511
515
  {
512
516
  return Convertible::Exact;
513
517
  }
514
- else if (Data_Type<Pointer<T>>::is_descendant(value))
518
+ else if (Data_Type<Pointer_T>::is_descendant(value))
515
519
  {
516
520
  return Convertible::Exact;
517
521
  }
@@ -524,6 +528,7 @@ namespace Rice::detail
524
528
  T* convert(VALUE value)
525
529
  {
526
530
  bool isOwner = this->arg_ && this->arg_->isOwner();
531
+ bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
527
532
 
528
533
  switch (rb_type(value))
529
534
  {
@@ -534,19 +539,26 @@ namespace Rice::detail
534
539
  }
535
540
  case RUBY_T_DATA:
536
541
  {
537
- if (Data_Type<T>::is_descendant(value))
542
+ if (Data_Type<T>::is_descendant(value) && !isBuffer)
538
543
  {
539
544
  return detail::unwrap<Intrinsic_T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), isOwner);
540
545
  }
541
- else if (Data_Type<Pointer<T>>::is_descendant(value))
546
+ else if (Data_Type<Pointer_T>::is_descendant(value))
542
547
  {
543
- return detail::unwrap<T>(value, Data_Type<Pointer<T>>::ruby_data_type(), isOwner);
548
+ return detail::unwrap<T>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
544
549
  }
545
550
  [[fallthrough]];
546
551
  }
547
552
  default:
548
553
  {
549
- throw create_type_exception<T*>(value);
554
+ if (isBuffer || std::is_fundamental_v<T>)
555
+ {
556
+ throw create_type_exception<Pointer_T>(value);
557
+ }
558
+ else
559
+ {
560
+ throw create_type_exception<T>(value);
561
+ }
550
562
  }
551
563
  }
552
564
  }
@@ -572,7 +584,7 @@ namespace Rice::detail
572
584
  {
573
585
  }
574
586
 
575
- Convertible is_convertible(VALUE value)
587
+ double is_convertible(VALUE value)
576
588
  {
577
589
  switch (rb_type(value))
578
590
  {
@@ -613,6 +625,7 @@ namespace Rice::detail
613
625
  "Please include rice/stl.hpp header for STL support");
614
626
 
615
627
  using Intrinsic_T = intrinsic_type<T>;
628
+ using Pointer_T = Pointer<remove_cv_recursive_t<T>*>;
616
629
  public:
617
630
  From_Ruby() = default;
618
631
 
@@ -620,16 +633,21 @@ namespace Rice::detail
620
633
  {
621
634
  }
622
635
 
623
- Convertible is_convertible(VALUE value)
636
+ double is_convertible(VALUE value)
624
637
  {
638
+ bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
639
+
625
640
  switch (rb_type(value))
626
641
  {
627
- case RUBY_T_DATA:
628
- return Data_Type<Pointer<T*>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
629
- break;
630
642
  case RUBY_T_NIL:
631
643
  return Convertible::Exact;
632
644
  break;
645
+ case RUBY_T_DATA:
646
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
647
+ {
648
+ return Convertible::Exact;
649
+ }
650
+ [[fallthrough]];
633
651
  default:
634
652
  return Convertible::None;
635
653
  }
@@ -638,23 +656,34 @@ namespace Rice::detail
638
656
  T** convert(VALUE value)
639
657
  {
640
658
  bool isOwner = this->arg_ && this->arg_->isOwner();
659
+ bool isBuffer = dynamic_cast<ArgBuffer*>(this->arg_) ? true : false;
641
660
 
642
661
  switch (rb_type(value))
643
662
  {
644
- case RUBY_T_DATA:
645
- {
646
- T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), isOwner);
647
- return result;
648
- break;
649
- }
650
663
  case RUBY_T_NIL:
651
664
  {
652
665
  return nullptr;
653
666
  break;
654
667
  }
668
+ case RUBY_T_DATA:
669
+ {
670
+ if (Data_Type<Pointer_T>::is_descendant(value) && isBuffer)
671
+ {
672
+ T** result = detail::unwrap<Intrinsic_T*>(value, Data_Type<Pointer_T>::ruby_data_type(), isOwner);
673
+ return result;
674
+ }
675
+ [[fallthrough]];
676
+ }
655
677
  default:
656
678
  {
657
- throw create_type_exception<T**>(value);
679
+ if (isBuffer)
680
+ {
681
+ throw create_type_exception<Pointer_T>(value);
682
+ }
683
+ else
684
+ {
685
+ throw create_type_exception<T**>(value);
686
+ }
658
687
  }
659
688
  }
660
689
  }
@@ -678,7 +707,7 @@ namespace Rice::detail
678
707
  "Please include rice/stl.hpp header for STL support");
679
708
 
680
709
  public:
681
- Convertible is_convertible(VALUE value)
710
+ double is_convertible(VALUE value)
682
711
  {
683
712
  switch (rb_type(value))
684
713
  {
data/rice/Data_Type.hpp CHANGED
@@ -90,8 +90,7 @@ namespace Rice
90
90
  * library to die at run time when it tries to convert the base
91
91
  * type into the Director proxy type.
92
92
  *
93
- * This method takes no methodInfo, just needs the type of the
94
- * Director proxy class.
93
+ * This method needs the type of the Director proxy class.
95
94
  *
96
95
  * For example:
97
96
  * \code
@@ -134,11 +133,11 @@ namespace Rice
134
133
  template<typename Iterator_Func_T>
135
134
  Data_Type<T>& define_iterator(Iterator_Func_T begin, Iterator_Func_T end, std::string name = "each");
136
135
 
137
- template <typename Attribute_T>
138
- Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, Return returnInfo = Return());
136
+ template <typename Attribute_T, typename...Arg_Ts>
137
+ Data_Type<T>& define_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, const Arg_Ts&...args);
139
138
 
140
- template <typename Attribute_T>
141
- Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, Return returnInfo = Return());
139
+ template <typename Attribute_T, typename...Arg_Ts>
140
+ Data_Type<T>& define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access = AttrAccess::ReadWrite, const Arg_Ts&...args);
142
141
 
143
142
  #include "cpp_api/shared_methods.hpp"
144
143
  protected:
@@ -161,11 +160,11 @@ namespace Rice
161
160
  template<typename T_, typename Base_T>
162
161
  friend Rice::Data_Type<T_> define_class(char const * name);
163
162
 
164
- template<typename Method_T>
165
- void wrap_native_method(VALUE klass, std::string name, Method_T&& function, MethodInfo* methodInfo);
163
+ template<typename Method_T, typename...Arg_Ts>
164
+ void wrap_native_method(VALUE klass, std::string name, Method_T&& function, const Arg_Ts&...args);
166
165
 
167
- template <typename Attribute_T>
168
- Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, Return returnInfo);
166
+ template <typename Attribute_T, typename...Arg_Ts>
167
+ Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access, const Arg_Ts&...args);
169
168
 
170
169
  private:
171
170
  template<typename T_>