rice 4.6.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.
data/rice/Buffer.ipp CHANGED
@@ -2,30 +2,42 @@ namespace Rice
2
2
  {
3
3
  // ---- Buffer<T> -------
4
4
  template<typename T>
5
- inline Buffer<T>::Buffer(T* pointer) : m_buffer(pointer)
5
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(T* pointer) : m_buffer(pointer)
6
6
  {
7
7
  }
8
8
 
9
9
  template<typename T>
10
- inline Buffer<T>::Buffer(T* pointer, size_t size) : m_size(size), m_buffer(pointer)
10
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(T* pointer, size_t size) : m_size(size), m_buffer(pointer)
11
11
  {
12
12
  }
13
13
 
14
14
  template <typename T>
15
- inline Buffer<T>::Buffer(VALUE value)
15
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(VALUE value)
16
16
  {
17
17
  if constexpr (std::is_fundamental_v<T>)
18
18
  {
19
- this->fromRubyType(value);
19
+ this->fromBuiltinType(value);
20
20
  }
21
21
  else
22
22
  {
23
- this->fromDataType(value);
23
+ this->fromWrappedType(value);
24
24
  }
25
25
  }
26
26
 
27
27
  template <typename T>
28
- inline void Buffer<T>::fromRubyType(VALUE value)
28
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::~Buffer()
29
+ {
30
+ if constexpr (std::is_destructible_v<T>)
31
+ {
32
+ if (this->m_owner)
33
+ {
34
+ delete[] this->m_buffer;
35
+ }
36
+ }
37
+ }
38
+
39
+ template <typename T>
40
+ inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::fromBuiltinType(VALUE value)
29
41
  {
30
42
  using Intrinsic_T = typename detail::intrinsic_type<T>;
31
43
  using RubyType_T = typename detail::RubyType<Intrinsic_T>;
@@ -97,7 +109,7 @@ namespace Rice
97
109
  }
98
110
 
99
111
  template <typename T>
100
- inline void Buffer<T>::fromDataType(VALUE value)
112
+ inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::fromWrappedType(VALUE value)
101
113
  {
102
114
  using Intrinsic_T = typename detail::intrinsic_type<T>;
103
115
 
@@ -129,19 +141,7 @@ namespace Rice
129
141
  }
130
142
 
131
143
  template <typename T>
132
- inline Buffer<T>::~Buffer()
133
- {
134
- if constexpr (std::is_destructible_v<T>)
135
- {
136
- if (this->m_owner)
137
- {
138
- delete[] this->m_buffer;
139
- }
140
- }
141
- }
142
-
143
- template <typename T>
144
- inline Buffer<T>::Buffer(Buffer<T>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
144
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
145
145
  {
146
146
  other.m_buffer = nullptr;
147
147
  other.m_size = 0;
@@ -149,7 +149,7 @@ namespace Rice
149
149
  }
150
150
 
151
151
  template <typename T>
152
- inline Buffer<T>& Buffer<T>::operator=(Buffer<T>&& other)
152
+ inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>& Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::operator=(Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>&& other)
153
153
  {
154
154
  this->m_buffer = other.m_buffer;
155
155
  other.m_buffer = nullptr;
@@ -164,57 +164,59 @@ namespace Rice
164
164
  }
165
165
 
166
166
  template <typename T>
167
- inline size_t Buffer<T>::size() const
167
+ inline size_t Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::size() const
168
168
  {
169
169
  return this->m_size;
170
170
  }
171
171
 
172
172
  template <typename T>
173
- void Buffer<T>::setSize(size_t value)
173
+ void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::setSize(size_t value)
174
174
  {
175
175
  this->m_size = value;
176
176
  }
177
177
 
178
178
  template <typename T>
179
- inline T* Buffer<T>::ptr()
179
+ inline T* Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::ptr()
180
180
  {
181
181
  return this->m_buffer;
182
182
  }
183
183
 
184
184
  template <typename T>
185
- inline T& Buffer<T>::reference()
185
+ inline T& Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::reference()
186
186
  {
187
187
  return *this->m_buffer;
188
188
  }
189
189
 
190
190
  template <typename T>
191
- inline bool Buffer<T>::isOwner() const
191
+ inline bool Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::isOwner() const
192
192
  {
193
193
  return this->m_owner;
194
194
  }
195
195
 
196
196
  template <typename T>
197
- inline void Buffer<T>::setOwner(bool value)
197
+ inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::setOwner(bool value)
198
198
  {
199
199
  this->m_owner = value;
200
200
  }
201
201
 
202
202
  template <typename T>
203
- inline void Buffer<T>::release()
203
+ inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::release()
204
204
  {
205
205
  this->m_owner = false;
206
206
  }
207
207
 
208
- /* template<typename T>
209
- inline VALUE Buffer<T>::toString() const
208
+ template<typename T>
209
+ inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toString() const
210
210
  {
211
- std::string name = detail::typeName(typeid(T));
212
- std::string result = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
213
- return detail::To_Ruby<std::string>().convert(result);
214
- }*/
211
+ std::string name = detail::typeName(typeid(T*));
212
+ std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
213
+
214
+ // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
215
+ return detail::protect(rb_utf8_str_new_cstr, description.c_str());
216
+ }
215
217
 
216
218
  template<typename T>
217
- inline VALUE Buffer<T>::bytes(size_t count) const
219
+ inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::bytes(size_t count) const
218
220
  {
219
221
  if (!this->m_buffer)
220
222
  {
@@ -228,13 +230,13 @@ namespace Rice
228
230
  }
229
231
 
230
232
  template<typename T>
231
- inline VALUE Buffer<T>::bytes() const
233
+ inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::bytes() const
232
234
  {
233
235
  return this->bytes(this->m_size);
234
236
  }
235
237
 
236
238
  template<typename T>
237
- inline Array Buffer<T>::toArray(size_t count) const
239
+ inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toArray(size_t count) const
238
240
  {
239
241
  if (!this->m_buffer)
240
242
  {
@@ -261,13 +263,13 @@ namespace Rice
261
263
  }
262
264
 
263
265
  template<typename T>
264
- inline Array Buffer<T>::toArray() const
266
+ inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toArray() const
265
267
  {
266
268
  return this->toArray(this->m_size);
267
269
  }
268
270
 
269
271
  template<typename T>
270
- inline T Buffer<T>::get(size_t index) const
272
+ inline typename Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Element_T& Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::operator[](size_t index)
271
273
  {
272
274
  if (index >= this->m_size)
273
275
  {
@@ -277,30 +279,19 @@ namespace Rice
277
279
  return this->m_buffer[index];
278
280
  }
279
281
 
282
+ // ---- Buffer<T*> - Builtin -------
280
283
  template<typename T>
281
- inline void Buffer<T>::set(size_t index, T element)
282
- {
283
- if (index >= this->m_size)
284
- {
285
- throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
286
- }
287
-
288
- this->m_buffer[index] = element;
289
- }
290
-
291
- // ---- Buffer<T*> -------
292
- template<typename T>
293
- inline Buffer<T*>::Buffer(T** pointer) : m_outer(pointer)
284
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_outer(pointer)
294
285
  {
295
286
  }
296
287
 
297
288
  template<typename T>
298
- inline Buffer<T*>::Buffer(T** pointer, size_t size) : m_outer(pointer), m_size(size)
289
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_outer(pointer), m_size(size)
299
290
  {
300
291
  }
301
292
 
302
293
  template <typename T>
303
- inline Buffer<T*>::Buffer(VALUE value)
294
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value)
304
295
  {
305
296
  ruby_value_type valueType = rb_type(value);
306
297
 
@@ -340,7 +331,7 @@ namespace Rice
340
331
  }
341
332
 
342
333
  template <typename T>
343
- inline Buffer<T*>::~Buffer()
334
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::~Buffer()
344
335
  {
345
336
  if (this->m_owner)
346
337
  {
@@ -349,7 +340,7 @@ namespace Rice
349
340
  }
350
341
 
351
342
  template <typename T>
352
- inline Buffer<T*>::Buffer(Buffer<T*>&& other) : m_owner(other.m_owner), m_size(other.m_size),
343
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size),
353
344
  m_outer(other.m_outer), m_inner(std::move(other.m_inner))
354
345
  {
355
346
  other.m_outer = nullptr;
@@ -359,7 +350,7 @@ namespace Rice
359
350
  }
360
351
 
361
352
  template <typename T>
362
- inline Buffer<T*>& Buffer<T*>::operator=(Buffer<T*>&& other)
353
+ inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>& Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::operator=(Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>&& other)
363
354
  {
364
355
  this->m_outer = other.m_outer;
365
356
  other.m_outer = nullptr;
@@ -377,57 +368,59 @@ namespace Rice
377
368
  }
378
369
 
379
370
  template <typename T>
380
- inline const Buffer<T>& Buffer<T*>::operator[](size_t index)
371
+ inline typename Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Element_T& Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::operator[](size_t index)
381
372
  {
382
373
  return this->m_inner[index];
383
374
  }
384
375
 
385
376
  template <typename T>
386
- inline size_t Buffer<T*>::size() const
377
+ inline size_t Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::size() const
387
378
  {
388
379
  return this->m_size;
389
380
  }
390
381
 
391
382
  template <typename T>
392
- void Buffer<T*>::setSize(size_t value)
383
+ void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setSize(size_t value)
393
384
  {
394
385
  this->m_size = value;
395
386
  }
396
387
 
397
388
  template <typename T>
398
- inline T** Buffer<T*>::ptr()
389
+ inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::ptr()
399
390
  {
400
391
  return this->m_outer;
401
392
  }
402
393
 
403
394
  template <typename T>
404
- inline bool Buffer<T*>::isOwner() const
395
+ inline bool Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::isOwner() const
405
396
  {
406
397
  return this->m_owner;
407
398
  }
408
399
 
409
400
  template <typename T>
410
- inline void Buffer<T*>::setOwner(bool value)
401
+ inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setOwner(bool value)
411
402
  {
412
403
  this->m_owner = value;
413
404
  }
414
405
 
415
406
  template <typename T>
416
- inline void Buffer<T*>::release()
407
+ inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::release()
417
408
  {
418
409
  this->m_owner = false;
419
410
  }
420
411
 
421
- /*template<typename T>
422
- inline VALUE Buffer<T*>::toString() const
412
+ template<typename T>
413
+ inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toString() const
423
414
  {
424
415
  std::string name = detail::typeName(typeid(T*));
425
- std::string result = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
426
- return detail::To_Ruby<std::string>().convert(result);
427
- }*/
416
+ std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
417
+
418
+ // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
419
+ return detail::protect(rb_utf8_str_new_cstr, description.c_str());
420
+ }
428
421
 
429
422
  template<typename T>
430
- inline VALUE Buffer<T*>::bytes(size_t count) const
423
+ inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes(size_t count) const
431
424
  {
432
425
  if (!this->m_outer)
433
426
  {
@@ -442,13 +435,13 @@ namespace Rice
442
435
  }
443
436
 
444
437
  template<typename T>
445
- inline VALUE Buffer<T*>::bytes() const
438
+ inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes() const
446
439
  {
447
440
  return this->bytes(this->m_size);
448
441
  }
449
442
 
450
443
  template<typename T>
451
- inline Array Buffer<T*>::toArray(size_t count) const
444
+ inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray(size_t count) const
452
445
  {
453
446
  if (!this->m_outer)
454
447
  {
@@ -471,7 +464,188 @@ namespace Rice
471
464
  }
472
465
 
473
466
  template<typename T>
474
- inline Array Buffer<T*>::toArray() const
467
+ inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray() const
468
+ {
469
+ return this->toArray(this->m_size);
470
+ }
471
+
472
+ // ---- Buffer<T*> - Wrapped -------
473
+ template<typename T>
474
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
475
+ {
476
+ }
477
+
478
+ template<typename T>
479
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
480
+ {
481
+ }
482
+
483
+ template <typename T>
484
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(VALUE value)
485
+ {
486
+ ruby_value_type valueType = rb_type(value);
487
+
488
+ switch (valueType)
489
+ {
490
+ case RUBY_T_ARRAY:
491
+ {
492
+ Array array(value);
493
+ this->m_size = array.size();
494
+ this->m_buffer = new T * [this->m_size]();
495
+
496
+ detail::From_Ruby<T> fromRuby;
497
+ for (size_t i = 0; i < this->m_size; i++)
498
+ {
499
+ Data_Object<detail::intrinsic_type<T>> dataObject(array[i].value());
500
+ this->m_buffer[i] = dataObject.get();
501
+ }
502
+
503
+ this->m_owner = true;
504
+ break;
505
+ }
506
+ default:
507
+ {
508
+ std::string typeName = detail::typeName(typeid(T));
509
+ throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
510
+ detail::protect(rb_obj_classname, value), typeName.c_str());
511
+ }
512
+ }
513
+ }
514
+
515
+ template <typename T>
516
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::~Buffer()
517
+ {
518
+ if (this->m_owner)
519
+ {
520
+ delete[] this->m_buffer;
521
+ }
522
+ }
523
+
524
+ template <typename T>
525
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size),
526
+ m_buffer(other.m_buffer)
527
+ {
528
+ other.m_buffer = nullptr;
529
+ other.m_size = 0;
530
+ other.m_owner = false;
531
+ }
532
+
533
+ template <typename T>
534
+ inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>& Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::operator=(Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>&& other)
535
+ {
536
+ this->m_buffer = other.m_buffer;
537
+ other.m_buffer = nullptr;
538
+
539
+ this->m_size = other.m_size;
540
+ other.m_size = 0;
541
+
542
+ this->m_owner = other.m_owner;
543
+ other.m_owner = false;
544
+
545
+ return *this;
546
+ }
547
+
548
+ template <typename T>
549
+ inline typename Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Element_T& Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::operator[](size_t index)
550
+ {
551
+ if (index >= this->m_size)
552
+ {
553
+ throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
554
+ }
555
+ return this->m_buffer[index];
556
+ }
557
+
558
+ template <typename T>
559
+ inline size_t Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::size() const
560
+ {
561
+ return this->m_size;
562
+ }
563
+
564
+ template <typename T>
565
+ void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::setSize(size_t value)
566
+ {
567
+ this->m_size = value;
568
+ }
569
+
570
+ template <typename T>
571
+ inline T** Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::ptr()
572
+ {
573
+ return this->m_buffer;
574
+ }
575
+
576
+ template <typename T>
577
+ inline bool Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::isOwner() const
578
+ {
579
+ return this->m_owner;
580
+ }
581
+
582
+ template <typename T>
583
+ inline void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::setOwner(bool value)
584
+ {
585
+ this->m_owner = value;
586
+ }
587
+
588
+ template <typename T>
589
+ inline void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::release()
590
+ {
591
+ this->m_owner = false;
592
+ }
593
+
594
+ template<typename T>
595
+ inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toString() const
596
+ {
597
+ std::string name = detail::typeName(typeid(T*));
598
+ std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
599
+
600
+ // We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
601
+ return detail::protect(rb_utf8_str_new_cstr, description.c_str());
602
+ }
603
+
604
+ template<typename T>
605
+ inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes(size_t count) const
606
+ {
607
+ if (!this->m_buffer)
608
+ {
609
+ return Qnil;
610
+ }
611
+ else
612
+ {
613
+ T** begin = this->m_buffer;
614
+ long length = (long)(count * sizeof(T*));
615
+ return detail::protect(rb_str_new_static, (const char*)*begin, length);
616
+ }
617
+ }
618
+
619
+ template<typename T>
620
+ inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes() const
621
+ {
622
+ return this->bytes(this->m_size);
623
+ }
624
+
625
+ template<typename T>
626
+ inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray(size_t count) const
627
+ {
628
+ if (!this->m_buffer)
629
+ {
630
+ return Qnil;
631
+ }
632
+ else
633
+ {
634
+ Array result;
635
+
636
+ T** ptr = this->m_buffer;
637
+ T** end = this->m_buffer + count;
638
+
639
+ for (; ptr < end; ptr++)
640
+ {
641
+ result.push(*ptr);
642
+ }
643
+ return result;
644
+ }
645
+ }
646
+
647
+ template<typename T>
648
+ inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray() const
475
649
  {
476
650
  return this->toArray(this->m_size);
477
651
  }
@@ -508,6 +682,9 @@ namespace Rice
508
682
  if (klassName.empty())
509
683
  {
510
684
  std::string typeName = detail::typeName(typeid(Buffer_T));
685
+ // This will end up as Buffer<T,void>. We want to remove the ,void part.
686
+ auto removeVoidRegex = std::regex(",\\s?void");
687
+ typeName = std::regex_replace(typeName, removeVoidRegex, "");
511
688
  klassName = detail::rubyClassName(typeName);
512
689
  }
513
690
 
@@ -523,23 +700,35 @@ namespace Rice
523
700
  define_constructor(Constructor<Buffer_T, VALUE>(), Arg("value").setValue()).
524
701
  define_method("size", &Buffer_T::size).
525
702
  define_method("size=", &Buffer_T::setSize).
526
- // template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
703
+ template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
527
704
  template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
528
705
  template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
529
706
  template define_method<Array(Buffer_T::*)(size_t) const>("to_ary", &Buffer_T::toArray, Return().setValue()).
530
707
  template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue());
531
708
 
532
- if constexpr (!std::is_pointer_v<T>)
709
+ klass.
710
+ define_method("[]", &Buffer_T::operator[], Arg("index"));
711
+
712
+ if constexpr (std::is_pointer_v<T> && detail::is_wrapped_v<T>)
713
+ {
714
+ klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T element) -> void
715
+ {
716
+ self[index] = element;
717
+ });
718
+ }
719
+ else if constexpr (std::is_pointer_v<T> && !detail::is_wrapped_v<T>)
720
+ {
721
+ klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T& element) -> void
722
+ {
723
+ self[index] = std::move(element);
724
+ });
725
+ }
726
+ else
533
727
  {
534
- klass.
535
- define_method("[]", [](const Buffer_T& self, size_t index) -> T
536
- {
537
- return self.get(index);
538
- }).
539
- define_method("[]=", [](Buffer_T& self, size_t index, T element) -> void
540
- {
541
- self.set(index, element);
542
- });
728
+ klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T& element) -> void
729
+ {
730
+ self[index] = element;
731
+ });
543
732
  }
544
733
 
545
734
  return klass;
data/rice/Data_Type.hpp CHANGED
@@ -166,6 +166,9 @@ namespace Rice
166
166
  template<bool IsMethod, typename Function_T>
167
167
  void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
168
168
 
169
+ template <typename Attribute_T>
170
+ Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access);
171
+
169
172
  private:
170
173
  template<typename T_>
171
174
  friend class Data_Type;