rice 4.5.0 → 4.6.1

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/Rakefile +5 -4
  8. data/include/rice/rice.hpp +5619 -3129
  9. data/include/rice/stl.hpp +2319 -1234
  10. data/lib/make_rice_headers.rb +79 -0
  11. data/lib/mkmf-rice.rb +4 -0
  12. data/lib/rice/version.rb +3 -0
  13. data/lib/rice.rb +1 -0
  14. data/lib/rubygems/builder.rb +11 -0
  15. data/lib/rubygems/cmake_builder.rb +113 -0
  16. data/lib/rubygems_plugin.rb +9 -0
  17. data/rice/Arg.hpp +7 -1
  18. data/rice/Arg.ipp +11 -2
  19. data/rice/Buffer.hpp +168 -0
  20. data/rice/Buffer.ipp +788 -0
  21. data/rice/Constructor.ipp +3 -3
  22. data/rice/Data_Object.hpp +2 -3
  23. data/rice/Data_Object.ipp +188 -188
  24. data/rice/Data_Type.hpp +7 -5
  25. data/rice/Data_Type.ipp +79 -52
  26. data/rice/Enum.hpp +0 -1
  27. data/rice/Enum.ipp +26 -23
  28. data/rice/Init.hpp +8 -0
  29. data/rice/Init.ipp +8 -0
  30. data/rice/MemoryView.ipp +1 -41
  31. data/rice/Return.hpp +1 -1
  32. data/rice/Return.ipp +6 -0
  33. data/rice/cpp_api/Array.hpp +209 -0
  34. data/rice/cpp_api/Array.ipp +304 -0
  35. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  36. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  37. data/rice/cpp_api/Class.hpp +70 -0
  38. data/rice/cpp_api/Class.ipp +97 -0
  39. data/rice/cpp_api/Encoding.hpp +32 -0
  40. data/rice/cpp_api/Encoding.ipp +59 -0
  41. data/rice/cpp_api/Hash.hpp +194 -0
  42. data/rice/cpp_api/Hash.ipp +257 -0
  43. data/rice/cpp_api/Identifier.hpp +46 -0
  44. data/rice/cpp_api/Identifier.ipp +31 -0
  45. data/rice/cpp_api/Module.hpp +72 -0
  46. data/rice/cpp_api/Module.ipp +101 -0
  47. data/rice/cpp_api/Object.hpp +272 -0
  48. data/rice/cpp_api/Object.ipp +235 -0
  49. data/rice/cpp_api/String.hpp +74 -0
  50. data/rice/cpp_api/String.ipp +120 -0
  51. data/rice/cpp_api/Struct.hpp +113 -0
  52. data/rice/cpp_api/Struct.ipp +92 -0
  53. data/rice/cpp_api/Symbol.hpp +46 -0
  54. data/rice/cpp_api/Symbol.ipp +93 -0
  55. data/rice/cpp_api/shared_methods.hpp +134 -0
  56. data/rice/detail/MethodInfo.hpp +1 -9
  57. data/rice/detail/MethodInfo.ipp +5 -72
  58. data/rice/detail/Native.hpp +3 -2
  59. data/rice/detail/Native.ipp +32 -4
  60. data/rice/detail/NativeAttributeGet.hpp +3 -2
  61. data/rice/detail/NativeAttributeGet.ipp +20 -3
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +11 -23
  64. data/rice/detail/NativeCallbackFFI.ipp +2 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +169 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyFunction.ipp +1 -0
  70. data/rice/detail/RubyType.hpp +2 -5
  71. data/rice/detail/RubyType.ipp +50 -5
  72. data/rice/detail/Type.hpp +3 -1
  73. data/rice/detail/Type.ipp +60 -31
  74. data/rice/detail/Wrapper.hpp +68 -33
  75. data/rice/detail/Wrapper.ipp +103 -113
  76. data/rice/detail/from_ruby.hpp +5 -4
  77. data/rice/detail/from_ruby.ipp +737 -365
  78. data/rice/detail/to_ruby.ipp +1092 -186
  79. data/rice/global_function.ipp +1 -1
  80. data/rice/libc/file.hpp +11 -0
  81. data/rice/libc/file.ipp +32 -0
  82. data/rice/rice.hpp +23 -16
  83. data/rice/stl/complex.hpp +6 -0
  84. data/rice/stl/complex.ipp +93 -0
  85. data/rice/stl/exception.hpp +11 -0
  86. data/rice/stl/exception.ipp +29 -0
  87. data/rice/stl/exception_ptr.hpp +6 -0
  88. data/rice/stl/exception_ptr.ipp +27 -0
  89. data/rice/stl/map.hpp +12 -0
  90. data/rice/stl/map.ipp +469 -0
  91. data/rice/stl/monostate.hpp +6 -0
  92. data/rice/stl/monostate.ipp +80 -0
  93. data/rice/stl/multimap.hpp +14 -0
  94. data/rice/stl/multimap.ipp +448 -0
  95. data/rice/stl/optional.hpp +6 -0
  96. data/rice/stl/optional.ipp +118 -0
  97. data/rice/stl/pair.hpp +13 -0
  98. data/rice/stl/pair.ipp +155 -0
  99. data/rice/stl/reference_wrapper.hpp +6 -0
  100. data/rice/stl/reference_wrapper.ipp +41 -0
  101. data/rice/stl/set.hpp +12 -0
  102. data/rice/stl/set.ipp +495 -0
  103. data/rice/stl/shared_ptr.hpp +28 -0
  104. data/rice/stl/shared_ptr.ipp +224 -0
  105. data/rice/stl/string.hpp +6 -0
  106. data/rice/stl/string.ipp +158 -0
  107. data/rice/stl/string_view.hpp +6 -0
  108. data/rice/stl/string_view.ipp +65 -0
  109. data/rice/stl/tuple.hpp +6 -0
  110. data/rice/stl/tuple.ipp +128 -0
  111. data/rice/stl/type_index.hpp +6 -0
  112. data/rice/stl/type_index.ipp +30 -0
  113. data/rice/stl/type_info.hpp +6 -0
  114. data/rice/stl/type_info.ipp +29 -0
  115. data/rice/stl/unique_ptr.hpp +22 -0
  116. data/rice/stl/unique_ptr.ipp +139 -0
  117. data/rice/stl/unordered_map.hpp +12 -0
  118. data/rice/stl/unordered_map.ipp +469 -0
  119. data/rice/stl/variant.hpp +6 -0
  120. data/rice/stl/variant.ipp +242 -0
  121. data/rice/stl/vector.hpp +12 -0
  122. data/rice/stl/vector.ipp +589 -0
  123. data/rice/stl.hpp +7 -3
  124. data/rice/traits/attribute_traits.hpp +26 -0
  125. data/rice/traits/function_traits.hpp +95 -0
  126. data/rice/traits/method_traits.hpp +47 -0
  127. data/rice/traits/rice_traits.hpp +172 -0
  128. data/rice.gemspec +85 -0
  129. data/test/embed_ruby.cpp +3 -0
  130. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  131. data/test/test_Array.cpp +6 -3
  132. data/test/test_Attribute.cpp +91 -9
  133. data/test/test_Buffer.cpp +340 -0
  134. data/test/test_Callback.cpp +2 -3
  135. data/test/test_Data_Object.cpp +88 -34
  136. data/test/test_Data_Type.cpp +106 -65
  137. data/test/test_Director.cpp +7 -3
  138. data/test/test_Enum.cpp +5 -2
  139. data/test/test_File.cpp +1 -1
  140. data/test/test_From_Ruby.cpp +180 -113
  141. data/test/test_Iterator.cpp +1 -1
  142. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  143. data/test/test_Keep_Alive.cpp +7 -18
  144. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  145. data/test/test_Module.cpp +13 -6
  146. data/test/test_Native_Registry.cpp +0 -1
  147. data/test/test_Overloads.cpp +180 -5
  148. data/test/test_Ownership.cpp +100 -57
  149. data/test/test_Proc.cpp +0 -1
  150. data/test/test_Self.cpp +4 -4
  151. data/test/test_Stl_Map.cpp +37 -39
  152. data/test/test_Stl_Multimap.cpp +693 -0
  153. data/test/test_Stl_Pair.cpp +8 -8
  154. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  155. data/test/test_Stl_Set.cpp +790 -0
  156. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  157. data/test/test_Stl_Tuple.cpp +116 -0
  158. data/test/test_Stl_Type.cpp +1 -1
  159. data/test/test_Stl_UniquePtr.cpp +202 -0
  160. data/test/test_Stl_Unordered_Map.cpp +28 -34
  161. data/test/test_Stl_Variant.cpp +217 -89
  162. data/test/test_Stl_Vector.cpp +209 -83
  163. data/test/test_To_Ruby.cpp +373 -1
  164. data/test/test_Type.cpp +85 -14
  165. data/test/test_global_functions.cpp +17 -4
  166. metadata +94 -10
  167. data/rice/detail/TupleIterator.hpp +0 -14
@@ -2,11 +2,12 @@
2
2
 
3
3
  namespace Rice::detail
4
4
  {
5
- inline Wrapper::Wrapper(bool isOwner): isOwner_(isOwner)
5
+ inline bool WrapperBase::isConst()
6
6
  {
7
+ return this->isConst_;
7
8
  }
8
9
 
9
- inline void Wrapper::ruby_mark()
10
+ inline void WrapperBase::ruby_mark()
10
11
  {
11
12
  for (VALUE value : this->keepAlive_)
12
13
  {
@@ -14,133 +15,122 @@ namespace Rice::detail
14
15
  }
15
16
  }
16
17
 
17
- inline void Wrapper::addKeepAlive(VALUE value)
18
+ inline void WrapperBase::addKeepAlive(VALUE value)
18
19
  {
19
20
  this->keepAlive_.push_back(value);
20
21
  }
21
22
 
22
- inline void Wrapper::setOwner(bool value)
23
+ inline void WrapperBase::setOwner(bool value)
23
24
  {
24
25
  this->isOwner_ = value;
25
26
  }
26
27
 
28
+ // ---- Wrapper -----
27
29
  template <typename T>
28
- class WrapperValue : public Wrapper
30
+ inline Wrapper<T>::Wrapper(T& data): data_(data)
29
31
  {
30
- public:
31
- WrapperValue(T& data): data_(std::move(data))
32
- {
33
- }
34
-
35
- ~WrapperValue()
36
- {
37
- Registries::instance.instances.remove(this->get());
38
- }
32
+ }
39
33
 
40
- void* get() override
41
- {
42
- return (void*)&this->data_;
43
- }
34
+ template <typename T>
35
+ inline Wrapper<T>::Wrapper(T&& data) : data_(std::move(data))
36
+ {
37
+ }
44
38
 
45
- private:
46
- T data_;
47
- };
39
+ template <typename T>
40
+ inline Wrapper<T>::~Wrapper()
41
+ {
42
+ Registries::instance.instances.remove(this->get());
43
+ }
48
44
 
49
45
  template <typename T>
50
- class WrapperReference : public Wrapper
46
+ inline void* Wrapper<T>::Wrapper::get()
51
47
  {
52
- public:
53
- WrapperReference(T& data): data_(data)
54
- {
55
- }
48
+ return (void*)&this->data_;
49
+ }
56
50
 
57
- ~WrapperReference()
58
- {
59
- Registries::instance.instances.remove(this->get());
60
- }
51
+ // ---- Wrapper& -----
52
+ template <typename T>
53
+ inline Wrapper<T&>::Wrapper(T& data): data_(data)
54
+ {
55
+ this->isConst_ = std::is_const_v<std::remove_reference_t<T>>;
56
+ }
61
57
 
62
- void* get() override
63
- {
64
- return (void*)&this->data_;
65
- }
58
+ template <typename T>
59
+ inline Wrapper<T&>::~Wrapper()
60
+ {
61
+ Registries::instance.instances.remove(this->get());
62
+ }
66
63
 
67
- private:
68
- T& data_;
69
- };
64
+ template <typename T>
65
+ inline void* Wrapper<T&>::get()
66
+ {
67
+ return (void*)&this->data_;
68
+ }
70
69
 
70
+ // ---- Wrapper* -----
71
71
  template <typename T>
72
- class WrapperPointer : public Wrapper
72
+ inline Wrapper<T*>::Wrapper(T* data, bool isOwner) : data_(data)
73
73
  {
74
- public:
75
- WrapperPointer(T* data, bool isOwner) : Wrapper(isOwner), data_(data)
76
- {
77
- }
74
+ this->isOwner_ = isOwner;
75
+ this->isConst_ = std::is_const_v<std::remove_pointer_t<T>>;
76
+ }
78
77
 
79
- ~WrapperPointer()
78
+ template <typename T>
79
+ inline Wrapper<T*>::~Wrapper()
80
+ {
81
+ Registries::instance.instances.remove(this->get());
82
+ if constexpr (std::is_destructible_v<T>)
80
83
  {
81
- Registries::instance.instances.remove(this->get());
82
-
83
- if constexpr (std::is_destructible_v<T>)
84
+ if (this->isOwner_)
84
85
  {
85
- if (this->isOwner_)
86
- {
87
- delete this->data_;
88
- }
86
+ delete this->data_;
89
87
  }
90
88
  }
89
+ }
91
90
 
92
- void* get() override
93
- {
94
- return (void*)this->data_;
95
- }
96
-
97
- private:
98
- T* data_ = nullptr;
99
- };
91
+ template <typename T>
92
+ inline void* Wrapper<T*>::get()
93
+ {
94
+ return (void*)this->data_;
95
+ }
100
96
 
101
97
  // ---- Helper Functions -------
102
- template <typename T, typename Wrapper_T>
103
- inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T& data, bool isOwner)
98
+ template <typename T>
99
+ inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner)
104
100
  {
105
101
  VALUE result = Registries::instance.instances.lookup(&data);
106
102
 
107
103
  if (result != Qnil)
108
104
  return result;
109
105
 
110
- Wrapper* wrapper = nullptr;
106
+ WrapperBase* wrapper = nullptr;
111
107
 
112
- // Is this a pointer but cannot be copied? For example a std::unique_ptr
113
- if constexpr (!std::is_void_v<Wrapper_T> && !std::is_copy_constructible_v<Wrapper_T>)
108
+ // If Ruby is not the owner then wrap the reference
109
+ if (!isOwner)
114
110
  {
115
- wrapper = new Wrapper_T(std::move(data));
116
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
111
+ wrapper = new Wrapper<T&>(data);
112
+ result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
117
113
  }
118
- // Is this a pointer or smart pointer like std::shared_ptr
119
- else if constexpr (!std::is_void_v<Wrapper_T>)
114
+
115
+ // Ruby is the owner so copy data
116
+ else if constexpr (std::is_copy_constructible_v<T>)
120
117
  {
121
- wrapper = new Wrapper_T(data);
122
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
118
+ wrapper = new Wrapper<T>(data);
119
+ result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
123
120
  }
124
- // If ruby is the owner than copy the object if possible
125
- else if (isOwner)
121
+
122
+ // Ruby is the owner so move data
123
+ else if constexpr (std::is_move_constructible_v<T>)
126
124
  {
127
- if constexpr (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>)
128
- {
129
- wrapper = new WrapperValue<T>(data);
130
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
131
- }
132
- else
133
- {
134
- std::string message = "Ruby was directed to take ownership of a C++ object but it does not have an accessible copy or move constructor. Type: " +
135
- typeName(typeid(T));
136
- throw std::runtime_error(message);
137
- }
125
+ wrapper = new Wrapper<T>(std::forward<T>(data));
126
+ result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
138
127
  }
139
- // Ruby is not the owner so just wrap the reference
128
+
140
129
  else
141
130
  {
142
- wrapper = new WrapperReference<T>(data);
143
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
131
+ std::string message = "Rice was directed to take ownership of a C++ object but it does not have an accessible copy or move constructor. Type: " +
132
+ typeName(typeid(T));
133
+ throw std::runtime_error(message);
144
134
  }
145
135
 
146
136
  Registries::instance.instances.add(wrapper->get(), result);
@@ -148,37 +138,31 @@ namespace Rice::detail
148
138
  return result;
149
139
  };
150
140
 
151
- template <typename T, typename Wrapper_T>
152
- inline VALUE wrap(VALUE klass, rb_data_type_t* rb_type, T* data, bool isOwner)
141
+ template <typename T>
142
+ inline VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T* data, bool isOwner)
153
143
  {
154
144
  VALUE result = Registries::instance.instances.lookup(data);
155
145
 
156
146
  if (result != Qnil)
157
147
  return result;
158
148
 
159
- Wrapper* wrapper = nullptr;
160
-
161
- if constexpr (!std::is_void_v<Wrapper_T>)
162
- {
163
- wrapper = new Wrapper_T(data);
164
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
165
- }
166
- else
167
- {
168
- wrapper = new WrapperPointer<T>(data, isOwner);
169
- result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
170
- }
149
+ WrapperBase* wrapper = new Wrapper<T*>(data, isOwner);
150
+ result = TypedData_Wrap_Struct(klass, rb_data_type, wrapper);
171
151
 
172
152
  Registries::instance.instances.add(wrapper->get(), result);
173
153
  return result;
174
154
  };
175
155
 
176
156
  template <typename T>
177
- inline T* unwrap(VALUE value, rb_data_type_t* rb_type, bool takeOwnership)
157
+ inline T* unwrap(VALUE value, rb_data_type_t* rb_data_type, bool takeOwnership)
178
158
  {
179
- Wrapper* wrapper = getWrapper(value, rb_type);
180
- if (takeOwnership)
181
- wrapper->setOwner(false);
159
+ if (rb_type(value) != RUBY_T_DATA)
160
+ {
161
+ std::string message = "The provided Ruby object does not wrap a C++ object";
162
+ throw std::runtime_error(message);
163
+ }
164
+
165
+ WrapperBase* wrapper = getWrapper(value, rb_data_type);
182
166
 
183
167
  if (wrapper == nullptr)
184
168
  {
@@ -189,17 +173,21 @@ namespace Rice::detail
189
173
  throw std::runtime_error(message);
190
174
  }
191
175
 
176
+ if (takeOwnership)
177
+ wrapper->setOwner(false);
178
+
192
179
  return static_cast<T*>(wrapper->get());
193
180
  }
194
181
 
195
- inline Wrapper* getWrapper(VALUE value, rb_data_type_t* rb_type)
182
+ template <typename Wrapper_T>
183
+ inline Wrapper_T* getWrapper(VALUE value, rb_data_type_t* rb_data_type)
196
184
  {
197
- Wrapper* wrapper = nullptr;
198
- TypedData_Get_Struct(value, Wrapper, rb_type, wrapper);
199
- return wrapper;
185
+ WrapperBase* wrapper = nullptr;
186
+ TypedData_Get_Struct(value, WrapperBase, rb_data_type, wrapper);
187
+ return dynamic_cast<Wrapper_T*>(wrapper);
200
188
  }
201
189
 
202
- inline Wrapper* getWrapper(VALUE value)
190
+ inline WrapperBase* getWrapper(VALUE value)
203
191
  {
204
192
  // Turn off spurious warning on g++ 12
205
193
  #if defined(__GNUC__) || defined(__clang__)
@@ -207,7 +195,7 @@ namespace Rice::detail
207
195
  #pragma GCC diagnostic ignored "-Warray-bounds"
208
196
  #endif
209
197
 
210
- return RTYPEDDATA_P(value) ? static_cast<Wrapper*>(RTYPEDDATA_DATA(value)) : nullptr;
198
+ return RTYPEDDATA_P(value) ? static_cast<WrapperBase*>(RTYPEDDATA_DATA(value)) : nullptr;
211
199
 
212
200
  #if defined(__GNUC__) || defined(__clang__)
213
201
  #pragma GCC diagnostic pop
@@ -215,17 +203,19 @@ namespace Rice::detail
215
203
  }
216
204
 
217
205
  template <typename T>
218
- inline void replace(VALUE value, rb_data_type_t* rb_type, T* data, bool isOwner)
206
+ inline void wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data, bool isOwner)
219
207
  {
220
- WrapperPointer<T>* wrapper = nullptr;
221
- TypedData_Get_Struct(value, WrapperPointer<T>, rb_type, wrapper);
208
+ using Wrapper_T = Wrapper<T*>;
209
+
210
+ Wrapper_T* wrapper = nullptr;
211
+ TypedData_Get_Struct(value, Wrapper_T, rb_data_type, wrapper);
222
212
  if (wrapper)
223
213
  {
224
214
  Registries::instance.instances.remove(wrapper->get());
225
215
  delete wrapper;
226
216
  }
227
217
 
228
- wrapper = new WrapperPointer<T>(data, isOwner);
218
+ wrapper = new Wrapper_T(data, true);
229
219
  RTYPEDDATA_DATA(value) = wrapper;
230
220
 
231
221
  Registries::instance.instances.add(data, value);
@@ -32,10 +32,11 @@ namespace Rice::detail
32
32
 
33
33
  enum class Convertible: uint8_t
34
34
  {
35
- None = 0b000,
36
- Narrowable = 0b001,
37
- Cast = 0b011,
38
- Exact = 0b111,
35
+ None = 0b0000,
36
+ Narrow = 0b0001,
37
+ Cast = 0b0011,
38
+ Const = 0b0111,
39
+ Exact = 0b1111
39
40
  };
40
41
  }
41
42