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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/include/rice/rice.hpp +408 -153
- data/include/rice/stl.hpp +49 -50
- data/lib/rice/version.rb +1 -1
- data/rice/Buffer.hpp +57 -12
- data/rice/Buffer.ipp +273 -84
- data/rice/Data_Type.hpp +3 -0
- data/rice/Data_Type.ipp +39 -28
- data/rice/detail/NativeAttributeGet.ipp +12 -1
- data/rice/detail/NativeAttributeSet.ipp +3 -21
- data/rice/detail/NativeCallbackFFI.ipp +1 -0
- data/rice/detail/NativeFunction.ipp +1 -0
- data/rice/detail/RubyFunction.ipp +1 -0
- data/rice/detail/Type.ipp +0 -1
- data/rice/stl/vector.ipp +49 -50
- data/rice/traits/attribute_traits.hpp +6 -6
- data/rice/traits/rice_traits.hpp +12 -0
- data/test/test_Attribute.cpp +57 -8
- data/test/test_Buffer.cpp +56 -1
- data/test/test_Data_Object.cpp +1 -1
- data/test/test_From_Ruby.cpp +6 -6
- metadata +1 -1
data/include/rice/rice.hpp
CHANGED
@@ -73,6 +73,7 @@ extern "C" typedef VALUE (*RUBY_VALUE_FUNC)(VALUE);
|
|
73
73
|
// ========= rice_traits.hpp =========
|
74
74
|
|
75
75
|
#include <ostream>
|
76
|
+
#include <tuple>
|
76
77
|
#include <type_traits>
|
77
78
|
#include <variant>
|
78
79
|
#include <vector>
|
@@ -225,6 +226,17 @@ namespace Rice
|
|
225
226
|
(callable(std::forward<decltype(args)>(args)), ...);
|
226
227
|
}, std::forward<Tuple_T>(tuple));
|
227
228
|
}
|
229
|
+
|
230
|
+
template<typename T, typename = void>
|
231
|
+
struct is_wrapped : std::true_type {};
|
232
|
+
|
233
|
+
template<typename T>
|
234
|
+
struct is_wrapped<T, std::enable_if_t<std::is_fundamental_v<detail::intrinsic_type<T>> ||
|
235
|
+
std::is_same_v<detail::intrinsic_type<T>, std::string>>
|
236
|
+
>: std::false_type {};
|
237
|
+
|
238
|
+
template<typename T>
|
239
|
+
constexpr bool is_wrapped_v = is_wrapped<T>::value;
|
228
240
|
} // detail
|
229
241
|
} // Rice
|
230
242
|
|
@@ -379,17 +391,17 @@ namespace Rice::detail
|
|
379
391
|
template<typename Attribute_T>
|
380
392
|
struct attribute_traits;
|
381
393
|
|
382
|
-
template<typename
|
383
|
-
struct attribute_traits<
|
394
|
+
template<typename Attribute_T>
|
395
|
+
struct attribute_traits<Attribute_T*>
|
384
396
|
{
|
385
|
-
using attr_type =
|
397
|
+
using attr_type = Attribute_T;
|
386
398
|
using class_type = std::nullptr_t;
|
387
399
|
};
|
388
400
|
|
389
|
-
template<typename
|
390
|
-
struct attribute_traits<
|
401
|
+
template<typename Attribute_T, typename Class_T>
|
402
|
+
struct attribute_traits<Attribute_T(Class_T::*)>
|
391
403
|
{
|
392
|
-
using attr_type =
|
404
|
+
using attr_type = Attribute_T;
|
393
405
|
using class_type = Class_T;
|
394
406
|
};
|
395
407
|
}
|
@@ -588,6 +600,7 @@ namespace Rice::detail
|
|
588
600
|
// ========= RubyFunction.ipp =========
|
589
601
|
|
590
602
|
#include <any>
|
603
|
+
#include <tuple>
|
591
604
|
|
592
605
|
namespace Rice::detail
|
593
606
|
{
|
@@ -2711,6 +2724,9 @@ inline auto& define_constant(std::string name, Constant_T value)
|
|
2711
2724
|
template<bool IsMethod, typename Function_T>
|
2712
2725
|
void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
|
2713
2726
|
|
2727
|
+
template <typename Attribute_T>
|
2728
|
+
Data_Type<T>& define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access);
|
2729
|
+
|
2714
2730
|
private:
|
2715
2731
|
template<typename T_>
|
2716
2732
|
friend class Data_Type;
|
@@ -3495,11 +3511,14 @@ namespace Rice
|
|
3495
3511
|
|
3496
3512
|
namespace Rice
|
3497
3513
|
{
|
3514
|
+
template<typename T, typename = void>
|
3515
|
+
class Buffer;
|
3516
|
+
|
3498
3517
|
template<typename T>
|
3499
|
-
class Buffer
|
3518
|
+
class Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>
|
3500
3519
|
{
|
3501
3520
|
public:
|
3502
|
-
using
|
3521
|
+
using Element_T = T;
|
3503
3522
|
|
3504
3523
|
Buffer(T* pointer);
|
3505
3524
|
Buffer(T* pointer, size_t size);
|
@@ -3512,6 +3531,7 @@ namespace Rice
|
|
3512
3531
|
|
3513
3532
|
Buffer& operator=(const Buffer& other) = delete;
|
3514
3533
|
Buffer& operator=(Buffer&& other);
|
3534
|
+
T& operator[](size_t index);
|
3515
3535
|
|
3516
3536
|
T* ptr();
|
3517
3537
|
T& reference();
|
@@ -3521,7 +3541,7 @@ namespace Rice
|
|
3521
3541
|
void setSize(size_t value);
|
3522
3542
|
|
3523
3543
|
// Ruby API
|
3524
|
-
|
3544
|
+
VALUE toString() const;
|
3525
3545
|
|
3526
3546
|
VALUE bytes() const;
|
3527
3547
|
VALUE bytes(size_t count) const;
|
@@ -3529,15 +3549,12 @@ namespace Rice
|
|
3529
3549
|
Array toArray() const;
|
3530
3550
|
Array toArray(size_t count) const;
|
3531
3551
|
|
3532
|
-
T get(size_t index) const;
|
3533
|
-
void set(size_t index, T value);
|
3534
|
-
|
3535
3552
|
bool isOwner() const;
|
3536
3553
|
void setOwner(bool value);
|
3537
3554
|
|
3538
3555
|
private:
|
3539
|
-
void
|
3540
|
-
void
|
3556
|
+
void fromBuiltinType(VALUE value);
|
3557
|
+
void fromWrappedType(VALUE value);
|
3541
3558
|
|
3542
3559
|
bool m_owner = false;
|
3543
3560
|
size_t m_size = 0;
|
@@ -3546,10 +3563,10 @@ namespace Rice
|
|
3546
3563
|
};
|
3547
3564
|
|
3548
3565
|
template<typename T>
|
3549
|
-
class Buffer<T
|
3566
|
+
class Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>
|
3550
3567
|
{
|
3551
3568
|
public:
|
3552
|
-
using
|
3569
|
+
using Element_T = Buffer<T>;
|
3553
3570
|
|
3554
3571
|
Buffer(T** pointer);
|
3555
3572
|
Buffer(T** pointer, size_t size);
|
@@ -3563,7 +3580,7 @@ namespace Rice
|
|
3563
3580
|
Buffer& operator=(const Buffer& other) = delete;
|
3564
3581
|
Buffer& operator=(Buffer&& other);
|
3565
3582
|
|
3566
|
-
|
3583
|
+
Element_T& operator[](size_t index);
|
3567
3584
|
|
3568
3585
|
T** ptr();
|
3569
3586
|
void release();
|
@@ -3572,7 +3589,7 @@ namespace Rice
|
|
3572
3589
|
void setSize(size_t value);
|
3573
3590
|
|
3574
3591
|
// Ruby API
|
3575
|
-
|
3592
|
+
VALUE toString() const;
|
3576
3593
|
|
3577
3594
|
VALUE bytes() const;
|
3578
3595
|
VALUE bytes(size_t count) const;
|
@@ -3590,6 +3607,50 @@ namespace Rice
|
|
3590
3607
|
std::vector<Buffer<T>> m_inner;
|
3591
3608
|
};
|
3592
3609
|
|
3610
|
+
template<typename T>
|
3611
|
+
class Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>
|
3612
|
+
{
|
3613
|
+
public:
|
3614
|
+
using Element_T = T*;
|
3615
|
+
|
3616
|
+
Buffer(T** pointer);
|
3617
|
+
Buffer(T** pointer, size_t size);
|
3618
|
+
Buffer(VALUE value);
|
3619
|
+
|
3620
|
+
~Buffer();
|
3621
|
+
|
3622
|
+
Buffer(const Buffer& other) = delete;
|
3623
|
+
Buffer(Buffer&& other);
|
3624
|
+
|
3625
|
+
Buffer& operator=(const Buffer& other) = delete;
|
3626
|
+
Buffer& operator=(Buffer&& other);
|
3627
|
+
|
3628
|
+
Element_T& operator[](size_t index);
|
3629
|
+
|
3630
|
+
T** ptr();
|
3631
|
+
void release();
|
3632
|
+
|
3633
|
+
size_t size() const;
|
3634
|
+
void setSize(size_t value);
|
3635
|
+
|
3636
|
+
// Ruby API
|
3637
|
+
VALUE toString() const;
|
3638
|
+
|
3639
|
+
VALUE bytes() const;
|
3640
|
+
VALUE bytes(size_t count) const;
|
3641
|
+
|
3642
|
+
Array toArray() const;
|
3643
|
+
Array toArray(size_t count) const;
|
3644
|
+
|
3645
|
+
void setOwner(bool value);
|
3646
|
+
bool isOwner() const;
|
3647
|
+
|
3648
|
+
private:
|
3649
|
+
bool m_owner = false;
|
3650
|
+
size_t m_size = 0;
|
3651
|
+
T** m_buffer = nullptr;
|
3652
|
+
};
|
3653
|
+
|
3593
3654
|
template<>
|
3594
3655
|
class Buffer<void>
|
3595
3656
|
{
|
@@ -3618,30 +3679,42 @@ namespace Rice
|
|
3618
3679
|
{
|
3619
3680
|
// ---- Buffer<T> -------
|
3620
3681
|
template<typename T>
|
3621
|
-
inline Buffer<T
|
3682
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(T* pointer) : m_buffer(pointer)
|
3622
3683
|
{
|
3623
3684
|
}
|
3624
3685
|
|
3625
3686
|
template<typename T>
|
3626
|
-
inline Buffer<T
|
3687
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(T* pointer, size_t size) : m_size(size), m_buffer(pointer)
|
3627
3688
|
{
|
3628
3689
|
}
|
3629
3690
|
|
3630
3691
|
template <typename T>
|
3631
|
-
inline Buffer<T
|
3692
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::Buffer(VALUE value)
|
3632
3693
|
{
|
3633
3694
|
if constexpr (std::is_fundamental_v<T>)
|
3634
3695
|
{
|
3635
|
-
this->
|
3696
|
+
this->fromBuiltinType(value);
|
3636
3697
|
}
|
3637
3698
|
else
|
3638
3699
|
{
|
3639
|
-
this->
|
3700
|
+
this->fromWrappedType(value);
|
3640
3701
|
}
|
3641
3702
|
}
|
3642
3703
|
|
3643
3704
|
template <typename T>
|
3644
|
-
inline
|
3705
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::~Buffer()
|
3706
|
+
{
|
3707
|
+
if constexpr (std::is_destructible_v<T>)
|
3708
|
+
{
|
3709
|
+
if (this->m_owner)
|
3710
|
+
{
|
3711
|
+
delete[] this->m_buffer;
|
3712
|
+
}
|
3713
|
+
}
|
3714
|
+
}
|
3715
|
+
|
3716
|
+
template <typename T>
|
3717
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::fromBuiltinType(VALUE value)
|
3645
3718
|
{
|
3646
3719
|
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
3647
3720
|
using RubyType_T = typename detail::RubyType<Intrinsic_T>;
|
@@ -3713,7 +3786,7 @@ namespace Rice
|
|
3713
3786
|
}
|
3714
3787
|
|
3715
3788
|
template <typename T>
|
3716
|
-
inline void Buffer<T
|
3789
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::fromWrappedType(VALUE value)
|
3717
3790
|
{
|
3718
3791
|
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
3719
3792
|
|
@@ -3745,19 +3818,7 @@ namespace Rice
|
|
3745
3818
|
}
|
3746
3819
|
|
3747
3820
|
template <typename T>
|
3748
|
-
inline Buffer<T
|
3749
|
-
{
|
3750
|
-
if constexpr (std::is_destructible_v<T>)
|
3751
|
-
{
|
3752
|
-
if (this->m_owner)
|
3753
|
-
{
|
3754
|
-
delete[] this->m_buffer;
|
3755
|
-
}
|
3756
|
-
}
|
3757
|
-
}
|
3758
|
-
|
3759
|
-
template <typename T>
|
3760
|
-
inline Buffer<T>::Buffer(Buffer<T>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
|
3821
|
+
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)
|
3761
3822
|
{
|
3762
3823
|
other.m_buffer = nullptr;
|
3763
3824
|
other.m_size = 0;
|
@@ -3765,7 +3826,7 @@ namespace Rice
|
|
3765
3826
|
}
|
3766
3827
|
|
3767
3828
|
template <typename T>
|
3768
|
-
inline Buffer<T
|
3829
|
+
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)
|
3769
3830
|
{
|
3770
3831
|
this->m_buffer = other.m_buffer;
|
3771
3832
|
other.m_buffer = nullptr;
|
@@ -3780,57 +3841,59 @@ namespace Rice
|
|
3780
3841
|
}
|
3781
3842
|
|
3782
3843
|
template <typename T>
|
3783
|
-
inline size_t Buffer<T
|
3844
|
+
inline size_t Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::size() const
|
3784
3845
|
{
|
3785
3846
|
return this->m_size;
|
3786
3847
|
}
|
3787
3848
|
|
3788
3849
|
template <typename T>
|
3789
|
-
void Buffer<T
|
3850
|
+
void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::setSize(size_t value)
|
3790
3851
|
{
|
3791
3852
|
this->m_size = value;
|
3792
3853
|
}
|
3793
3854
|
|
3794
3855
|
template <typename T>
|
3795
|
-
inline T* Buffer<T
|
3856
|
+
inline T* Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::ptr()
|
3796
3857
|
{
|
3797
3858
|
return this->m_buffer;
|
3798
3859
|
}
|
3799
3860
|
|
3800
3861
|
template <typename T>
|
3801
|
-
inline T& Buffer<T
|
3862
|
+
inline T& Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::reference()
|
3802
3863
|
{
|
3803
3864
|
return *this->m_buffer;
|
3804
3865
|
}
|
3805
3866
|
|
3806
3867
|
template <typename T>
|
3807
|
-
inline bool Buffer<T
|
3868
|
+
inline bool Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::isOwner() const
|
3808
3869
|
{
|
3809
3870
|
return this->m_owner;
|
3810
3871
|
}
|
3811
3872
|
|
3812
3873
|
template <typename T>
|
3813
|
-
inline void Buffer<T
|
3874
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::setOwner(bool value)
|
3814
3875
|
{
|
3815
3876
|
this->m_owner = value;
|
3816
3877
|
}
|
3817
3878
|
|
3818
3879
|
template <typename T>
|
3819
|
-
inline void Buffer<T
|
3880
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::release()
|
3820
3881
|
{
|
3821
3882
|
this->m_owner = false;
|
3822
3883
|
}
|
3823
3884
|
|
3824
|
-
|
3825
|
-
inline VALUE Buffer<T
|
3885
|
+
template<typename T>
|
3886
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toString() const
|
3826
3887
|
{
|
3827
|
-
std::string name = detail::typeName(typeid(T));
|
3828
|
-
std::string
|
3829
|
-
|
3830
|
-
|
3888
|
+
std::string name = detail::typeName(typeid(T*));
|
3889
|
+
std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
|
3890
|
+
|
3891
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
3892
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
3893
|
+
}
|
3831
3894
|
|
3832
3895
|
template<typename T>
|
3833
|
-
inline VALUE Buffer<T
|
3896
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::bytes(size_t count) const
|
3834
3897
|
{
|
3835
3898
|
if (!this->m_buffer)
|
3836
3899
|
{
|
@@ -3844,13 +3907,13 @@ namespace Rice
|
|
3844
3907
|
}
|
3845
3908
|
|
3846
3909
|
template<typename T>
|
3847
|
-
inline VALUE Buffer<T
|
3910
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::bytes() const
|
3848
3911
|
{
|
3849
3912
|
return this->bytes(this->m_size);
|
3850
3913
|
}
|
3851
3914
|
|
3852
3915
|
template<typename T>
|
3853
|
-
inline Array Buffer<T
|
3916
|
+
inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toArray(size_t count) const
|
3854
3917
|
{
|
3855
3918
|
if (!this->m_buffer)
|
3856
3919
|
{
|
@@ -3877,13 +3940,13 @@ namespace Rice
|
|
3877
3940
|
}
|
3878
3941
|
|
3879
3942
|
template<typename T>
|
3880
|
-
inline Array Buffer<T
|
3943
|
+
inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T>>>::toArray() const
|
3881
3944
|
{
|
3882
3945
|
return this->toArray(this->m_size);
|
3883
3946
|
}
|
3884
3947
|
|
3885
3948
|
template<typename T>
|
3886
|
-
inline T Buffer<T
|
3949
|
+
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)
|
3887
3950
|
{
|
3888
3951
|
if (index >= this->m_size)
|
3889
3952
|
{
|
@@ -3893,30 +3956,19 @@ namespace Rice
|
|
3893
3956
|
return this->m_buffer[index];
|
3894
3957
|
}
|
3895
3958
|
|
3959
|
+
// ---- Buffer<T*> - Builtin -------
|
3896
3960
|
template<typename T>
|
3897
|
-
inline
|
3898
|
-
{
|
3899
|
-
if (index >= this->m_size)
|
3900
|
-
{
|
3901
|
-
throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
|
3902
|
-
}
|
3903
|
-
|
3904
|
-
this->m_buffer[index] = element;
|
3905
|
-
}
|
3906
|
-
|
3907
|
-
// ---- Buffer<T*> -------
|
3908
|
-
template<typename T>
|
3909
|
-
inline Buffer<T*>::Buffer(T** pointer) : m_outer(pointer)
|
3961
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_outer(pointer)
|
3910
3962
|
{
|
3911
3963
|
}
|
3912
3964
|
|
3913
3965
|
template<typename T>
|
3914
|
-
inline Buffer<T
|
3966
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_outer(pointer), m_size(size)
|
3915
3967
|
{
|
3916
3968
|
}
|
3917
3969
|
|
3918
3970
|
template <typename T>
|
3919
|
-
inline Buffer<T
|
3971
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value)
|
3920
3972
|
{
|
3921
3973
|
ruby_value_type valueType = rb_type(value);
|
3922
3974
|
|
@@ -3956,7 +4008,7 @@ namespace Rice
|
|
3956
4008
|
}
|
3957
4009
|
|
3958
4010
|
template <typename T>
|
3959
|
-
inline Buffer<T
|
4011
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::~Buffer()
|
3960
4012
|
{
|
3961
4013
|
if (this->m_owner)
|
3962
4014
|
{
|
@@ -3965,7 +4017,7 @@ namespace Rice
|
|
3965
4017
|
}
|
3966
4018
|
|
3967
4019
|
template <typename T>
|
3968
|
-
inline Buffer<T
|
4020
|
+
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),
|
3969
4021
|
m_outer(other.m_outer), m_inner(std::move(other.m_inner))
|
3970
4022
|
{
|
3971
4023
|
other.m_outer = nullptr;
|
@@ -3975,7 +4027,7 @@ namespace Rice
|
|
3975
4027
|
}
|
3976
4028
|
|
3977
4029
|
template <typename T>
|
3978
|
-
inline Buffer<T
|
4030
|
+
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)
|
3979
4031
|
{
|
3980
4032
|
this->m_outer = other.m_outer;
|
3981
4033
|
other.m_outer = nullptr;
|
@@ -3993,57 +4045,59 @@ namespace Rice
|
|
3993
4045
|
}
|
3994
4046
|
|
3995
4047
|
template <typename T>
|
3996
|
-
inline
|
4048
|
+
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)
|
3997
4049
|
{
|
3998
4050
|
return this->m_inner[index];
|
3999
4051
|
}
|
4000
4052
|
|
4001
4053
|
template <typename T>
|
4002
|
-
inline size_t Buffer<T
|
4054
|
+
inline size_t Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::size() const
|
4003
4055
|
{
|
4004
4056
|
return this->m_size;
|
4005
4057
|
}
|
4006
4058
|
|
4007
4059
|
template <typename T>
|
4008
|
-
void Buffer<T
|
4060
|
+
void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setSize(size_t value)
|
4009
4061
|
{
|
4010
4062
|
this->m_size = value;
|
4011
4063
|
}
|
4012
4064
|
|
4013
4065
|
template <typename T>
|
4014
|
-
inline T** Buffer<T
|
4066
|
+
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::ptr()
|
4015
4067
|
{
|
4016
4068
|
return this->m_outer;
|
4017
4069
|
}
|
4018
4070
|
|
4019
4071
|
template <typename T>
|
4020
|
-
inline bool Buffer<T
|
4072
|
+
inline bool Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::isOwner() const
|
4021
4073
|
{
|
4022
4074
|
return this->m_owner;
|
4023
4075
|
}
|
4024
4076
|
|
4025
4077
|
template <typename T>
|
4026
|
-
inline void Buffer<T
|
4078
|
+
inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setOwner(bool value)
|
4027
4079
|
{
|
4028
4080
|
this->m_owner = value;
|
4029
4081
|
}
|
4030
4082
|
|
4031
4083
|
template <typename T>
|
4032
|
-
inline void Buffer<T
|
4084
|
+
inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::release()
|
4033
4085
|
{
|
4034
4086
|
this->m_owner = false;
|
4035
4087
|
}
|
4036
4088
|
|
4037
|
-
|
4038
|
-
inline VALUE Buffer<T
|
4089
|
+
template<typename T>
|
4090
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toString() const
|
4039
4091
|
{
|
4040
4092
|
std::string name = detail::typeName(typeid(T*));
|
4041
|
-
std::string
|
4042
|
-
|
4043
|
-
|
4093
|
+
std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
|
4094
|
+
|
4095
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
4096
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
4097
|
+
}
|
4044
4098
|
|
4045
4099
|
template<typename T>
|
4046
|
-
inline VALUE Buffer<T
|
4100
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes(size_t count) const
|
4047
4101
|
{
|
4048
4102
|
if (!this->m_outer)
|
4049
4103
|
{
|
@@ -4058,13 +4112,13 @@ namespace Rice
|
|
4058
4112
|
}
|
4059
4113
|
|
4060
4114
|
template<typename T>
|
4061
|
-
inline VALUE Buffer<T
|
4115
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes() const
|
4062
4116
|
{
|
4063
4117
|
return this->bytes(this->m_size);
|
4064
4118
|
}
|
4065
4119
|
|
4066
4120
|
template<typename T>
|
4067
|
-
inline Array Buffer<T
|
4121
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray(size_t count) const
|
4068
4122
|
{
|
4069
4123
|
if (!this->m_outer)
|
4070
4124
|
{
|
@@ -4087,7 +4141,188 @@ namespace Rice
|
|
4087
4141
|
}
|
4088
4142
|
|
4089
4143
|
template<typename T>
|
4090
|
-
inline Array Buffer<T
|
4144
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray() const
|
4145
|
+
{
|
4146
|
+
return this->toArray(this->m_size);
|
4147
|
+
}
|
4148
|
+
|
4149
|
+
// ---- Buffer<T*> - Wrapped -------
|
4150
|
+
template<typename T>
|
4151
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
4152
|
+
{
|
4153
|
+
}
|
4154
|
+
|
4155
|
+
template<typename T>
|
4156
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
|
4157
|
+
{
|
4158
|
+
}
|
4159
|
+
|
4160
|
+
template <typename T>
|
4161
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(VALUE value)
|
4162
|
+
{
|
4163
|
+
ruby_value_type valueType = rb_type(value);
|
4164
|
+
|
4165
|
+
switch (valueType)
|
4166
|
+
{
|
4167
|
+
case RUBY_T_ARRAY:
|
4168
|
+
{
|
4169
|
+
Array array(value);
|
4170
|
+
this->m_size = array.size();
|
4171
|
+
this->m_buffer = new T * [this->m_size]();
|
4172
|
+
|
4173
|
+
detail::From_Ruby<T> fromRuby;
|
4174
|
+
for (size_t i = 0; i < this->m_size; i++)
|
4175
|
+
{
|
4176
|
+
Data_Object<detail::intrinsic_type<T>> dataObject(array[i].value());
|
4177
|
+
this->m_buffer[i] = dataObject.get();
|
4178
|
+
}
|
4179
|
+
|
4180
|
+
this->m_owner = true;
|
4181
|
+
break;
|
4182
|
+
}
|
4183
|
+
default:
|
4184
|
+
{
|
4185
|
+
std::string typeName = detail::typeName(typeid(T));
|
4186
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
4187
|
+
detail::protect(rb_obj_classname, value), typeName.c_str());
|
4188
|
+
}
|
4189
|
+
}
|
4190
|
+
}
|
4191
|
+
|
4192
|
+
template <typename T>
|
4193
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::~Buffer()
|
4194
|
+
{
|
4195
|
+
if (this->m_owner)
|
4196
|
+
{
|
4197
|
+
delete[] this->m_buffer;
|
4198
|
+
}
|
4199
|
+
}
|
4200
|
+
|
4201
|
+
template <typename T>
|
4202
|
+
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),
|
4203
|
+
m_buffer(other.m_buffer)
|
4204
|
+
{
|
4205
|
+
other.m_buffer = nullptr;
|
4206
|
+
other.m_size = 0;
|
4207
|
+
other.m_owner = false;
|
4208
|
+
}
|
4209
|
+
|
4210
|
+
template <typename T>
|
4211
|
+
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)
|
4212
|
+
{
|
4213
|
+
this->m_buffer = other.m_buffer;
|
4214
|
+
other.m_buffer = nullptr;
|
4215
|
+
|
4216
|
+
this->m_size = other.m_size;
|
4217
|
+
other.m_size = 0;
|
4218
|
+
|
4219
|
+
this->m_owner = other.m_owner;
|
4220
|
+
other.m_owner = false;
|
4221
|
+
|
4222
|
+
return *this;
|
4223
|
+
}
|
4224
|
+
|
4225
|
+
template <typename T>
|
4226
|
+
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)
|
4227
|
+
{
|
4228
|
+
if (index >= this->m_size)
|
4229
|
+
{
|
4230
|
+
throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
|
4231
|
+
}
|
4232
|
+
return this->m_buffer[index];
|
4233
|
+
}
|
4234
|
+
|
4235
|
+
template <typename T>
|
4236
|
+
inline size_t Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::size() const
|
4237
|
+
{
|
4238
|
+
return this->m_size;
|
4239
|
+
}
|
4240
|
+
|
4241
|
+
template <typename T>
|
4242
|
+
void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::setSize(size_t value)
|
4243
|
+
{
|
4244
|
+
this->m_size = value;
|
4245
|
+
}
|
4246
|
+
|
4247
|
+
template <typename T>
|
4248
|
+
inline T** Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::ptr()
|
4249
|
+
{
|
4250
|
+
return this->m_buffer;
|
4251
|
+
}
|
4252
|
+
|
4253
|
+
template <typename T>
|
4254
|
+
inline bool Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::isOwner() const
|
4255
|
+
{
|
4256
|
+
return this->m_owner;
|
4257
|
+
}
|
4258
|
+
|
4259
|
+
template <typename T>
|
4260
|
+
inline void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::setOwner(bool value)
|
4261
|
+
{
|
4262
|
+
this->m_owner = value;
|
4263
|
+
}
|
4264
|
+
|
4265
|
+
template <typename T>
|
4266
|
+
inline void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::release()
|
4267
|
+
{
|
4268
|
+
this->m_owner = false;
|
4269
|
+
}
|
4270
|
+
|
4271
|
+
template<typename T>
|
4272
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toString() const
|
4273
|
+
{
|
4274
|
+
std::string name = detail::typeName(typeid(T*));
|
4275
|
+
std::string description = "Buffer<type: " + detail::cppClassName(name) + ", size: " + std::to_string(this->m_size) + ">";
|
4276
|
+
|
4277
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
4278
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
4279
|
+
}
|
4280
|
+
|
4281
|
+
template<typename T>
|
4282
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes(size_t count) const
|
4283
|
+
{
|
4284
|
+
if (!this->m_buffer)
|
4285
|
+
{
|
4286
|
+
return Qnil;
|
4287
|
+
}
|
4288
|
+
else
|
4289
|
+
{
|
4290
|
+
T** begin = this->m_buffer;
|
4291
|
+
long length = (long)(count * sizeof(T*));
|
4292
|
+
return detail::protect(rb_str_new_static, (const char*)*begin, length);
|
4293
|
+
}
|
4294
|
+
}
|
4295
|
+
|
4296
|
+
template<typename T>
|
4297
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes() const
|
4298
|
+
{
|
4299
|
+
return this->bytes(this->m_size);
|
4300
|
+
}
|
4301
|
+
|
4302
|
+
template<typename T>
|
4303
|
+
inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray(size_t count) const
|
4304
|
+
{
|
4305
|
+
if (!this->m_buffer)
|
4306
|
+
{
|
4307
|
+
return Qnil;
|
4308
|
+
}
|
4309
|
+
else
|
4310
|
+
{
|
4311
|
+
Array result;
|
4312
|
+
|
4313
|
+
T** ptr = this->m_buffer;
|
4314
|
+
T** end = this->m_buffer + count;
|
4315
|
+
|
4316
|
+
for (; ptr < end; ptr++)
|
4317
|
+
{
|
4318
|
+
result.push(*ptr);
|
4319
|
+
}
|
4320
|
+
return result;
|
4321
|
+
}
|
4322
|
+
}
|
4323
|
+
|
4324
|
+
template<typename T>
|
4325
|
+
inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray() const
|
4091
4326
|
{
|
4092
4327
|
return this->toArray(this->m_size);
|
4093
4328
|
}
|
@@ -4124,6 +4359,9 @@ namespace Rice
|
|
4124
4359
|
if (klassName.empty())
|
4125
4360
|
{
|
4126
4361
|
std::string typeName = detail::typeName(typeid(Buffer_T));
|
4362
|
+
// This will end up as Buffer<T,void>. We want to remove the ,void part.
|
4363
|
+
auto removeVoidRegex = std::regex(",\\s?void");
|
4364
|
+
typeName = std::regex_replace(typeName, removeVoidRegex, "");
|
4127
4365
|
klassName = detail::rubyClassName(typeName);
|
4128
4366
|
}
|
4129
4367
|
|
@@ -4139,23 +4377,35 @@ namespace Rice
|
|
4139
4377
|
define_constructor(Constructor<Buffer_T, VALUE>(), Arg("value").setValue()).
|
4140
4378
|
define_method("size", &Buffer_T::size).
|
4141
4379
|
define_method("size=", &Buffer_T::setSize).
|
4142
|
-
|
4380
|
+
template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
|
4143
4381
|
template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
4144
4382
|
template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
4145
4383
|
template define_method<Array(Buffer_T::*)(size_t) const>("to_ary", &Buffer_T::toArray, Return().setValue()).
|
4146
4384
|
template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue());
|
4147
4385
|
|
4148
|
-
|
4386
|
+
klass.
|
4387
|
+
define_method("[]", &Buffer_T::operator[], Arg("index"));
|
4388
|
+
|
4389
|
+
if constexpr (std::is_pointer_v<T> && detail::is_wrapped_v<T>)
|
4149
4390
|
{
|
4150
|
-
klass.
|
4151
|
-
|
4152
|
-
|
4153
|
-
|
4154
|
-
|
4155
|
-
|
4156
|
-
|
4157
|
-
|
4158
|
-
|
4391
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T element) -> void
|
4392
|
+
{
|
4393
|
+
self[index] = element;
|
4394
|
+
});
|
4395
|
+
}
|
4396
|
+
else if constexpr (std::is_pointer_v<T> && !detail::is_wrapped_v<T>)
|
4397
|
+
{
|
4398
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T& element) -> void
|
4399
|
+
{
|
4400
|
+
self[index] = std::move(element);
|
4401
|
+
});
|
4402
|
+
}
|
4403
|
+
else
|
4404
|
+
{
|
4405
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, typename Buffer_T::Element_T& element) -> void
|
4406
|
+
{
|
4407
|
+
self[index] = element;
|
4408
|
+
});
|
4159
4409
|
}
|
4160
4410
|
|
4161
4411
|
return klass;
|
@@ -8509,7 +8759,6 @@ namespace Rice::detail
|
|
8509
8759
|
return base;
|
8510
8760
|
}
|
8511
8761
|
|
8512
|
-
|
8513
8762
|
inline std::string rubyClassName(const std::string& typeInfoName)
|
8514
8763
|
{
|
8515
8764
|
std::string base = cppClassName(typeInfoName);
|
@@ -9242,7 +9491,18 @@ namespace Rice::detail
|
|
9242
9491
|
if constexpr (std::is_member_object_pointer_v<Attribute_T>)
|
9243
9492
|
{
|
9244
9493
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
9245
|
-
|
9494
|
+
|
9495
|
+
if constexpr (std::is_fundamental_v<detail::intrinsic_type<To_Ruby_T>> ||
|
9496
|
+
(std::is_array_v<To_Ruby_T> && std::is_fundamental_v<std::remove_extent_t<To_Ruby_T>>))
|
9497
|
+
{
|
9498
|
+
return To_Ruby<To_Ruby_T>().convert(nativeSelf->*attribute_);
|
9499
|
+
}
|
9500
|
+
else
|
9501
|
+
{
|
9502
|
+
// If the attribute is an object return a reference to avoid a copy (and avoid issues with
|
9503
|
+
// attributes that are not assignable, copy constructible or move constructible)
|
9504
|
+
return To_Ruby<To_Ruby_T&>().convert(nativeSelf->*attribute_);
|
9505
|
+
}
|
9246
9506
|
}
|
9247
9507
|
else
|
9248
9508
|
{
|
@@ -9302,39 +9562,21 @@ namespace Rice::detail
|
|
9302
9562
|
template<typename Attribute_T>
|
9303
9563
|
inline VALUE NativeAttributeSet<Attribute_T>::operator()(size_t argc, const VALUE* argv, VALUE self)
|
9304
9564
|
{
|
9305
|
-
if constexpr (std::is_fundamental_v<intrinsic_type<Attr_T>> && std::is_pointer_v<Attr_T>)
|
9306
|
-
{
|
9307
|
-
static_assert(true, "An fundamental value, such as an integer, cannot be assigned to an attribute that is a pointer.");
|
9308
|
-
}
|
9309
|
-
else if constexpr (std::is_same_v<intrinsic_type<Attr_T>, std::string> && std::is_pointer_v<Attr_T>)
|
9310
|
-
{
|
9311
|
-
static_assert(true, "An string cannot be assigned to an attribute that is a pointer.");
|
9312
|
-
}
|
9313
|
-
|
9314
9565
|
if (argc != 1)
|
9315
9566
|
{
|
9316
9567
|
throw std::runtime_error("Incorrect number of parameters for setting attribute. Attribute: " + this->name_);
|
9317
9568
|
}
|
9318
9569
|
|
9319
9570
|
VALUE value = argv[0];
|
9320
|
-
|
9321
|
-
if constexpr (!std::is_null_pointer_v<Receiver_T>
|
9322
|
-
!std::is_const_v<Attr_T> &&
|
9323
|
-
(std::is_fundamental_v<Attr_T> || std::is_assignable_v<Attr_T, Attr_T>))
|
9571
|
+
|
9572
|
+
if constexpr (!std::is_null_pointer_v<Receiver_T>)
|
9324
9573
|
{
|
9325
9574
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
9326
9575
|
nativeSelf->*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
9327
9576
|
}
|
9328
|
-
else if constexpr (std::is_null_pointer_v<Receiver_T> &&
|
9329
|
-
!std::is_const_v<Attr_T> &&
|
9330
|
-
(std::is_fundamental_v<Attr_T> || std::is_assignable_v<Attr_T, Attr_T>))
|
9331
|
-
{
|
9332
|
-
*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
9333
|
-
}
|
9334
9577
|
else
|
9335
9578
|
{
|
9336
|
-
|
9337
|
-
throw std::invalid_argument("Could not set attribute. Attribute: " + this->name_);
|
9579
|
+
*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
9338
9580
|
}
|
9339
9581
|
|
9340
9582
|
return value;
|
@@ -9480,6 +9722,7 @@ namespace Rice::detail
|
|
9480
9722
|
#include <array>
|
9481
9723
|
#include <stdexcept>
|
9482
9724
|
#include <sstream>
|
9725
|
+
#include <tuple>
|
9483
9726
|
|
9484
9727
|
namespace Rice::detail
|
9485
9728
|
{
|
@@ -10223,6 +10466,7 @@ namespace Rice::detail
|
|
10223
10466
|
|
10224
10467
|
// ========= NativeCallbackFFI.ipp =========
|
10225
10468
|
#ifdef HAVE_LIBFFI
|
10469
|
+
#include <tuple>
|
10226
10470
|
#include <ffi.h>
|
10227
10471
|
|
10228
10472
|
namespace Rice::detail
|
@@ -12360,7 +12604,7 @@ namespace Rice
|
|
12360
12604
|
|
12361
12605
|
auto instances = unbound_instances();
|
12362
12606
|
for (auto instance: instances)
|
12363
|
-
{
|
12607
|
+
{
|
12364
12608
|
instance->set_value(klass);
|
12365
12609
|
}
|
12366
12610
|
instances.clear();
|
@@ -12539,7 +12783,7 @@ namespace Rice
|
|
12539
12783
|
return false;
|
12540
12784
|
}
|
12541
12785
|
}
|
12542
|
-
|
12786
|
+
|
12543
12787
|
template<typename Base_T>
|
12544
12788
|
inline Class get_superklass()
|
12545
12789
|
{
|
@@ -12579,7 +12823,7 @@ namespace Rice
|
|
12579
12823
|
Class superKlass = get_superklass<Base_T>();
|
12580
12824
|
return define_class_under<T, Base_T>(parent, id, superKlass);
|
12581
12825
|
}
|
12582
|
-
|
12826
|
+
|
12583
12827
|
template<typename T, typename Base_T>
|
12584
12828
|
inline Data_Type<T> define_class(char const* name)
|
12585
12829
|
{
|
@@ -12613,42 +12857,53 @@ namespace Rice
|
|
12613
12857
|
template <typename Attribute_T>
|
12614
12858
|
inline Data_Type<T>& Data_Type<T>::define_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
12615
12859
|
{
|
12616
|
-
|
12617
|
-
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
12618
|
-
|
12619
|
-
// Define native attribute getter
|
12620
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
12621
|
-
detail::NativeAttributeGet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
|
12622
|
-
|
12623
|
-
using Attr_T = typename detail::NativeAttributeSet<Attribute_T>::Attr_T;
|
12624
|
-
if constexpr (!std::is_const_v<Attr_T> &&
|
12625
|
-
(std::is_fundamental_v<Attr_T> || std::is_assignable_v<Attr_T, Attr_T>))
|
12626
|
-
{
|
12627
|
-
// Define native attribute setter
|
12628
|
-
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
12629
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass_, name, std::forward<Attribute_T>(attribute));
|
12630
|
-
}
|
12631
|
-
|
12632
|
-
return *this;
|
12860
|
+
return this->define_attr_internal<Attribute_T>(this->klass_, name, std::forward<Attribute_T>(attribute), access);
|
12633
12861
|
}
|
12634
12862
|
|
12635
12863
|
template <typename T>
|
12636
12864
|
template <typename Attribute_T>
|
12637
12865
|
inline Data_Type<T>& Data_Type<T>::define_singleton_attr(std::string name, Attribute_T attribute, AttrAccess access)
|
12638
12866
|
{
|
12639
|
-
// Make sure the Attribute type has been previously seen by Rice
|
12640
|
-
detail::verifyType<typename detail::attribute_traits<Attribute_T>::attr_type>();
|
12641
|
-
|
12642
|
-
// Define native attribute
|
12643
12867
|
VALUE singleton = detail::protect(rb_singleton_class, this->value());
|
12868
|
+
return this->define_attr_internal<Attribute_T>(singleton, name, std::forward<Attribute_T>(attribute), access);
|
12869
|
+
}
|
12644
12870
|
|
12645
|
-
|
12871
|
+
template <typename T>
|
12872
|
+
template <typename Attribute_T>
|
12873
|
+
inline Data_Type<T>& Data_Type<T>::define_attr_internal(VALUE klass, std::string name, Attribute_T attribute, AttrAccess access)
|
12874
|
+
{
|
12875
|
+
using Attr_T = typename detail::attribute_traits<Attribute_T>::attr_type;
|
12876
|
+
|
12877
|
+
// Make sure the Attribute type has been previously seen by Rice
|
12878
|
+
detail::verifyType<Attr_T>();
|
12879
|
+
|
12880
|
+
// Define attribute getter
|
12646
12881
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Read)
|
12647
|
-
|
12882
|
+
{
|
12883
|
+
detail::NativeAttributeGet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
12884
|
+
}
|
12648
12885
|
|
12649
|
-
// Define
|
12886
|
+
// Define attribute setter
|
12650
12887
|
if (access == AttrAccess::ReadWrite || access == AttrAccess::Write)
|
12651
|
-
|
12888
|
+
{
|
12889
|
+
if constexpr (std::is_const_v<Attr_T>)
|
12890
|
+
{
|
12891
|
+
throw std::runtime_error("Cannot define attribute writer for a const attribute: " + name);
|
12892
|
+
}
|
12893
|
+
else if constexpr (!std::is_fundamental_v<Attr_T> && !std::is_assignable_v<Attr_T, Attr_T>)
|
12894
|
+
{
|
12895
|
+
throw std::runtime_error("Cannot define attribute writer for a non assignable attribute: " + name);
|
12896
|
+
}
|
12897
|
+
else if constexpr (!std::is_fundamental_v<Attr_T> && !std::is_copy_constructible_v<Attr_T>)
|
12898
|
+
{
|
12899
|
+
throw std::runtime_error("Cannot define attribute writer for a non copy constructible attribute: " + name);
|
12900
|
+
}
|
12901
|
+
else
|
12902
|
+
{
|
12903
|
+
// Define native attribute setter
|
12904
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
12905
|
+
}
|
12906
|
+
}
|
12652
12907
|
|
12653
12908
|
return *this;
|
12654
12909
|
}
|