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
@@ -19,6 +19,10 @@ namespace Rice
19
19
  template<typename T>
20
20
  constexpr bool is_const_any_v = std::is_const_v<std::remove_pointer_t<std::remove_pointer_t<std::remove_reference_t<T>>>>;
21
21
 
22
+ // Helper to detect char types
23
+ template<typename T>
24
+ constexpr bool is_char_type_v = std::is_same_v<T, char> || std::is_same_v<T, signed char> || std::is_same_v<T, unsigned char>;
25
+
22
26
  // Recursively remove const/volatile
23
27
  template<typename T>
24
28
  struct remove_cv_recursive
@@ -109,45 +113,6 @@ namespace Rice
109
113
  template <typename T>
110
114
  constexpr bool is_std_vector_v = is_std_vector<T>::value;
111
115
 
112
-
113
- // -- Tuple Helpers ---
114
- template<typename T>
115
- struct tuple_shift;
116
-
117
- template<typename T, typename...Arg_Ts>
118
- struct tuple_shift<std::tuple<T, Arg_Ts...>>
119
- {
120
- using type = std::tuple<Arg_Ts...>;
121
- };
122
-
123
- template<typename T, typename...Arg_Ts>
124
- struct tuple_unshift;
125
-
126
- template<typename T, typename...Arg_Ts>
127
- struct tuple_unshift<T, std::tuple<Arg_Ts...>>
128
- {
129
- using type = std::tuple<T, Arg_Ts...>;
130
- };
131
-
132
- template<template<typename, typename...> typename T, typename...Arg_Ts>
133
- struct tuple_map;
134
-
135
- template<template<typename, typename...> typename T, typename...Arg_Ts>
136
- struct tuple_map<T, std::tuple<Arg_Ts...>>
137
- {
138
- using type = std::tuple<T<Arg_Ts>...>;
139
- };
140
-
141
-
142
- template<typename...Arg_Ts>
143
- struct tuple_to_variant;
144
-
145
- template<typename...Arg_Ts>
146
- struct tuple_to_variant<std::tuple<Arg_Ts...>>
147
- {
148
- using type = std::variant<Arg_Ts...>;
149
- };
150
-
151
116
  template<class T>
152
117
  struct is_pointer_pointer : std::false_type {};
153
118
 
@@ -186,6 +151,164 @@ namespace Rice
186
151
 
187
152
  template<typename T>
188
153
  constexpr bool is_wrapped_v = is_wrapped<T>::value;
154
+
155
+ // -- Tuple Helpers ---
156
+ template<typename T>
157
+ struct tuple_shift;
158
+
159
+ template<typename T, typename...Parameter_Ts>
160
+ struct tuple_shift<std::tuple<T, Parameter_Ts...>>
161
+ {
162
+ using type = std::tuple<Parameter_Ts...>;
163
+ };
164
+
165
+ template<typename T, typename...Parameter_Ts>
166
+ struct tuple_unshift;
167
+
168
+ template<typename T, typename...Parameter_Ts>
169
+ struct tuple_unshift<T, std::tuple<Parameter_Ts...>>
170
+ {
171
+ using type = std::tuple<T, Parameter_Ts...>;
172
+ };
173
+
174
+ template<template<typename, typename...> typename T, typename...Parameter_Ts>
175
+ struct tuple_map;
176
+
177
+ template<template<typename, typename...> typename T, typename...Parameter_Ts>
178
+ struct tuple_map<T, std::tuple<Parameter_Ts...>>
179
+ {
180
+ using type = std::tuple<T<Parameter_Ts>...>;
181
+ };
182
+
183
+ template<typename...Parameter_Ts>
184
+ struct tuple_to_variant;
185
+
186
+ template<typename...Parameter_Ts>
187
+ struct tuple_to_variant<std::tuple<Parameter_Ts...>>
188
+ {
189
+ using type = std::variant<Parameter_Ts...>;
190
+ };
191
+
192
+ template <typename T, typename... List>
193
+ struct is_one_of : std::disjunction<std::is_same<T, List>...> {};
194
+
195
+ template <typename T, typename... List>
196
+ constexpr bool is_one_of_v = is_one_of<T, List...>::value;
197
+
198
+ template<typename... FilterTypes, typename... Arg_Ts>
199
+ auto tuple_filter(const Arg_Ts&... args)
200
+ {
201
+ return std::tuple_cat([&args]()
202
+ {
203
+ if constexpr (is_one_of_v<Arg_Ts, FilterTypes...>)
204
+ {
205
+ return std::tuple<const Arg_Ts&>(args);
206
+ }
207
+ else
208
+ {
209
+ return std::tuple<>();
210
+ }
211
+ }()...);
212
+ };
213
+
214
+ // --- filter_types: recursively builds a new tuple of allowed types ---
215
+ template <typename Tuple, typename... Allowed>
216
+ struct tuple_filter_types;
217
+
218
+ template <typename... Ts, typename... Allowed>
219
+ struct tuple_filter_types<std::tuple<Ts...>, Allowed...>
220
+ {
221
+ using type = decltype(std::tuple_cat(std::declval<
222
+ std::conditional_t<is_one_of_v<std::decay_t<Ts>, Allowed...>, std::tuple<Ts>, std::tuple<>>>()...));
223
+ };
224
+
225
+ template <typename Tuple, typename... Allowed>
226
+ using tuple_filter_types_t = typename tuple_filter_types<Tuple, Allowed...>::type;
227
+
228
+ template <typename T, std::size_t... Is>
229
+ auto vector_to_tuple(const std::vector<T>& vec, std::index_sequence<Is...>)
230
+ {
231
+ return std::make_tuple(vec[Is]...);
232
+ }
233
+
234
+ template <typename Tuple, typename T, typename Seq>
235
+ struct tuple_pad_type;
236
+
237
+ template <typename... Ts, typename T, std::size_t... Is>
238
+ struct tuple_pad_type<std::tuple<Ts...>, T, std::index_sequence<Is...>>
239
+ {
240
+ // Use Is only to repeat T N times.
241
+ // std::conditional_t<true, T, something<Is>> is always T, but expands N times.
242
+ using type = std::tuple<
243
+ Ts...,
244
+ std::conditional_t<true, T, std::integral_constant<std::size_t, Is>>...
245
+ >;
246
+ };
247
+
248
+ template <typename Tuple, typename T, std::size_t N>
249
+ using tuple_pad_type_t = typename tuple_pad_type<Tuple, T, std::make_index_sequence<N>>::type;
250
+
251
+ // Pad tuple with values from a vector (vector size must match N)
252
+ template <std::size_t N, typename T, typename... Ts>
253
+ auto pad_tuple(const std::tuple<Ts...>& original, const std::vector<T>& padding)
254
+ {
255
+ if (padding.size() != N)
256
+ {
257
+ throw std::invalid_argument("Vector size doesn't match template parameter N");
258
+ }
259
+
260
+ auto padding_tuple = vector_to_tuple(padding, std::make_index_sequence<N>{});
261
+ return std::tuple_cat(original, padding_tuple);
262
+ }
263
+
264
+ template <typename Tuple, typename... Ts>
265
+ struct tuple_element_index_impl;
266
+
267
+ template <typename... Ts>
268
+ struct tuple_element_index_impl<std::tuple<>, Ts...>
269
+ {
270
+ static constexpr std::size_t value = 0;
271
+ };
272
+
273
+ template <typename First, typename... Rest, typename... Ts>
274
+ struct tuple_element_index_impl<std::tuple<First, Rest...>, Ts...>
275
+ {
276
+ static constexpr bool matches = (std::is_same_v<std::decay_t<First>, Ts> || ...);
277
+ static constexpr std::size_t value =
278
+ matches ? 0 : 1 + tuple_element_index_impl<std::tuple<Rest...>, Ts...>::value;
279
+ };
280
+
281
+ template <typename Tuple, typename... Ts>
282
+ struct tuple_element_index
283
+ {
284
+ static constexpr std::size_t value = tuple_element_index_impl<Tuple, Ts...>::value;
285
+ };
286
+
287
+ template <typename Tuple, typename... Ts>
288
+ inline constexpr std::size_t tuple_element_index_v = tuple_element_index<Tuple, Ts...>::value;
289
+
290
+ /* template<typename Target, typename T>
291
+ constexpr auto tuple_predicate(T&& element)
292
+ {
293
+ using U = std::decay_t<T>;
294
+ if constexpr (std::is_same_v<U, Target>)
295
+ {
296
+ return std::tuple<U>{ std::forward<T>(element) };
297
+ }
298
+ else
299
+ {
300
+ return std::tuple<>{};
301
+ }
302
+ }
303
+
304
+ template<typename Class_T, typename... Ts>
305
+ constexpr auto tuple_filter(Ts&&... args)
306
+ {
307
+ return std::tuple_cat(tuple_predicate<Class_T>(std::forward<Ts>(args))...);
308
+ }*/
309
+
310
+
311
+
189
312
  } // detail
190
313
  } // Rice
191
314
 
data/rice.gemspec CHANGED
@@ -48,9 +48,7 @@ Ruby extensions with C++ easier.
48
48
  'FindRuby.cmake',
49
49
 
50
50
  # Include files
51
- 'include/rice/rice.hpp',
52
- 'include/rice/stl.hpp',
53
- 'include/rice/ruby-api.hpp',
51
+ 'include/rice/*.hpp',
54
52
 
55
53
  # Bin files
56
54
  'bin/rice-rbs.rb',
@@ -67,7 +65,6 @@ Ruby extensions with C++ easier.
67
65
  ]
68
66
 
69
67
  s.required_ruby_version = ">= 3.1"
70
- s.add_dependency "ostruct"
71
68
  s.add_development_dependency "bundler"
72
69
  s.add_development_dependency "rake"
73
70
  s.add_development_dependency "minitest"
data/test/test_Array.cpp CHANGED
@@ -2,6 +2,8 @@
2
2
  #include "embed_ruby.hpp"
3
3
  #include <rice/rice.hpp>
4
4
 
5
+ #include <algorithm>
6
+ #include <iterator>
5
7
  #include <vector>
6
8
 
7
9
  using namespace Rice;
@@ -235,9 +237,9 @@ TESTCASE(iterate_and_call_member)
235
237
  Array::iterator it = a.begin();
236
238
  Array::iterator end = a.end();
237
239
  std::vector<Object> v;
238
- for(int j = 0; it != end; ++j, ++it)
240
+ for(const auto& item: a)
239
241
  {
240
- v.push_back(it->to_s());
242
+ v.push_back(Object(item).to_s());
241
243
  }
242
244
  ASSERT_EQUAL(42, detail::From_Ruby<int>().convert(a[0].value()));
243
245
  ASSERT_EQUAL(43, detail::From_Ruby<int>().convert(a[1].value()));
@@ -278,7 +280,7 @@ TESTCASE(assign_int)
278
280
 
279
281
  namespace
280
282
  {
281
- void testArrayArg(Object self, Array string)
283
+ void testArrayArg(Object, Array)
282
284
  {
283
285
  }
284
286
  }
@@ -313,3 +315,259 @@ TESTCASE(array_from_ruby)
313
315
  Array a(rb_ary_new());
314
316
  ASSERT_EQUAL(a, detail::From_Ruby<Array>().convert(a));
315
317
  }
318
+
319
+ // Random-access iterator tests
320
+ TESTCASE(iterator_random_access_category)
321
+ {
322
+ // Verify the iterator is now a random-access iterator
323
+ static_assert(std::is_same_v<
324
+ Array::iterator::iterator_category,
325
+ std::random_access_iterator_tag>,
326
+ "Array::iterator should be a random_access_iterator");
327
+
328
+ static_assert(std::is_same_v<
329
+ Array::const_iterator::iterator_category,
330
+ std::random_access_iterator_tag>,
331
+ "Array::const_iterator should be a random_access_iterator");
332
+ }
333
+
334
+ TESTCASE(iterator_arithmetic_add)
335
+ {
336
+ Array a;
337
+ a.push(10, false);
338
+ a.push(20, false);
339
+ a.push(30, false);
340
+ a.push(40, false);
341
+ a.push(50, false);
342
+
343
+ Array::iterator it = a.begin();
344
+ Array::iterator it2 = it + 2;
345
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(it2->value()));
346
+
347
+ it2 = 3 + it; // Test non-member operator+
348
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(it2->value()));
349
+ }
350
+
351
+ TESTCASE(iterator_arithmetic_subtract)
352
+ {
353
+ Array a;
354
+ a.push(10, false);
355
+ a.push(20, false);
356
+ a.push(30, false);
357
+ a.push(40, false);
358
+ a.push(50, false);
359
+
360
+ Array::iterator it = a.end();
361
+ Array::iterator it2 = it - 2;
362
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(it2->value()));
363
+ }
364
+
365
+ TESTCASE(iterator_compound_assignment)
366
+ {
367
+ Array a;
368
+ a.push(10, false);
369
+ a.push(20, false);
370
+ a.push(30, false);
371
+ a.push(40, false);
372
+ a.push(50, false);
373
+
374
+ Array::iterator it = a.begin();
375
+ it += 3;
376
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(it->value()));
377
+
378
+ it -= 2;
379
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(it->value()));
380
+ }
381
+
382
+ TESTCASE(iterator_difference)
383
+ {
384
+ Array a;
385
+ a.push(10, false);
386
+ a.push(20, false);
387
+ a.push(30, false);
388
+ a.push(40, false);
389
+ a.push(50, false);
390
+
391
+ Array::iterator begin = a.begin();
392
+ Array::iterator end = a.end();
393
+ ASSERT_EQUAL(5, end - begin);
394
+ ASSERT_EQUAL(-5, begin - end);
395
+
396
+ Array::iterator mid = begin + 2;
397
+ ASSERT_EQUAL(2, mid - begin);
398
+ ASSERT_EQUAL(3, end - mid);
399
+ }
400
+
401
+ TESTCASE(iterator_subscript)
402
+ {
403
+ Array a;
404
+ a.push(10, false);
405
+ a.push(20, false);
406
+ a.push(30, false);
407
+ a.push(40, false);
408
+ a.push(50, false);
409
+
410
+ Array::iterator it = a.begin();
411
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(it[0].value()));
412
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(it[2].value()));
413
+ ASSERT_EQUAL(50, detail::From_Ruby<int>().convert(it[4].value()));
414
+ }
415
+
416
+ TESTCASE(iterator_comparison_less_greater)
417
+ {
418
+ Array a;
419
+ a.push(10, false);
420
+ a.push(20, false);
421
+ a.push(30, false);
422
+
423
+ Array::iterator begin = a.begin();
424
+ Array::iterator mid = begin + 1;
425
+ Array::iterator end = a.end();
426
+
427
+ ASSERT_EQUAL(true, begin < mid);
428
+ ASSERT_EQUAL(true, begin < end);
429
+ ASSERT_EQUAL(true, mid < end);
430
+
431
+ ASSERT_EQUAL(true, end > mid);
432
+ ASSERT_EQUAL(true, end > begin);
433
+ ASSERT_EQUAL(true, mid > begin);
434
+
435
+ ASSERT_EQUAL(true, begin <= begin);
436
+ ASSERT_EQUAL(true, begin <= mid);
437
+ ASSERT_EQUAL(true, mid <= end);
438
+
439
+ ASSERT_EQUAL(true, end >= end);
440
+ ASSERT_EQUAL(true, end >= mid);
441
+ ASSERT_EQUAL(true, mid >= begin);
442
+ }
443
+
444
+ TESTCASE(iterator_decrement)
445
+ {
446
+ Array a;
447
+ a.push(10, false);
448
+ a.push(20, false);
449
+ a.push(30, false);
450
+
451
+ Array::iterator it = a.end();
452
+ --it;
453
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(it->value()));
454
+ --it;
455
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(it->value()));
456
+ --it;
457
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(it->value()));
458
+ }
459
+
460
+ TESTCASE(iterator_decrement_postfix)
461
+ {
462
+ Array a;
463
+ a.push(10, false);
464
+ a.push(20, false);
465
+ a.push(30, false);
466
+
467
+ Array::iterator it = a.end();
468
+ it--;
469
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(it->value()));
470
+ Array::iterator prev = it--;
471
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(prev->value()));
472
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(it->value()));
473
+ }
474
+
475
+ TESTCASE(iterator_std_sort)
476
+ {
477
+ // std::sort requires iterators that return assignable references.
478
+ // Our iterator returns a Proxy which supports assignment to the array,
479
+ // but STL algorithms need iter_swap to work. Test that we can use
480
+ // std::sort with explicit swap via indices instead.
481
+ Array a;
482
+ a.push(30, false);
483
+ a.push(10, false);
484
+ a.push(50, false);
485
+ a.push(20, false);
486
+ a.push(40, false);
487
+
488
+ // Manual sort using random-access capabilities (bubble sort for simplicity)
489
+ for (long i = 0; i < a.size() - 1; i++)
490
+ {
491
+ for (long j = 0; j < a.size() - i - 1; j++)
492
+ {
493
+ auto it = a.begin();
494
+ int val1 = detail::From_Ruby<int>().convert(it[j].value());
495
+ int val2 = detail::From_Ruby<int>().convert(it[j + 1].value());
496
+ if (val1 > val2)
497
+ {
498
+ // Swap using array subscript operator
499
+ Object temp = a[j];
500
+ a[j] = detail::From_Ruby<int>().convert(a[j + 1].value());
501
+ a[j + 1] = detail::From_Ruby<int>().convert(temp.value());
502
+ }
503
+ }
504
+ }
505
+
506
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(a[0].value()));
507
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(a[1].value()));
508
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(a[2].value()));
509
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(a[3].value()));
510
+ ASSERT_EQUAL(50, detail::From_Ruby<int>().convert(a[4].value()));
511
+ }
512
+
513
+ TESTCASE(iterator_std_reverse)
514
+ {
515
+ // std::reverse requires iter_swap support. Test manual reverse using
516
+ // random-access iterator capabilities instead.
517
+ Array a;
518
+ a.push(10, false);
519
+ a.push(20, false);
520
+ a.push(30, false);
521
+ a.push(40, false);
522
+ a.push(50, false);
523
+
524
+ // Manual reverse using random-access capabilities
525
+ auto begin = a.begin();
526
+ auto end = a.end() - 1;
527
+ while (begin < end)
528
+ {
529
+ long i = begin.index();
530
+ long j = end.index();
531
+ Object temp = a[i];
532
+ a[i] = detail::From_Ruby<int>().convert(a[j].value());
533
+ a[j] = detail::From_Ruby<int>().convert(temp.value());
534
+ ++begin;
535
+ --end;
536
+ }
537
+
538
+ ASSERT_EQUAL(50, detail::From_Ruby<int>().convert(a[0].value()));
539
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(a[1].value()));
540
+ ASSERT_EQUAL(30, detail::From_Ruby<int>().convert(a[2].value()));
541
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(a[3].value()));
542
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(a[4].value()));
543
+ }
544
+
545
+ TESTCASE(iterator_std_distance)
546
+ {
547
+ Array a;
548
+ a.push(10, false);
549
+ a.push(20, false);
550
+ a.push(30, false);
551
+ a.push(40, false);
552
+ a.push(50, false);
553
+
554
+ ASSERT_EQUAL(5, std::distance(a.begin(), a.end()));
555
+ ASSERT_EQUAL(3, std::distance(a.begin() + 1, a.begin() + 4));
556
+ }
557
+
558
+ TESTCASE(iterator_std_advance)
559
+ {
560
+ Array a;
561
+ a.push(10, false);
562
+ a.push(20, false);
563
+ a.push(30, false);
564
+ a.push(40, false);
565
+ a.push(50, false);
566
+
567
+ Array::iterator it = a.begin();
568
+ std::advance(it, 3);
569
+ ASSERT_EQUAL(40, detail::From_Ruby<int>().convert(it->value()));
570
+
571
+ std::advance(it, -2);
572
+ ASSERT_EQUAL(20, detail::From_Ruby<int>().convert(it->value()));
573
+ }
@@ -28,6 +28,9 @@ namespace
28
28
 
29
29
  class NotAssignable
30
30
  {
31
+ public:
32
+ NotAssignable() = default;
33
+ NotAssignable(const NotAssignable&) = default;
31
34
  NotAssignable& operator=(const NotAssignable&) = delete;
32
35
  };
33
36
 
@@ -35,7 +38,7 @@ namespace
35
38
  {
36
39
  public:
37
40
  NotCopyable() = default;
38
- NotCopyable(const NotCopyable& other) = delete;
41
+ NotCopyable(const NotCopyable&) = delete;
39
42
  };
40
43
 
41
44
  enum OldEnum
@@ -453,7 +456,7 @@ TESTCASE(BufferAttribute)
453
456
 
454
457
  Class c = define_class<BufferAttrs>("BufferAttrs")
455
458
  .define_constructor(Constructor<BufferAttrs>())
456
- .define_attr("buffer", &BufferAttrs::buffer, Rice::AttrAccess::Read, Return().setBuffer());
459
+ .define_attr("buffer", &BufferAttrs::buffer, Rice::AttrAccess::Read, ReturnBuffer());
457
460
 
458
461
  std::string code = R"(struct = BufferAttrs.new
459
462
  struct.buffer.class)";
@@ -487,7 +490,7 @@ TESTCASE(CounterBufferAttribute)
487
490
 
488
491
  define_class<BufferAttrs>("BufferAttrs")
489
492
  .define_constructor(Constructor<BufferAttrs>())
490
- .define_attr("counters_buffer", &BufferAttrs::countersBuffer, Rice::AttrAccess::Read, Return().setBuffer());
493
+ .define_attr("counters_buffer", &BufferAttrs::countersBuffer, Rice::AttrAccess::Read, ReturnBuffer());
491
494
 
492
495
  std::string code = R"(struct = BufferAttrs.new
493
496
  struct.counters_buffer.class)";
data/test/test_Buffer.cpp CHANGED
@@ -255,8 +255,8 @@ namespace
255
255
  TESTCASE(pointer_of_doubles)
256
256
  {
257
257
  Module m = define_module("Testing").
258
- define_module_function("speeds", &speeds, Return().setBuffer()).
259
- define_module_function("speeds_ptr", &speedsPtr, Return().setBuffer());
258
+ define_module_function("speeds", &speeds, ReturnBuffer()).
259
+ define_module_function("speeds_ptr", &speedsPtr, ReturnBuffer());
260
260
 
261
261
  std::string code = R"(buffer = Rice::Buffer≺double≻.new(speeds, 3)
262
262
  buffer[2])";
@@ -275,48 +275,12 @@ TESTCASE(pointer_of_doubles)
275
275
 
276
276
  namespace
277
277
  {
278
- void updateRef(int& ref)
279
- {
280
- ref = 4;
281
- }
282
-
283
278
  void updatePtr(int* ptr)
284
279
  {
285
280
  *ptr = 5;
286
281
  }
287
282
  }
288
283
 
289
- TESTCASE(update_reference)
290
- {
291
- define_buffer<int>();
292
- Module m = define_module("Testing");
293
- m.define_module_function("update_reference", &updateRef);
294
-
295
- std::string code = R"(buffer = Rice::Buffer≺int≻.new(0)
296
- update_reference(buffer.data)
297
- buffer.to_ary(1).first)";
298
-
299
- Object result = m.module_eval(code);
300
- ASSERT_EQUAL(4, detail::From_Ruby<int>().convert(result));
301
-
302
- code = R"(buffer = Rice::Buffer≺int≻.new(0)
303
- update_reference(buffer.data)
304
- buffer[0])";
305
-
306
- result = m.module_eval(code);
307
- ASSERT_EQUAL(4, detail::From_Ruby<int>().convert(result));
308
-
309
- code = R"(buffer = Rice::Buffer≺int≻.new(0)
310
- update_reference(buffer.data)
311
- buffer[1])";
312
-
313
- ASSERT_EXCEPTION_CHECK(
314
- Exception,
315
- m.module_eval(code),
316
- ASSERT_EQUAL("index 1 outside of bounds: 0..1", ex.what())
317
- );
318
- }
319
-
320
284
  TESTCASE(update_ptr)
321
285
  {
322
286
  define_buffer<int>();
@@ -492,8 +456,8 @@ TESTCASE(pointer_of_objects)
492
456
  define_buffer<MyClassBuf*>();
493
457
 
494
458
  Module m = define_module("Testing").
495
- define_module_function("class_buffs", &classBufs).
496
- define_module_function("class_buffs_ptr", &classBufsPtr);
459
+ define_module_function("class_buffs", &classBufs, ReturnBuffer()).
460
+ define_module_function("class_buffs_ptr", &classBufsPtr, ReturnBuffer());
497
461
 
498
462
  define_class<MyClassBuf>("MyClassBuf").
499
463
  define_constructor(Constructor<MyClassBuf, int>()).
@@ -593,8 +557,8 @@ TESTCASE(array_of_objects_ptr)
593
557
  TESTCASE(pass_objects)
594
558
  {
595
559
  Module m = define_module("Testing");
596
- m.define_module_function<size_t(*)(const MyClassBuf*, size_t)>("sum_ids", &sumIds, Arg("myClasses").setBuffer());
597
- m.define_module_function<size_t(*)(const MyClassBuf**, size_t)>("sum_ids_ptr", &sumIds);
560
+ m.define_module_function<size_t(*)(const MyClassBuf*, size_t)>("sum_ids", &sumIds, ArgBuffer("myClasses"));
561
+ m.define_module_function<size_t(*)(const MyClassBuf**, size_t)>("sum_ids_ptr", &sumIds, ArgBuffer("myClasses"));
598
562
 
599
563
  define_class_under<MyClassBuf>(m, "MyClassBuf").
600
564
  define_constructor(Constructor<MyClassBuf, int>()).