rice 4.6.0 → 4.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/CMakeLists.txt +0 -4
- data/Rakefile +2 -8
- data/bin/rice-doc.rb +212 -0
- data/bin/rice-rbs.rb +93 -0
- data/include/rice/rice.hpp +5221 -4009
- data/include/rice/stl.hpp +822 -295
- data/lib/rice/doc/cpp_reference.rb +166 -0
- data/lib/rice/doc/doxygen.rb +294 -0
- data/lib/rice/doc/mkdocs.rb +298 -0
- data/lib/rice/doc/rice.rb +29 -0
- data/lib/rice/doc/ruby.rb +37 -0
- data/lib/rice/doc.rb +5 -0
- data/lib/{make_rice_headers.rb → rice/make_rice_headers.rb} +3 -0
- data/lib/rice/native.rb +18 -0
- data/lib/rice/native_registry.rb +21 -0
- data/lib/rice/parameter.rb +7 -0
- data/lib/rice/rbs.rb +104 -0
- data/lib/rice/version.rb +1 -1
- data/lib/rice.rb +4 -0
- data/lib/rubygems/cmake_builder.rb +24 -27
- data/rice/Arg.hpp +4 -4
- data/rice/Arg.ipp +4 -4
- data/rice/Buffer.hpp +77 -28
- data/rice/Buffer.ipp +500 -183
- data/rice/Data_Object.ipp +101 -82
- data/rice/Data_Type.hpp +7 -6
- data/rice/Data_Type.ipp +77 -47
- data/rice/Enum.ipp +15 -21
- data/rice/Function.hpp +17 -0
- data/rice/Function.ipp +13 -0
- data/rice/Pointer.hpp +15 -0
- data/rice/Pointer.ipp +49 -0
- data/rice/Return.hpp +1 -1
- data/rice/Return.ipp +2 -2
- data/rice/api.hpp +30 -0
- data/rice/cpp_api/Array.hpp +2 -2
- data/rice/cpp_api/Array.ipp +50 -5
- data/rice/cpp_api/Class.hpp +0 -5
- data/rice/cpp_api/Class.ipp +19 -0
- data/rice/cpp_api/Hash.ipp +20 -0
- data/rice/cpp_api/Module.hpp +6 -3
- data/rice/cpp_api/Module.ipp +49 -11
- data/rice/cpp_api/Object.ipp +31 -2
- data/rice/cpp_api/String.hpp +1 -2
- data/rice/cpp_api/String.ipp +21 -1
- data/rice/cpp_api/Struct.ipp +5 -0
- data/rice/cpp_api/Symbol.ipp +34 -0
- data/rice/cpp_api/shared_methods.hpp +12 -12
- data/rice/detail/MethodInfo.hpp +4 -2
- data/rice/detail/MethodInfo.ipp +19 -3
- data/rice/detail/ModuleRegistry.hpp +18 -0
- data/rice/detail/ModuleRegistry.ipp +25 -0
- data/rice/detail/Native.hpp +45 -2
- data/rice/detail/Native.ipp +196 -2
- data/rice/detail/NativeAttributeGet.hpp +9 -4
- data/rice/detail/NativeAttributeGet.ipp +73 -8
- data/rice/detail/NativeAttributeSet.hpp +4 -0
- data/rice/detail/NativeAttributeSet.ipp +33 -23
- data/rice/detail/NativeCallbackFFI.ipp +3 -2
- data/rice/detail/NativeCallbackSimple.ipp +1 -1
- data/rice/detail/NativeFunction.hpp +11 -49
- data/rice/detail/NativeFunction.ipp +83 -379
- data/rice/detail/NativeInvoker.hpp +74 -0
- data/rice/detail/NativeInvoker.ipp +197 -0
- data/rice/detail/NativeIterator.hpp +4 -0
- data/rice/detail/NativeIterator.ipp +19 -0
- data/rice/detail/NativeMethod.hpp +97 -0
- data/rice/detail/NativeMethod.ipp +332 -0
- data/rice/detail/NativeProc.hpp +51 -0
- data/rice/detail/NativeProc.ipp +133 -0
- data/rice/detail/NativeRegistry.hpp +8 -0
- data/rice/detail/NativeRegistry.ipp +27 -0
- data/rice/detail/Parameter.hpp +47 -0
- data/rice/detail/Parameter.ipp +105 -0
- data/rice/detail/Proc.ipp +14 -13
- data/rice/detail/Registries.hpp +1 -0
- data/rice/detail/RubyType.hpp +0 -2
- data/rice/detail/RubyType.ipp +15 -33
- data/rice/detail/Type.hpp +44 -8
- data/rice/detail/Type.ipp +150 -49
- data/rice/detail/TypeRegistry.hpp +3 -0
- data/rice/detail/TypeRegistry.ipp +17 -27
- data/rice/detail/Types.ipp +430 -0
- data/rice/detail/Wrapper.hpp +12 -0
- data/rice/detail/Wrapper.ipp +45 -2
- data/rice/detail/from_ruby.ipp +567 -1073
- data/rice/detail/ruby.hpp +1 -0
- data/rice/detail/to_ruby.ipp +4 -635
- data/rice/libc/file.ipp +3 -6
- data/rice/rice.hpp +22 -12
- data/rice/rice_api/Arg.hpp +7 -0
- data/rice/rice_api/Arg.ipp +9 -0
- data/rice/rice_api/ModuleRegistry.hpp +7 -0
- data/rice/rice_api/ModuleRegistry.ipp +10 -0
- data/rice/rice_api/Native.hpp +7 -0
- data/rice/rice_api/Native.ipp +52 -0
- data/rice/rice_api/NativeRegistry.hpp +7 -0
- data/rice/rice_api/NativeRegistry.ipp +21 -0
- data/rice/rice_api/Parameter.hpp +7 -0
- data/rice/rice_api/Parameter.ipp +11 -0
- data/rice/rice_api/Registries.hpp +6 -0
- data/rice/rice_api/Registries.ipp +12 -0
- data/rice/rice_api/TypeRegistry.hpp +7 -0
- data/rice/rice_api/TypeRegistry.ipp +10 -0
- data/rice/stl/complex.ipp +35 -0
- data/rice/stl/exception.ipp +20 -7
- data/rice/stl/filesystem.hpp +6 -0
- data/rice/stl/filesystem.ipp +34 -0
- data/rice/stl/map.ipp +13 -21
- data/rice/stl/monostate.ipp +37 -1
- data/rice/stl/multimap.ipp +17 -24
- data/rice/stl/optional.ipp +47 -2
- data/rice/stl/pair.ipp +23 -58
- data/rice/stl/reference_wrapper.ipp +22 -1
- data/rice/stl/set.ipp +17 -9
- data/rice/stl/shared_ptr.ipp +44 -17
- data/rice/stl/string.ipp +175 -7
- data/rice/stl/string_view.ipp +5 -0
- data/rice/stl/tuple.ipp +38 -9
- data/rice/stl/unique_ptr.ipp +46 -2
- data/rice/stl/unordered_map.ipp +13 -21
- data/rice/stl/variant.ipp +47 -11
- data/rice/stl/vector.ipp +182 -104
- data/rice/stl.hpp +1 -0
- data/rice/traits/attribute_traits.hpp +6 -6
- data/rice/traits/function_traits.hpp +2 -2
- data/rice/traits/method_traits.hpp +5 -16
- data/rice/traits/rice_traits.hpp +36 -4
- data/rice.gemspec +11 -22
- data/test/embed_ruby.cpp +0 -3
- data/test/test_Array.cpp +38 -38
- data/test/test_Attribute.cpp +244 -10
- data/test/test_Buffer.cpp +344 -13
- data/test/test_Callback.cpp +2 -3
- data/test/test_Class.cpp +5 -5
- data/test/test_Data_Object.cpp +0 -55
- data/test/test_Data_Type.cpp +19 -30
- data/test/test_Enum.cpp +4 -46
- data/test/test_From_Ruby.cpp +89 -82
- data/test/test_GVL.cpp +109 -0
- data/test/test_Iterator.cpp +1 -1
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -3
- data/test/test_Module.cpp +8 -9
- data/test/test_Object.cpp +1 -1
- data/test/test_Overloads.cpp +3 -3
- data/test/test_Stl_Map.cpp +8 -8
- data/test/test_Stl_Multimap.cpp +4 -4
- data/test/test_Stl_Pair.cpp +5 -3
- data/test/test_Stl_SharedPtr.cpp +24 -12
- data/test/test_Stl_Tuple.cpp +1 -1
- data/test/test_Stl_UniquePtr.cpp +8 -0
- data/test/test_Stl_Unordered_Map.cpp +9 -9
- data/test/test_Stl_Variant.cpp +9 -3
- data/test/test_Stl_Vector.cpp +118 -13
- data/test/test_To_Ruby.cpp +35 -28
- data/test/test_Type.cpp +256 -53
- data/test/unittest.hpp +35 -0
- metadata +66 -34
- data/rice/Init.hpp +0 -8
- data/rice/Init.ipp +0 -8
- data/rice/detail/RubyFunction.hpp +0 -31
- data/rice/detail/RubyFunction.ipp +0 -76
- data/sample/callbacks/extconf.rb +0 -5
- data/sample/callbacks/sample_callbacks.cpp +0 -35
- data/sample/callbacks/test.rb +0 -28
- data/sample/enum/extconf.rb +0 -5
- data/sample/enum/sample_enum.cpp +0 -40
- data/sample/enum/test.rb +0 -8
- data/sample/inheritance/animals.cpp +0 -82
- data/sample/inheritance/extconf.rb +0 -5
- data/sample/inheritance/test.rb +0 -7
- data/sample/map/extconf.rb +0 -5
- data/sample/map/map.cpp +0 -73
- data/sample/map/test.rb +0 -7
- data/test/ext/t1/Foo.hpp +0 -10
- data/test/ext/t1/extconf.rb +0 -4
- data/test/ext/t1/t1.cpp +0 -13
- data/test/ext/t2/extconf.rb +0 -4
- data/test/ext/t2/t2.cpp +0 -11
- data/test/ruby/test_callbacks_sample.rb +0 -28
- data/test/ruby/test_multiple_extensions.rb +0 -18
- data/test/ruby/test_multiple_extensions_same_class.rb +0 -14
- data/test/ruby/test_multiple_extensions_with_inheritance.rb +0 -20
- /data/test/{test_Stl_Type.cpp → test_Stl_Type_Info.cpp} +0 -0
data/rice/Buffer.ipp
CHANGED
|
@@ -2,35 +2,52 @@ namespace Rice
|
|
|
2
2
|
{
|
|
3
3
|
// ---- Buffer<T> -------
|
|
4
4
|
template<typename T>
|
|
5
|
-
inline Buffer<T
|
|
5
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::Buffer(T* pointer) : m_buffer(pointer)
|
|
6
6
|
{
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
template<typename T>
|
|
10
|
-
inline Buffer<T
|
|
10
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_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
|
|
15
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
16
|
+
{
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
template <typename T>
|
|
20
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::Buffer(VALUE value, size_t size)
|
|
16
21
|
{
|
|
17
22
|
if constexpr (std::is_fundamental_v<T>)
|
|
18
23
|
{
|
|
19
|
-
this->
|
|
24
|
+
this->fromBuiltinType(value, size);
|
|
20
25
|
}
|
|
21
26
|
else
|
|
22
27
|
{
|
|
23
|
-
this->
|
|
28
|
+
this->fromWrappedType(value, size);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
template <typename T>
|
|
33
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::~Buffer()
|
|
34
|
+
{
|
|
35
|
+
if constexpr (std::is_destructible_v<T>)
|
|
36
|
+
{
|
|
37
|
+
if (this->m_owner)
|
|
38
|
+
{
|
|
39
|
+
delete[] this->m_buffer;
|
|
40
|
+
}
|
|
24
41
|
}
|
|
25
42
|
}
|
|
26
43
|
|
|
27
44
|
template <typename T>
|
|
28
|
-
inline void Buffer<T
|
|
45
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::fromBuiltinType(VALUE value, size_t size)
|
|
29
46
|
{
|
|
30
47
|
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
|
31
48
|
using RubyType_T = typename detail::RubyType<Intrinsic_T>;
|
|
32
|
-
ruby_value_type valueType = rb_type(value);
|
|
33
49
|
|
|
50
|
+
ruby_value_type valueType = rb_type(value);
|
|
34
51
|
switch (valueType)
|
|
35
52
|
{
|
|
36
53
|
case RUBY_T_ARRAY:
|
|
@@ -39,9 +56,19 @@ namespace Rice
|
|
|
39
56
|
this->m_size = array.size();
|
|
40
57
|
this->m_buffer = new T[this->m_size]();
|
|
41
58
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
if constexpr (std::is_fundamental_v<T>)
|
|
60
|
+
{
|
|
61
|
+
String packed = array.pack<Intrinsic_T>();
|
|
62
|
+
memcpy((void*)this->m_buffer, RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
|
|
63
|
+
}
|
|
64
|
+
else
|
|
65
|
+
{
|
|
66
|
+
detail::From_Ruby<Intrinsic_T> fromRuby;
|
|
67
|
+
for (int i = 0; i < array.size(); i++)
|
|
68
|
+
{
|
|
69
|
+
this->m_buffer[0] = fromRuby.convert(array[i]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
45
72
|
this->m_owner = true;
|
|
46
73
|
break;
|
|
47
74
|
}
|
|
@@ -57,21 +84,21 @@ namespace Rice
|
|
|
57
84
|
{
|
|
58
85
|
this->m_buffer = new T[this->m_size]();
|
|
59
86
|
}
|
|
60
|
-
memcpy(this->m_buffer, RSTRING_PTR(value), this->m_size);
|
|
87
|
+
memcpy((void*)this->m_buffer, RSTRING_PTR(value), this->m_size);
|
|
61
88
|
|
|
62
89
|
this->m_owner = true;
|
|
63
90
|
break;
|
|
64
91
|
}
|
|
65
92
|
case RUBY_T_DATA:
|
|
66
93
|
{
|
|
67
|
-
if (Data_Type<T
|
|
94
|
+
if (Data_Type<Pointer<T>>::is_descendant(value))
|
|
68
95
|
{
|
|
69
|
-
this->
|
|
70
|
-
this->m_buffer = new T[this->m_size]();
|
|
71
|
-
this->m_buffer[0] = *detail::unwrap<T>(value, Data_Type<T>::ruby_data_type(), false);
|
|
96
|
+
this->m_buffer = detail::unwrap<T>(value, Data_Type<Pointer<T>>::ruby_data_type(), false);
|
|
72
97
|
this->m_owner = false;
|
|
98
|
+
this->m_size = size;
|
|
73
99
|
break;
|
|
74
100
|
}
|
|
101
|
+
[[fallthrough]];
|
|
75
102
|
}
|
|
76
103
|
default:
|
|
77
104
|
{
|
|
@@ -82,13 +109,14 @@ namespace Rice
|
|
|
82
109
|
T data = detail::protect(RubyType_T::fromRuby, value);
|
|
83
110
|
this->m_size = 1;
|
|
84
111
|
this->m_buffer = new T[this->m_size]();
|
|
85
|
-
memcpy(this->m_buffer, &data, sizeof(T));
|
|
112
|
+
memcpy((void*)this->m_buffer, &data, sizeof(T));
|
|
86
113
|
this->m_owner = true;
|
|
87
114
|
break;
|
|
88
115
|
}
|
|
89
116
|
else
|
|
90
117
|
{
|
|
91
|
-
|
|
118
|
+
detail::TypeMapper<T> typeMapper;
|
|
119
|
+
std::string typeName = typeMapper.name();
|
|
92
120
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
|
93
121
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
94
122
|
}
|
|
@@ -97,7 +125,7 @@ namespace Rice
|
|
|
97
125
|
}
|
|
98
126
|
|
|
99
127
|
template <typename T>
|
|
100
|
-
inline void Buffer<T
|
|
128
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::fromWrappedType(VALUE value, size_t size)
|
|
101
129
|
{
|
|
102
130
|
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
|
103
131
|
|
|
@@ -108,20 +136,68 @@ namespace Rice
|
|
|
108
136
|
Array array(value);
|
|
109
137
|
this->m_size = array.size();
|
|
110
138
|
|
|
111
|
-
// Use operator new[] to allocate memory but not call constructors
|
|
112
|
-
|
|
139
|
+
// Use operator new[] to allocate memory but not call constructors.
|
|
140
|
+
size_t size = sizeof(T) * this->m_size;
|
|
141
|
+
this->m_buffer = static_cast<T*>(operator new[](size));
|
|
113
142
|
|
|
114
143
|
detail::From_Ruby<Intrinsic_T> fromRuby;
|
|
115
144
|
|
|
116
145
|
for (size_t i = 0; i < this->m_size; i++)
|
|
117
146
|
{
|
|
118
|
-
|
|
147
|
+
// Construct objects in allocated memory using move or copy construction
|
|
148
|
+
if constexpr (std::is_move_constructible_v<T>)
|
|
149
|
+
{
|
|
150
|
+
new (&this->m_buffer[i]) T(std::move(fromRuby.convert(array[i].value())));
|
|
151
|
+
}
|
|
152
|
+
else if constexpr (std::is_copy_constructible_v<T>)
|
|
153
|
+
{
|
|
154
|
+
new (&this->m_buffer[i]) T(fromRuby.convert(array[i].value()));
|
|
155
|
+
}
|
|
156
|
+
else
|
|
157
|
+
{
|
|
158
|
+
throw Exception(rb_eTypeError, "Cannot construct object of type %s - type is not move or copy constructible",
|
|
159
|
+
detail::TypeMapper<Intrinsic_T>().name().c_str());
|
|
160
|
+
}
|
|
119
161
|
}
|
|
120
162
|
break;
|
|
121
163
|
}
|
|
164
|
+
case RUBY_T_DATA:
|
|
165
|
+
{
|
|
166
|
+
if (Data_Type<Pointer<Intrinsic_T>>::is_descendant(value))
|
|
167
|
+
{
|
|
168
|
+
this->m_buffer = detail::unwrap<T>(value, Data_Type<Pointer<Intrinsic_T>>::ruby_data_type(), false);
|
|
169
|
+
this->m_owner = false;
|
|
170
|
+
this->m_size = size;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
else if (Data_Type<Intrinsic_T>::is_descendant(value))
|
|
174
|
+
{
|
|
175
|
+
this->m_buffer = detail::unwrap<T>(value, Data_Type<Intrinsic_T>::ruby_data_type(), false);
|
|
176
|
+
this->m_owner = false;
|
|
177
|
+
this->m_size = size;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
case RUBY_T_STRING:
|
|
182
|
+
{
|
|
183
|
+
// This special case is a bit ugly...
|
|
184
|
+
if constexpr (std::is_same_v<detail::intrinsic_type<T>, std::string>)
|
|
185
|
+
{
|
|
186
|
+
// FromRuby owns the converted string so we need to keep it alive until we get to the copy constructor
|
|
187
|
+
// two lines down
|
|
188
|
+
detail::From_Ruby<T*> fromRuby;
|
|
189
|
+
T* converted = fromRuby.convert(value);
|
|
190
|
+
this->m_buffer = new T[1]{ *converted };
|
|
191
|
+
this->m_owner = true;
|
|
192
|
+
this->m_size = 1;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
[[fallthrough]];
|
|
196
|
+
}
|
|
122
197
|
default:
|
|
123
198
|
{
|
|
124
|
-
|
|
199
|
+
detail::TypeMapper<T> typeMapper;
|
|
200
|
+
std::string typeName = typeMapper.name();
|
|
125
201
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
|
126
202
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
127
203
|
}
|
|
@@ -129,19 +205,7 @@ namespace Rice
|
|
|
129
205
|
}
|
|
130
206
|
|
|
131
207
|
template <typename T>
|
|
132
|
-
inline Buffer<T
|
|
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)
|
|
208
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::Buffer(Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
|
|
145
209
|
{
|
|
146
210
|
other.m_buffer = nullptr;
|
|
147
211
|
other.m_size = 0;
|
|
@@ -149,7 +213,7 @@ namespace Rice
|
|
|
149
213
|
}
|
|
150
214
|
|
|
151
215
|
template <typename T>
|
|
152
|
-
inline Buffer<T
|
|
216
|
+
inline Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>& Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::operator=(Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>&& other)
|
|
153
217
|
{
|
|
154
218
|
this->m_buffer = other.m_buffer;
|
|
155
219
|
other.m_buffer = nullptr;
|
|
@@ -164,57 +228,54 @@ namespace Rice
|
|
|
164
228
|
}
|
|
165
229
|
|
|
166
230
|
template <typename T>
|
|
167
|
-
inline size_t Buffer<T
|
|
231
|
+
inline size_t Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::size() const
|
|
168
232
|
{
|
|
169
233
|
return this->m_size;
|
|
170
234
|
}
|
|
171
235
|
|
|
172
236
|
template <typename T>
|
|
173
|
-
|
|
237
|
+
inline T* Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::ptr()
|
|
174
238
|
{
|
|
175
|
-
this->
|
|
239
|
+
return this->m_buffer;
|
|
176
240
|
}
|
|
177
241
|
|
|
178
242
|
template <typename T>
|
|
179
|
-
inline T
|
|
243
|
+
inline T& Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::reference()
|
|
180
244
|
{
|
|
181
|
-
return this->m_buffer;
|
|
245
|
+
return *this->m_buffer;
|
|
182
246
|
}
|
|
183
247
|
|
|
184
248
|
template <typename T>
|
|
185
|
-
inline T
|
|
249
|
+
inline T* Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::release()
|
|
186
250
|
{
|
|
187
|
-
|
|
251
|
+
this->m_owner = false;
|
|
252
|
+
return this->m_buffer;
|
|
188
253
|
}
|
|
189
254
|
|
|
190
255
|
template <typename T>
|
|
191
|
-
inline bool Buffer<T
|
|
256
|
+
inline bool Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::isOwner() const
|
|
192
257
|
{
|
|
193
258
|
return this->m_owner;
|
|
194
259
|
}
|
|
195
260
|
|
|
196
261
|
template <typename T>
|
|
197
|
-
inline void Buffer<T
|
|
262
|
+
inline void Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::setOwner(bool value)
|
|
198
263
|
{
|
|
199
264
|
this->m_owner = value;
|
|
200
265
|
}
|
|
201
266
|
|
|
202
|
-
template
|
|
203
|
-
inline
|
|
267
|
+
template<typename T>
|
|
268
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::toString() const
|
|
204
269
|
{
|
|
205
|
-
|
|
206
|
-
|
|
270
|
+
detail::TypeMapper<T*> typeMapper;
|
|
271
|
+
std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
207
272
|
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
}*/
|
|
273
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
274
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
275
|
+
}
|
|
215
276
|
|
|
216
277
|
template<typename T>
|
|
217
|
-
inline VALUE Buffer<T
|
|
278
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::bytes(size_t count) const
|
|
218
279
|
{
|
|
219
280
|
if (!this->m_buffer)
|
|
220
281
|
{
|
|
@@ -228,13 +289,13 @@ namespace Rice
|
|
|
228
289
|
}
|
|
229
290
|
|
|
230
291
|
template<typename T>
|
|
231
|
-
inline VALUE Buffer<T
|
|
292
|
+
inline VALUE Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::bytes() const
|
|
232
293
|
{
|
|
233
294
|
return this->bytes(this->m_size);
|
|
234
295
|
}
|
|
235
296
|
|
|
236
297
|
template<typename T>
|
|
237
|
-
inline Array Buffer<T
|
|
298
|
+
inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::toArray(size_t count) const
|
|
238
299
|
{
|
|
239
300
|
if (!this->m_buffer)
|
|
240
301
|
{
|
|
@@ -254,20 +315,20 @@ namespace Rice
|
|
|
254
315
|
|
|
255
316
|
for (; ptr < end; ptr++)
|
|
256
317
|
{
|
|
257
|
-
result.push(*ptr);
|
|
318
|
+
result.push(*ptr, false);
|
|
258
319
|
}
|
|
259
320
|
return result;
|
|
260
321
|
}
|
|
261
322
|
}
|
|
262
323
|
|
|
263
324
|
template<typename T>
|
|
264
|
-
inline Array Buffer<T
|
|
325
|
+
inline Array Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::toArray() const
|
|
265
326
|
{
|
|
266
327
|
return this->toArray(this->m_size);
|
|
267
328
|
}
|
|
268
329
|
|
|
269
330
|
template<typename T>
|
|
270
|
-
inline T Buffer<T
|
|
331
|
+
inline T& Buffer<T, std::enable_if_t<!std::is_pointer_v<T> && !std::is_void_v<T>>>::operator[](size_t index)
|
|
271
332
|
{
|
|
272
333
|
if (index >= this->m_size)
|
|
273
334
|
{
|
|
@@ -277,62 +338,79 @@ namespace Rice
|
|
|
277
338
|
return this->m_buffer[index];
|
|
278
339
|
}
|
|
279
340
|
|
|
341
|
+
// ---- Buffer<T*> - Builtin -------
|
|
280
342
|
template<typename T>
|
|
281
|
-
inline
|
|
343
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
|
282
344
|
{
|
|
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
345
|
}
|
|
290
346
|
|
|
291
|
-
// ---- Buffer<T*> -------
|
|
292
347
|
template<typename T>
|
|
293
|
-
inline Buffer<T
|
|
348
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
|
|
294
349
|
{
|
|
295
350
|
}
|
|
296
351
|
|
|
297
|
-
template<typename T>
|
|
298
|
-
inline Buffer<T
|
|
352
|
+
template <typename T>
|
|
353
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
299
354
|
{
|
|
300
355
|
}
|
|
301
|
-
|
|
356
|
+
|
|
302
357
|
template <typename T>
|
|
303
|
-
inline Buffer<T
|
|
358
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::Buffer(VALUE value, size_t size)
|
|
304
359
|
{
|
|
305
|
-
|
|
360
|
+
using Intrinsic_T = typename detail::intrinsic_type<T>;
|
|
306
361
|
|
|
362
|
+
ruby_value_type valueType = rb_type(value);
|
|
307
363
|
switch (valueType)
|
|
308
364
|
{
|
|
309
365
|
case RUBY_T_ARRAY:
|
|
310
366
|
{
|
|
311
367
|
Array outer(value);
|
|
368
|
+
|
|
369
|
+
// Allocate outer buffer
|
|
312
370
|
this->m_size = outer.size();
|
|
313
|
-
this->
|
|
371
|
+
this->m_buffer = new T*[this->m_size]();
|
|
314
372
|
|
|
315
373
|
for (size_t i = 0; i < this->m_size; i++)
|
|
316
374
|
{
|
|
317
375
|
// Check the inner value is also an array
|
|
318
376
|
Array inner(outer[i].value());
|
|
319
377
|
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// And update the outer array
|
|
324
|
-
this->m_outer[i] = buffer.ptr();
|
|
378
|
+
// Allocate inner buffer
|
|
379
|
+
this->m_buffer[i] = new T[inner.size()]();
|
|
325
380
|
|
|
326
|
-
|
|
327
|
-
|
|
381
|
+
if constexpr (std::is_fundamental_v<Intrinsic_T>)
|
|
382
|
+
{
|
|
383
|
+
String packed = inner.pack<Intrinsic_T>();
|
|
384
|
+
memcpy((void*)this->m_buffer[i], RSTRING_PTR(packed.value()), RSTRING_LEN(packed.value()));
|
|
385
|
+
}
|
|
386
|
+
else
|
|
387
|
+
{
|
|
388
|
+
detail::From_Ruby<Intrinsic_T*> fromRuby;
|
|
389
|
+
for (int i = 0; i < inner.size(); i++)
|
|
390
|
+
{
|
|
391
|
+
this->m_buffer[0] = fromRuby.convert(inner[i].value());
|
|
392
|
+
}
|
|
393
|
+
}
|
|
328
394
|
}
|
|
329
395
|
|
|
330
396
|
this->m_owner = true;
|
|
331
397
|
break;
|
|
332
398
|
}
|
|
399
|
+
case RUBY_T_DATA:
|
|
400
|
+
{
|
|
401
|
+
if (Data_Type<Pointer<T*>>::is_descendant(value))
|
|
402
|
+
{
|
|
403
|
+
this->m_buffer = detail::unwrap<T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), false);
|
|
404
|
+
this->m_owner = false;
|
|
405
|
+
this->m_size = size;
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
[[fallthrough]];
|
|
409
|
+
}
|
|
333
410
|
default:
|
|
334
411
|
{
|
|
335
|
-
|
|
412
|
+
detail::TypeMapper<T> typeMapper;
|
|
413
|
+
std::string typeName = typeMapper.name();
|
|
336
414
|
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
|
337
415
|
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
338
416
|
}
|
|
@@ -340,32 +418,33 @@ namespace Rice
|
|
|
340
418
|
}
|
|
341
419
|
|
|
342
420
|
template <typename T>
|
|
343
|
-
inline Buffer<T
|
|
421
|
+
inline Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::~Buffer()
|
|
344
422
|
{
|
|
345
423
|
if (this->m_owner)
|
|
346
424
|
{
|
|
347
|
-
|
|
425
|
+
for (size_t i = 0; i < this->m_size; i++)
|
|
426
|
+
{
|
|
427
|
+
delete this->m_buffer[i];
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
delete[] this->m_buffer;
|
|
348
431
|
}
|
|
349
432
|
}
|
|
350
433
|
|
|
351
434
|
template <typename T>
|
|
352
|
-
inline Buffer<T
|
|
353
|
-
|
|
435
|
+
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),
|
|
436
|
+
m_buffer(other.m_buffer)
|
|
354
437
|
{
|
|
355
|
-
other.
|
|
356
|
-
other.m_inner.clear();
|
|
438
|
+
other.m_buffer = nullptr;
|
|
357
439
|
other.m_size = 0;
|
|
358
440
|
other.m_owner = false;
|
|
359
441
|
}
|
|
360
442
|
|
|
361
443
|
template <typename T>
|
|
362
|
-
inline Buffer<T
|
|
444
|
+
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
445
|
{
|
|
364
|
-
this->
|
|
365
|
-
other.
|
|
366
|
-
|
|
367
|
-
this->m_inner = std::move(other.m_inner);
|
|
368
|
-
other.m_inner.clear();
|
|
446
|
+
this->m_buffer = other.m_buffer;
|
|
447
|
+
other.m_buffer = nullptr;
|
|
369
448
|
|
|
370
449
|
this->m_size = other.m_size;
|
|
371
450
|
other.m_size = 0;
|
|
@@ -377,80 +456,269 @@ namespace Rice
|
|
|
377
456
|
}
|
|
378
457
|
|
|
379
458
|
template <typename T>
|
|
380
|
-
inline
|
|
459
|
+
inline T* Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::operator[](size_t index)
|
|
381
460
|
{
|
|
382
|
-
return this->
|
|
461
|
+
return this->m_buffer[index];
|
|
383
462
|
}
|
|
384
463
|
|
|
385
464
|
template <typename T>
|
|
386
|
-
inline size_t Buffer<T
|
|
465
|
+
inline size_t Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::size() const
|
|
387
466
|
{
|
|
388
467
|
return this->m_size;
|
|
389
468
|
}
|
|
390
469
|
|
|
391
470
|
template <typename T>
|
|
392
|
-
|
|
471
|
+
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::ptr()
|
|
393
472
|
{
|
|
394
|
-
this->
|
|
473
|
+
return this->m_buffer;
|
|
395
474
|
}
|
|
396
475
|
|
|
397
476
|
template <typename T>
|
|
398
|
-
inline T** Buffer<T
|
|
477
|
+
inline T** Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::release()
|
|
399
478
|
{
|
|
400
|
-
|
|
479
|
+
this->m_owner = false;
|
|
480
|
+
return this->m_buffer;
|
|
401
481
|
}
|
|
402
482
|
|
|
403
483
|
template <typename T>
|
|
404
|
-
inline bool Buffer<T
|
|
484
|
+
inline bool Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::isOwner() const
|
|
405
485
|
{
|
|
406
486
|
return this->m_owner;
|
|
407
487
|
}
|
|
408
488
|
|
|
409
489
|
template <typename T>
|
|
410
|
-
inline void Buffer<T
|
|
490
|
+
inline void Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::setOwner(bool value)
|
|
411
491
|
{
|
|
412
492
|
this->m_owner = value;
|
|
413
493
|
}
|
|
414
494
|
|
|
495
|
+
template<typename T>
|
|
496
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toString() const
|
|
497
|
+
{
|
|
498
|
+
detail::TypeMapper<T*> typeMapper;
|
|
499
|
+
std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
500
|
+
|
|
501
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
502
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
template<typename T>
|
|
506
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes(size_t count) const
|
|
507
|
+
{
|
|
508
|
+
if (!this->m_buffer)
|
|
509
|
+
{
|
|
510
|
+
return Qnil;
|
|
511
|
+
}
|
|
512
|
+
else
|
|
513
|
+
{
|
|
514
|
+
T** begin = this->m_buffer;
|
|
515
|
+
long length = (long)(count * sizeof(T*));
|
|
516
|
+
return detail::protect(rb_str_new_static, (const char*)*begin, length);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
template<typename T>
|
|
521
|
+
inline VALUE Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::bytes() const
|
|
522
|
+
{
|
|
523
|
+
return this->bytes(this->m_size);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
template<typename T>
|
|
527
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray(size_t count) const
|
|
528
|
+
{
|
|
529
|
+
if (!this->m_buffer)
|
|
530
|
+
{
|
|
531
|
+
return Qnil;
|
|
532
|
+
}
|
|
533
|
+
else
|
|
534
|
+
{
|
|
535
|
+
Array result;
|
|
536
|
+
|
|
537
|
+
T** ptr = this->m_buffer;
|
|
538
|
+
T** end = this->m_buffer + count;
|
|
539
|
+
|
|
540
|
+
for (; ptr < end; ptr++)
|
|
541
|
+
{
|
|
542
|
+
Buffer<T> buffer(*ptr);
|
|
543
|
+
result.push(std::move(buffer), true);
|
|
544
|
+
}
|
|
545
|
+
return result;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
template<typename T>
|
|
550
|
+
inline Array Buffer<T*, std::enable_if_t<!detail::is_wrapped_v<T>>>::toArray() const
|
|
551
|
+
{
|
|
552
|
+
return this->toArray(this->m_size);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// ---- Buffer<T*> - Wrapped -------
|
|
556
|
+
template<typename T>
|
|
557
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer) : m_buffer(pointer)
|
|
558
|
+
{
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
template<typename T>
|
|
562
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(T** pointer, size_t size) : m_buffer(pointer), m_size(size)
|
|
563
|
+
{
|
|
564
|
+
}
|
|
565
|
+
|
|
415
566
|
template <typename T>
|
|
416
|
-
inline
|
|
567
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
568
|
+
{
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
template <typename T>
|
|
572
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::Buffer(VALUE value, size_t size)
|
|
573
|
+
{
|
|
574
|
+
ruby_value_type valueType = rb_type(value);
|
|
575
|
+
switch (valueType)
|
|
576
|
+
{
|
|
577
|
+
case RUBY_T_ARRAY:
|
|
578
|
+
{
|
|
579
|
+
Array array(value);
|
|
580
|
+
this->m_size = array.size();
|
|
581
|
+
this->m_buffer = new T * [this->m_size]();
|
|
582
|
+
|
|
583
|
+
detail::From_Ruby<T*> fromRuby;
|
|
584
|
+
|
|
585
|
+
for (size_t i = 0; i < this->m_size; i++)
|
|
586
|
+
{
|
|
587
|
+
this->m_buffer[i] = fromRuby.convert(array[i].value());
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
this->m_owner = true;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
case RUBY_T_DATA:
|
|
594
|
+
{
|
|
595
|
+
if (Data_Type<Pointer<T*>>::is_descendant(value))
|
|
596
|
+
{
|
|
597
|
+
this->m_buffer = detail::unwrap<T*>(value, Data_Type<Pointer<T*>>::ruby_data_type(), false);
|
|
598
|
+
this->m_owner = false;
|
|
599
|
+
this->m_size = size;
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
default:
|
|
604
|
+
{
|
|
605
|
+
detail::TypeMapper<T> typeMapper;
|
|
606
|
+
std::string typeName = typeMapper.name();
|
|
607
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
|
608
|
+
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
template <typename T>
|
|
614
|
+
inline Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::~Buffer()
|
|
615
|
+
{
|
|
616
|
+
if (this->m_owner)
|
|
617
|
+
{
|
|
618
|
+
delete[] this->m_buffer;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
template <typename T>
|
|
623
|
+
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),
|
|
624
|
+
m_buffer(other.m_buffer)
|
|
625
|
+
{
|
|
626
|
+
other.m_buffer = nullptr;
|
|
627
|
+
other.m_size = 0;
|
|
628
|
+
other.m_owner = false;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
template <typename T>
|
|
632
|
+
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)
|
|
633
|
+
{
|
|
634
|
+
this->m_buffer = other.m_buffer;
|
|
635
|
+
other.m_buffer = nullptr;
|
|
636
|
+
|
|
637
|
+
this->m_size = other.m_size;
|
|
638
|
+
other.m_size = 0;
|
|
639
|
+
|
|
640
|
+
this->m_owner = other.m_owner;
|
|
641
|
+
other.m_owner = false;
|
|
642
|
+
|
|
643
|
+
return *this;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
template <typename T>
|
|
647
|
+
inline T* Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::operator[](size_t index)
|
|
648
|
+
{
|
|
649
|
+
if (index >= this->m_size)
|
|
650
|
+
{
|
|
651
|
+
throw Exception(rb_eIndexError, "index %ld outside of bounds: 0..%ld", index, this->m_size);
|
|
652
|
+
}
|
|
653
|
+
return this->m_buffer[index];
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
template <typename T>
|
|
657
|
+
inline size_t Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::size() const
|
|
658
|
+
{
|
|
659
|
+
return this->m_size;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
template <typename T>
|
|
663
|
+
inline T** Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::ptr()
|
|
664
|
+
{
|
|
665
|
+
return this->m_buffer;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
template <typename T>
|
|
669
|
+
inline T** Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::release()
|
|
417
670
|
{
|
|
418
671
|
this->m_owner = false;
|
|
672
|
+
return this->m_buffer;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
template <typename T>
|
|
676
|
+
inline bool Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::isOwner() const
|
|
677
|
+
{
|
|
678
|
+
return this->m_owner;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
template <typename T>
|
|
682
|
+
inline void Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::setOwner(bool value)
|
|
683
|
+
{
|
|
684
|
+
this->m_owner = value;
|
|
419
685
|
}
|
|
420
686
|
|
|
421
|
-
|
|
422
|
-
inline VALUE Buffer<T
|
|
687
|
+
template<typename T>
|
|
688
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toString() const
|
|
423
689
|
{
|
|
424
|
-
|
|
425
|
-
std::string
|
|
426
|
-
|
|
427
|
-
|
|
690
|
+
detail::TypeMapper<T*> typeMapper;
|
|
691
|
+
std::string description = "Buffer<type: " + typeMapper.simplifiedName() + ", size: " + std::to_string(this->m_size) + ">";
|
|
692
|
+
|
|
693
|
+
// We can't use To_Ruby because To_Ruby depends on Buffer - ie a circular reference
|
|
694
|
+
return detail::protect(rb_utf8_str_new_cstr, description.c_str());
|
|
695
|
+
}
|
|
428
696
|
|
|
429
697
|
template<typename T>
|
|
430
|
-
inline VALUE Buffer<T
|
|
698
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes(size_t count) const
|
|
431
699
|
{
|
|
432
|
-
if (!this->
|
|
700
|
+
if (!this->m_buffer)
|
|
433
701
|
{
|
|
434
702
|
return Qnil;
|
|
435
703
|
}
|
|
436
704
|
else
|
|
437
705
|
{
|
|
438
|
-
T** begin = this->
|
|
706
|
+
T** begin = this->m_buffer;
|
|
439
707
|
long length = (long)(count * sizeof(T*));
|
|
440
708
|
return detail::protect(rb_str_new_static, (const char*)*begin, length);
|
|
441
709
|
}
|
|
442
710
|
}
|
|
443
711
|
|
|
444
712
|
template<typename T>
|
|
445
|
-
inline VALUE Buffer<T
|
|
713
|
+
inline VALUE Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::bytes() const
|
|
446
714
|
{
|
|
447
715
|
return this->bytes(this->m_size);
|
|
448
716
|
}
|
|
449
717
|
|
|
450
718
|
template<typename T>
|
|
451
|
-
inline Array Buffer<T
|
|
719
|
+
inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray(size_t count) const
|
|
452
720
|
{
|
|
453
|
-
if (!this->
|
|
721
|
+
if (!this->m_buffer)
|
|
454
722
|
{
|
|
455
723
|
return Qnil;
|
|
456
724
|
}
|
|
@@ -458,35 +726,70 @@ namespace Rice
|
|
|
458
726
|
{
|
|
459
727
|
Array result;
|
|
460
728
|
|
|
461
|
-
T** ptr = this->
|
|
462
|
-
T** end = this->
|
|
729
|
+
T** ptr = this->m_buffer;
|
|
730
|
+
T** end = this->m_buffer + count;
|
|
463
731
|
|
|
464
732
|
for (; ptr < end; ptr++)
|
|
465
733
|
{
|
|
466
|
-
|
|
467
|
-
result.push(std::move(buffer));
|
|
734
|
+
result.push(*ptr, false);
|
|
468
735
|
}
|
|
469
736
|
return result;
|
|
470
737
|
}
|
|
471
738
|
}
|
|
472
739
|
|
|
473
740
|
template<typename T>
|
|
474
|
-
inline Array Buffer<T
|
|
741
|
+
inline Array Buffer<T*, std::enable_if_t<detail::is_wrapped_v<T>>>::toArray() const
|
|
475
742
|
{
|
|
476
743
|
return this->toArray(this->m_size);
|
|
477
744
|
}
|
|
478
745
|
|
|
479
746
|
// ---- Buffer<void> -------
|
|
480
|
-
|
|
747
|
+
template<typename T>
|
|
748
|
+
inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(VALUE value) : Buffer(value, 0)
|
|
749
|
+
{
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
template<typename T>
|
|
753
|
+
inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(VALUE value, size_t size)
|
|
754
|
+
{
|
|
755
|
+
ruby_value_type valueType = rb_type(value);
|
|
756
|
+
|
|
757
|
+
switch (valueType)
|
|
758
|
+
{
|
|
759
|
+
case RUBY_T_STRING:
|
|
760
|
+
{
|
|
761
|
+
this->m_size = RSTRING_LEN(value);
|
|
762
|
+
this->m_buffer = ::operator new(this->m_size);
|
|
763
|
+
memcpy((void*)this->m_buffer, RSTRING_PTR(value), this->m_size);
|
|
764
|
+
|
|
765
|
+
this->m_owner = true;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
default:
|
|
769
|
+
{
|
|
770
|
+
detail::TypeMapper<void> typeMapper;
|
|
771
|
+
std::string typeName = typeMapper.name();
|
|
772
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s*)",
|
|
773
|
+
detail::protect(rb_obj_classname, value), typeName.c_str());
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
template<typename T>
|
|
779
|
+
inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(T* pointer) : m_buffer(pointer)
|
|
481
780
|
{
|
|
482
781
|
}
|
|
483
782
|
|
|
484
|
-
|
|
783
|
+
template<typename T>
|
|
784
|
+
inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>::Buffer(Buffer<T, std::enable_if_t<std::is_void_v<T>>>&& other) : m_owner(other.m_owner), m_size(other.m_size), m_buffer(other.m_buffer)
|
|
485
785
|
{
|
|
486
786
|
other.m_buffer = nullptr;
|
|
787
|
+
other.m_size = 0;
|
|
788
|
+
other.m_owner = false;
|
|
487
789
|
}
|
|
488
790
|
|
|
489
|
-
|
|
791
|
+
template<typename T>
|
|
792
|
+
inline Buffer<T, std::enable_if_t<std::is_void_v<T>>>& Buffer<T, std::enable_if_t<std::is_void_v<T>>>::operator=(Buffer<T, std::enable_if_t<std::is_void_v<T>>>&& other)
|
|
490
793
|
{
|
|
491
794
|
this->m_buffer = other.m_buffer;
|
|
492
795
|
other.m_buffer = nullptr;
|
|
@@ -494,89 +797,108 @@ namespace Rice
|
|
|
494
797
|
return *this;
|
|
495
798
|
}
|
|
496
799
|
|
|
497
|
-
|
|
800
|
+
template<typename T>
|
|
801
|
+
inline size_t Buffer<T, std::enable_if_t<std::is_void_v<T>>>::size() const
|
|
802
|
+
{
|
|
803
|
+
return this->m_size;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
template<typename T>
|
|
807
|
+
inline T* Buffer<T, std::enable_if_t<std::is_void_v<T>>>::ptr()
|
|
498
808
|
{
|
|
499
809
|
return this->m_buffer;
|
|
500
810
|
}
|
|
501
811
|
|
|
812
|
+
template <typename T>
|
|
813
|
+
inline T* Buffer<T, std::enable_if_t<std::is_void_v<T>>>::release()
|
|
814
|
+
{
|
|
815
|
+
this->m_owner = false;
|
|
816
|
+
return this->m_buffer;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
template<typename T>
|
|
820
|
+
inline VALUE Buffer<T, std::enable_if_t<std::is_void_v<T>>>::bytes(size_t count) const
|
|
821
|
+
{
|
|
822
|
+
if (!this->m_buffer)
|
|
823
|
+
{
|
|
824
|
+
return Qnil;
|
|
825
|
+
}
|
|
826
|
+
else
|
|
827
|
+
{
|
|
828
|
+
return detail::protect(rb_usascii_str_new, (const char*)this->m_buffer, (long)count);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
template<typename T>
|
|
833
|
+
inline VALUE Buffer<T, std::enable_if_t<std::is_void_v<T>>>::bytes() const
|
|
834
|
+
{
|
|
835
|
+
return this->bytes(this->m_size);
|
|
836
|
+
}
|
|
837
|
+
|
|
502
838
|
// ------ define_buffer ----------
|
|
503
839
|
template<typename T>
|
|
504
840
|
inline Data_Type<Buffer<T>> define_buffer(std::string klassName)
|
|
505
841
|
{
|
|
506
842
|
using Buffer_T = Buffer<T>;
|
|
843
|
+
using Data_Type_T = Data_Type<Buffer_T>;
|
|
507
844
|
|
|
508
845
|
if (klassName.empty())
|
|
509
846
|
{
|
|
510
|
-
|
|
511
|
-
klassName =
|
|
847
|
+
detail::TypeMapper<Buffer_T> typeMapper;
|
|
848
|
+
klassName = typeMapper.rubyName();
|
|
512
849
|
}
|
|
513
850
|
|
|
514
851
|
Module rb_mRice = define_module("Rice");
|
|
515
852
|
|
|
853
|
+
if (Data_Type_T::check_defined(klassName, rb_mRice))
|
|
854
|
+
{
|
|
855
|
+
return Data_Type_T();
|
|
856
|
+
}
|
|
857
|
+
|
|
516
858
|
if constexpr (std::is_void_v<T>)
|
|
517
859
|
{
|
|
518
|
-
return define_class_under<Buffer_T>(rb_mRice, klassName)
|
|
860
|
+
return define_class_under<Buffer_T>(rb_mRice, klassName).
|
|
861
|
+
define_constructor(Constructor<Buffer_T, VALUE>(), Arg("value").setValue()).
|
|
862
|
+
define_constructor(Constructor<Buffer_T, VALUE, size_t>(), Arg("value").setValue(), Arg("size")).
|
|
863
|
+
define_method("size", &Buffer_T::size).
|
|
864
|
+
template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
|
865
|
+
template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
|
866
|
+
define_method("data", &Buffer_T::ptr, Return().setBuffer()).
|
|
867
|
+
define_method("release", &Buffer_T::release, Return().setBuffer());
|
|
519
868
|
}
|
|
520
869
|
else
|
|
521
870
|
{
|
|
522
871
|
Data_Type<Buffer_T> klass = define_class_under<Buffer_T>(rb_mRice, klassName).
|
|
523
872
|
define_constructor(Constructor<Buffer_T, VALUE>(), Arg("value").setValue()).
|
|
873
|
+
define_constructor(Constructor<Buffer_T, VALUE, size_t>(), Arg("value").setValue(), Arg("size")).
|
|
524
874
|
define_method("size", &Buffer_T::size).
|
|
525
|
-
define_method("
|
|
526
|
-
// template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
|
|
875
|
+
template define_method<VALUE(Buffer_T::*)() const>("to_s", &Buffer_T::toString, Return().setValue()).
|
|
527
876
|
template define_method<VALUE(Buffer_T::*)(size_t) const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
|
528
877
|
template define_method<VALUE(Buffer_T::*)() const>("bytes", &Buffer_T::bytes, Return().setValue()).
|
|
529
878
|
template define_method<Array(Buffer_T::*)(size_t) const>("to_ary", &Buffer_T::toArray, Return().setValue()).
|
|
530
|
-
template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue())
|
|
879
|
+
template define_method<Array(Buffer_T::*)() const>("to_ary", &Buffer_T::toArray, Return().setValue()).
|
|
880
|
+
define_method("[]", &Buffer_T::operator[], Arg("index")).
|
|
881
|
+
define_method("data", &Buffer_T::ptr, Return().setBuffer()).
|
|
882
|
+
define_method("release", &Buffer_T::release, Return().setBuffer());
|
|
531
883
|
|
|
532
|
-
if constexpr (!std::is_pointer_v<T>)
|
|
884
|
+
if constexpr (!std::is_pointer_v<T> && !std::is_void_v<T> && !std::is_const_v<T> && std::is_copy_assignable_v<T>)
|
|
533
885
|
{
|
|
534
|
-
klass.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
886
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, T& value) -> void
|
|
887
|
+
{
|
|
888
|
+
self[index] = value;
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
else if constexpr (std::is_pointer_v<T> && !std::is_const_v<std::remove_pointer_t<T>> && std::is_copy_assignable_v<std::remove_pointer_t<T>>)
|
|
892
|
+
{
|
|
893
|
+
klass.define_method("[]=", [](Buffer_T& self, size_t index, T value) -> void
|
|
894
|
+
{
|
|
895
|
+
*self[index] = *value;
|
|
896
|
+
});
|
|
543
897
|
}
|
|
544
898
|
|
|
545
899
|
return klass;
|
|
546
900
|
}
|
|
547
901
|
}
|
|
548
|
-
|
|
549
|
-
inline void define_fundamental_buffer_types()
|
|
550
|
-
{
|
|
551
|
-
define_buffer<bool>();
|
|
552
|
-
define_buffer<int>();
|
|
553
|
-
define_buffer<int*>();
|
|
554
|
-
define_buffer<unsigned int>();
|
|
555
|
-
define_buffer<unsigned int*>();
|
|
556
|
-
define_buffer<char>();
|
|
557
|
-
define_buffer<char*>();
|
|
558
|
-
define_buffer<unsigned char>();
|
|
559
|
-
define_buffer<unsigned char*>();
|
|
560
|
-
define_buffer<signed char>();
|
|
561
|
-
define_buffer<signed char*>();
|
|
562
|
-
define_buffer<double>();
|
|
563
|
-
define_buffer<double*>();
|
|
564
|
-
define_buffer<float>();
|
|
565
|
-
define_buffer<float*>();
|
|
566
|
-
define_buffer<long>();
|
|
567
|
-
define_buffer<long*>();
|
|
568
|
-
define_buffer<unsigned long>();
|
|
569
|
-
define_buffer<unsigned long*>();
|
|
570
|
-
define_buffer<long long>();
|
|
571
|
-
define_buffer<long long*>();
|
|
572
|
-
define_buffer<unsigned long long>();
|
|
573
|
-
define_buffer<unsigned long long*>();
|
|
574
|
-
define_buffer<short>();
|
|
575
|
-
define_buffer<short*>();
|
|
576
|
-
define_buffer<unsigned short>();
|
|
577
|
-
define_buffer<unsigned short*>();
|
|
578
|
-
define_buffer<void>();
|
|
579
|
-
}
|
|
580
902
|
}
|
|
581
903
|
|
|
582
904
|
namespace Rice::detail
|
|
@@ -586,13 +908,8 @@ namespace Rice::detail
|
|
|
586
908
|
{
|
|
587
909
|
static bool verify()
|
|
588
910
|
{
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
if (!Data_Type<Buffer<T>>::is_defined())
|
|
592
|
-
{
|
|
593
|
-
define_buffer<T>();
|
|
594
|
-
}
|
|
595
|
-
|
|
911
|
+
detail::verifyType<T>();
|
|
912
|
+
define_buffer<T>();
|
|
596
913
|
return true;
|
|
597
914
|
}
|
|
598
915
|
};
|