rice 4.3.3 → 4.6.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 +86 -26
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/README.md +7 -2
- data/Rakefile +12 -5
- data/include/rice/rice.hpp +9522 -4426
- data/include/rice/stl.hpp +2831 -1198
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +40 -94
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +26 -6
- data/rice/Arg.ipp +35 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +73 -3
- data/rice/Data_Object.ipp +388 -96
- data/rice/Data_Type.hpp +214 -3
- data/rice/Data_Type.ipp +144 -67
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -7
- data/rice/Enum.ipp +102 -55
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +3 -0
- data/rice/Return.hpp +7 -27
- data/rice/Return.ipp +13 -13
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
- data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +12 -10
- data/rice/detail/MethodInfo.ipp +26 -21
- data/rice/detail/Native.hpp +33 -0
- data/rice/detail/Native.ipp +157 -0
- data/rice/detail/NativeAttributeGet.hpp +52 -0
- data/rice/detail/NativeAttributeGet.ipp +57 -0
- data/rice/detail/NativeAttributeSet.hpp +44 -0
- data/rice/detail/NativeAttributeSet.ipp +88 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +33 -23
- data/rice/detail/NativeFunction.ipp +309 -70
- data/rice/detail/NativeIterator.hpp +9 -11
- data/rice/detail/NativeIterator.ipp +33 -31
- data/rice/detail/NativeRegistry.hpp +24 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +16 -0
- data/rice/detail/RubyType.ipp +232 -0
- data/rice/detail/Type.hpp +7 -6
- data/rice/detail/Type.ipp +192 -45
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +68 -32
- data/rice/detail/Wrapper.ipp +121 -109
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +38 -3
- data/rice/detail/from_ruby.ipp +1321 -492
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +1424 -194
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +116 -26
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +11 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +7 -1
- data/test/extconf.rb +2 -0
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +18 -4
- data/test/test_Attribute.cpp +136 -21
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +230 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +97 -38
- data/test/test_Data_Type.cpp +470 -65
- data/test/test_Director.cpp +17 -8
- data/test/test_Enum.cpp +155 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +609 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +6 -1
- data/test/test_Jump_Exception.cpp +23 -0
- data/test/test_Keep_Alive.cpp +13 -19
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +128 -67
- data/test/test_Native_Registry.cpp +2 -34
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +806 -0
- data/test/test_Ownership.cpp +160 -54
- data/test/test_Proc.cpp +44 -0
- data/test/test_Self.cpp +9 -4
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +54 -42
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +14 -9
- data/test/test_Stl_Reference_Wrapper.cpp +9 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/test_Stl_SharedPtr.cpp +458 -0
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +43 -38
- data/test/test_Stl_Variant.cpp +217 -84
- data/test/test_Stl_Vector.cpp +306 -58
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +524 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +171 -0
- data/test/test_global_functions.cpp +67 -7
- data/test/unittest.cpp +8 -0
- metadata +127 -26
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_Stl_SmartPointer.cpp +0 -283
- data/test/test_To_From_Ruby.cpp +0 -399
data/rice/stl/vector.ipp
ADDED
@@ -0,0 +1,590 @@
|
|
1
|
+
#include <vector>
|
2
|
+
|
3
|
+
namespace Rice
|
4
|
+
{
|
5
|
+
namespace stl
|
6
|
+
{
|
7
|
+
template<typename T>
|
8
|
+
class VectorHelper
|
9
|
+
{
|
10
|
+
// We do NOT use Reference_T and instead use Parameter_T to avoid the weirdness
|
11
|
+
// of std::vector<bool>. Reference_T is actually a proxy class that we do not
|
12
|
+
// want to have to register with Rice nor do we want to pass it around.
|
13
|
+
using Value_T = typename T::value_type;
|
14
|
+
using Size_T = typename T::size_type;
|
15
|
+
using Difference_T = typename T::difference_type;
|
16
|
+
// For To_Ruby_T however we do need to use reference type because this is what
|
17
|
+
// will be passed by an interator to To_Ruby#convert
|
18
|
+
using Reference_T = typename T::reference;
|
19
|
+
using Parameter_T = std::conditional_t<std::is_pointer_v<Value_T>, Value_T, Value_T&>;
|
20
|
+
using To_Ruby_T = detail::remove_cv_recursive_t<typename T::reference>;
|
21
|
+
|
22
|
+
public:
|
23
|
+
VectorHelper(Data_Type<T> klass) : klass_(klass)
|
24
|
+
{
|
25
|
+
this->define_constructors();
|
26
|
+
this->define_constructable_methods();
|
27
|
+
this->define_capacity_methods();
|
28
|
+
this->define_access_methods();
|
29
|
+
this->define_comparable_methods();
|
30
|
+
this->define_modify_methods();
|
31
|
+
this->define_enumerable();
|
32
|
+
this->define_to_array();
|
33
|
+
this->define_to_s();
|
34
|
+
}
|
35
|
+
|
36
|
+
private:
|
37
|
+
|
38
|
+
// Helper method to translate Ruby indices to vector indices
|
39
|
+
Difference_T normalizeIndex(Size_T size, Difference_T index, bool enforceBounds = false)
|
40
|
+
{
|
41
|
+
// Negative indices mean count from the right. Note that negative indices
|
42
|
+
// wrap around!
|
43
|
+
if (index < 0)
|
44
|
+
{
|
45
|
+
index = ((-index) % size);
|
46
|
+
index = index > 0 ? size - index : index;
|
47
|
+
}
|
48
|
+
|
49
|
+
if (enforceBounds && (index < 0 || index >= (Difference_T)size))
|
50
|
+
{
|
51
|
+
throw std::out_of_range("Invalid index: " + std::to_string(index));
|
52
|
+
}
|
53
|
+
|
54
|
+
return index;
|
55
|
+
};
|
56
|
+
|
57
|
+
void define_constructors()
|
58
|
+
{
|
59
|
+
klass_.define_constructor(Constructor<T>())
|
60
|
+
.define_constructor(Constructor<T, Size_T, const Parameter_T>())
|
61
|
+
.define_constructor(Constructor<T, const T&>());
|
62
|
+
|
63
|
+
if constexpr (std::is_default_constructible_v<Value_T>)
|
64
|
+
{
|
65
|
+
klass_.define_constructor(Constructor<T, Size_T>());
|
66
|
+
}
|
67
|
+
|
68
|
+
// Allow creation of a vector from a Ruby Array
|
69
|
+
klass_.define_method("initialize", [](VALUE self, Array array) -> void
|
70
|
+
{
|
71
|
+
// Create a new vector from the array
|
72
|
+
T* data = new T();
|
73
|
+
data->reserve(array.size());
|
74
|
+
|
75
|
+
detail::From_Ruby<Value_T> fromRuby;
|
76
|
+
|
77
|
+
for (long i = 0; i < array.size(); i++)
|
78
|
+
{
|
79
|
+
VALUE element = detail::protect(rb_ary_entry, array, i);
|
80
|
+
data->push_back(fromRuby.convert(element));
|
81
|
+
}
|
82
|
+
|
83
|
+
// Wrap the vector
|
84
|
+
detail::wrapConstructed<T>(self, Data_Type<T>::ruby_data_type(), data, true);
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
88
|
+
void define_constructable_methods()
|
89
|
+
{
|
90
|
+
if constexpr (std::is_default_constructible_v<Value_T> && std::is_same_v<Value_T, bool>)
|
91
|
+
{
|
92
|
+
klass_.define_method("resize", static_cast<void (T::*)(const size_t, bool)>(&T::resize));
|
93
|
+
}
|
94
|
+
else if constexpr (std::is_default_constructible_v<Value_T>)
|
95
|
+
{
|
96
|
+
klass_.define_method("resize", static_cast<void (T::*)(const size_t)>(&T::resize));
|
97
|
+
}
|
98
|
+
else
|
99
|
+
{
|
100
|
+
klass_.define_method("resize", [](const T& vector, Size_T newSize)
|
101
|
+
{
|
102
|
+
// Do nothing
|
103
|
+
});
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
void define_capacity_methods()
|
108
|
+
{
|
109
|
+
klass_.define_method("empty?", &T::empty)
|
110
|
+
.define_method("capacity", &T::capacity)
|
111
|
+
.define_method("max_size", &T::max_size)
|
112
|
+
.define_method("reserve", &T::reserve)
|
113
|
+
.define_method("size", &T::size);
|
114
|
+
|
115
|
+
rb_define_alias(klass_, "count", "size");
|
116
|
+
rb_define_alias(klass_, "length", "size");
|
117
|
+
//detail::protect(rb_define_alias, klass_, "count", "size");
|
118
|
+
//detail::protect(rb_define_alias, klass_, "length", "size");
|
119
|
+
}
|
120
|
+
|
121
|
+
void define_access_methods()
|
122
|
+
{
|
123
|
+
// Access methods
|
124
|
+
klass_.define_method("first", [](const T& vector) -> std::optional<Value_T>
|
125
|
+
{
|
126
|
+
if (vector.size() > 0)
|
127
|
+
{
|
128
|
+
return vector.front();
|
129
|
+
}
|
130
|
+
else
|
131
|
+
{
|
132
|
+
return std::nullopt;
|
133
|
+
}
|
134
|
+
})
|
135
|
+
.define_method("last", [](const T& vector) -> std::optional<Value_T>
|
136
|
+
{
|
137
|
+
if (vector.size() > 0)
|
138
|
+
{
|
139
|
+
return vector.back();
|
140
|
+
}
|
141
|
+
else
|
142
|
+
{
|
143
|
+
return std::nullopt;
|
144
|
+
}
|
145
|
+
})
|
146
|
+
.define_method("[]", [this](const T& vector, Difference_T index) -> std::optional<Value_T>
|
147
|
+
{
|
148
|
+
index = normalizeIndex(vector.size(), index);
|
149
|
+
if (index < 0 || index >= (Difference_T)vector.size())
|
150
|
+
{
|
151
|
+
return std::nullopt;
|
152
|
+
}
|
153
|
+
else
|
154
|
+
{
|
155
|
+
return vector[index];
|
156
|
+
}
|
157
|
+
})
|
158
|
+
.define_method("[]", [this](const T& vector, Difference_T start, Difference_T length) -> VALUE
|
159
|
+
{
|
160
|
+
start = normalizeIndex(vector.size(), start);
|
161
|
+
if (start < 0 || start >= (Difference_T)vector.size())
|
162
|
+
{
|
163
|
+
return rb_ary_new();
|
164
|
+
}
|
165
|
+
else
|
166
|
+
{
|
167
|
+
auto begin = vector.begin() + start;
|
168
|
+
|
169
|
+
// Ruby does not throw an exception when the length is too long
|
170
|
+
Difference_T size = (Difference_T)vector.size();
|
171
|
+
if (start + length > size)
|
172
|
+
{
|
173
|
+
length = size - start;
|
174
|
+
}
|
175
|
+
|
176
|
+
auto finish = vector.begin() + start + length;
|
177
|
+
T slice(begin, finish);
|
178
|
+
|
179
|
+
VALUE result = rb_ary_new();
|
180
|
+
std::for_each(slice.begin(), slice.end(), [&result](const Reference_T element)
|
181
|
+
{
|
182
|
+
VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
|
183
|
+
rb_ary_push(result, value);
|
184
|
+
});
|
185
|
+
|
186
|
+
return result;
|
187
|
+
}
|
188
|
+
}, Return().setValue());
|
189
|
+
|
190
|
+
if constexpr (!std::is_same_v<Value_T, bool>)
|
191
|
+
{
|
192
|
+
define_buffer<Value_T>();
|
193
|
+
define_buffer<Value_T*>();
|
194
|
+
klass_.template define_method<Value_T*(T::*)()>("data", &T::data);
|
195
|
+
}
|
196
|
+
|
197
|
+
rb_define_alias(klass_, "at", "[]");
|
198
|
+
}
|
199
|
+
|
200
|
+
// Methods that require Value_T to support operator==
|
201
|
+
void define_comparable_methods()
|
202
|
+
{
|
203
|
+
if constexpr (detail::is_comparable_v<T>)
|
204
|
+
{
|
205
|
+
klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
|
206
|
+
{
|
207
|
+
auto iter = std::find(vector.begin(), vector.end(), element);
|
208
|
+
if (iter == vector.end())
|
209
|
+
{
|
210
|
+
return std::nullopt;
|
211
|
+
}
|
212
|
+
else
|
213
|
+
{
|
214
|
+
Value_T result = *iter;
|
215
|
+
vector.erase(iter);
|
216
|
+
return result;
|
217
|
+
}
|
218
|
+
})
|
219
|
+
.define_method("include?", [](T& vector, Parameter_T element)
|
220
|
+
{
|
221
|
+
return std::find(vector.begin(), vector.end(), element) != vector.end();
|
222
|
+
})
|
223
|
+
.define_method("index", [](T& vector, Parameter_T element) -> std::optional<Difference_T>
|
224
|
+
{
|
225
|
+
auto iter = std::find(vector.begin(), vector.end(), element);
|
226
|
+
if (iter == vector.end())
|
227
|
+
{
|
228
|
+
return std::nullopt;
|
229
|
+
}
|
230
|
+
else
|
231
|
+
{
|
232
|
+
return iter - vector.begin();
|
233
|
+
}
|
234
|
+
});
|
235
|
+
}
|
236
|
+
else
|
237
|
+
{
|
238
|
+
klass_.define_method("delete", [](T& vector, Parameter_T element) -> std::optional<Value_T>
|
239
|
+
{
|
240
|
+
return std::nullopt;
|
241
|
+
})
|
242
|
+
.define_method("include?", [](const T& vector, Parameter_T element)
|
243
|
+
{
|
244
|
+
return false;
|
245
|
+
})
|
246
|
+
.define_method("index", [](const T& vector, Parameter_T element) -> std::optional<Difference_T>
|
247
|
+
{
|
248
|
+
return std::nullopt;
|
249
|
+
});
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
void define_modify_methods()
|
254
|
+
{
|
255
|
+
klass_.define_method("clear", &T::clear)
|
256
|
+
.define_method("delete_at", [](T& vector, const size_t& pos)
|
257
|
+
{
|
258
|
+
auto iter = vector.begin() + pos;
|
259
|
+
Value_T result = *iter;
|
260
|
+
vector.erase(iter);
|
261
|
+
return result;
|
262
|
+
})
|
263
|
+
.define_method("insert", [this](T& vector, Difference_T index, Parameter_T element) -> T&
|
264
|
+
{
|
265
|
+
index = normalizeIndex(vector.size(), index, true);
|
266
|
+
auto iter = vector.begin() + index;
|
267
|
+
vector.insert(iter, element);
|
268
|
+
return vector;
|
269
|
+
})
|
270
|
+
.define_method("pop", [](T& vector) -> std::optional<Value_T>
|
271
|
+
{
|
272
|
+
if (vector.size() > 0)
|
273
|
+
{
|
274
|
+
Value_T result = vector.back();
|
275
|
+
vector.pop_back();
|
276
|
+
return result;
|
277
|
+
}
|
278
|
+
else
|
279
|
+
{
|
280
|
+
return std::nullopt;
|
281
|
+
}
|
282
|
+
})
|
283
|
+
.define_method("push", [](T& vector, Parameter_T element) -> T&
|
284
|
+
{
|
285
|
+
vector.push_back(element);
|
286
|
+
return vector;
|
287
|
+
})
|
288
|
+
.define_method("shrink_to_fit", &T::shrink_to_fit)
|
289
|
+
.define_method("[]=", [this](T& vector, Difference_T index, Parameter_T element) -> Parameter_T
|
290
|
+
{
|
291
|
+
index = normalizeIndex(vector.size(), index, true);
|
292
|
+
vector[index] = element;
|
293
|
+
return element;
|
294
|
+
});
|
295
|
+
|
296
|
+
rb_define_alias(klass_, "push_back", "push");
|
297
|
+
rb_define_alias(klass_, "<<", "push");
|
298
|
+
rb_define_alias(klass_, "append", "push");
|
299
|
+
}
|
300
|
+
|
301
|
+
void define_enumerable()
|
302
|
+
{
|
303
|
+
// Add enumerable support
|
304
|
+
klass_.template define_iterator<typename T::iterator(T::*)()>(&T::begin, &T::end);
|
305
|
+
}
|
306
|
+
|
307
|
+
void define_to_array()
|
308
|
+
{
|
309
|
+
// Add enumerable support
|
310
|
+
klass_.define_method("to_a", [](T& vector)
|
311
|
+
{
|
312
|
+
VALUE result = rb_ary_new();
|
313
|
+
std::for_each(vector.begin(), vector.end(), [&result](const Reference_T element)
|
314
|
+
{
|
315
|
+
VALUE value = detail::To_Ruby<Parameter_T>().convert(element);
|
316
|
+
rb_ary_push(result, value);
|
317
|
+
});
|
318
|
+
|
319
|
+
return result;
|
320
|
+
}, Return().setValue());
|
321
|
+
}
|
322
|
+
|
323
|
+
void define_to_s()
|
324
|
+
{
|
325
|
+
if constexpr (detail::is_ostreamable_v<Value_T>)
|
326
|
+
{
|
327
|
+
klass_.define_method("to_s", [](const T& vector)
|
328
|
+
{
|
329
|
+
auto iter = vector.begin();
|
330
|
+
auto finish = vector.size() > 1000 ? vector.begin() + 1000 : vector.end();
|
331
|
+
|
332
|
+
std::stringstream stream;
|
333
|
+
stream << "[";
|
334
|
+
|
335
|
+
for (; iter != finish; iter++)
|
336
|
+
{
|
337
|
+
if (iter == vector.begin())
|
338
|
+
{
|
339
|
+
stream << *iter;
|
340
|
+
}
|
341
|
+
else
|
342
|
+
{
|
343
|
+
stream << ", " << *iter;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
stream << "]";
|
348
|
+
return stream.str();
|
349
|
+
});
|
350
|
+
}
|
351
|
+
else
|
352
|
+
{
|
353
|
+
klass_.define_method("to_s", [](const T& vector)
|
354
|
+
{
|
355
|
+
return "[Not printable]";
|
356
|
+
});
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
private:
|
361
|
+
Data_Type<T> klass_;
|
362
|
+
};
|
363
|
+
} // namespace
|
364
|
+
|
365
|
+
template<typename T>
|
366
|
+
Data_Type<std::vector<T>> define_vector(std::string klassName)
|
367
|
+
{
|
368
|
+
using Vector_T = std::vector<T>;
|
369
|
+
using Data_Type_T = Data_Type<Vector_T>;
|
370
|
+
|
371
|
+
if (klassName.empty())
|
372
|
+
{
|
373
|
+
std::string typeName = detail::typeName(typeid(Vector_T));
|
374
|
+
klassName = detail::rubyClassName(typeName);
|
375
|
+
}
|
376
|
+
|
377
|
+
Module rb_mStd = define_module("Std");
|
378
|
+
if (Data_Type_T::check_defined(klassName, rb_mStd))
|
379
|
+
{
|
380
|
+
return Data_Type_T();
|
381
|
+
}
|
382
|
+
|
383
|
+
Identifier id(klassName);
|
384
|
+
Data_Type_T result = define_class_under<detail::intrinsic_type<Vector_T>>(rb_mStd, id);
|
385
|
+
stl::VectorHelper helper(result);
|
386
|
+
return result;
|
387
|
+
}
|
388
|
+
|
389
|
+
|
390
|
+
namespace detail
|
391
|
+
{
|
392
|
+
template<typename T>
|
393
|
+
struct Type<std::vector<T>>
|
394
|
+
{
|
395
|
+
static bool verify()
|
396
|
+
{
|
397
|
+
Type<intrinsic_type<T>>::verify();
|
398
|
+
|
399
|
+
if (!Data_Type<std::vector<T>>::is_defined())
|
400
|
+
{
|
401
|
+
define_vector<T>();
|
402
|
+
}
|
403
|
+
|
404
|
+
return true;
|
405
|
+
}
|
406
|
+
};
|
407
|
+
|
408
|
+
template<typename T>
|
409
|
+
class From_Ruby<std::vector<T>>
|
410
|
+
{
|
411
|
+
public:
|
412
|
+
From_Ruby() = default;
|
413
|
+
|
414
|
+
explicit From_Ruby(Arg * arg) : arg_(arg)
|
415
|
+
{
|
416
|
+
}
|
417
|
+
|
418
|
+
Convertible is_convertible(VALUE value)
|
419
|
+
{
|
420
|
+
switch (rb_type(value))
|
421
|
+
{
|
422
|
+
case RUBY_T_DATA:
|
423
|
+
return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
424
|
+
break;
|
425
|
+
case RUBY_T_ARRAY:
|
426
|
+
if constexpr (std::is_default_constructible_v<T>)
|
427
|
+
{
|
428
|
+
return Convertible::Cast;
|
429
|
+
}
|
430
|
+
default:
|
431
|
+
return Convertible::None;
|
432
|
+
}
|
433
|
+
}
|
434
|
+
|
435
|
+
std::vector<T> convert(VALUE value)
|
436
|
+
{
|
437
|
+
switch (rb_type(value))
|
438
|
+
{
|
439
|
+
case RUBY_T_DATA:
|
440
|
+
{
|
441
|
+
// This is a wrapped vector (hopefully!)
|
442
|
+
return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
|
443
|
+
}
|
444
|
+
case RUBY_T_ARRAY:
|
445
|
+
{
|
446
|
+
// If this an Ruby array and the vector type is copyable
|
447
|
+
if constexpr (std::is_default_constructible_v<T>)
|
448
|
+
{
|
449
|
+
return Array(value).to_vector<T>();
|
450
|
+
}
|
451
|
+
}
|
452
|
+
default:
|
453
|
+
{
|
454
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
455
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
456
|
+
}
|
457
|
+
}
|
458
|
+
}
|
459
|
+
|
460
|
+
private:
|
461
|
+
Arg* arg_ = nullptr;
|
462
|
+
};
|
463
|
+
|
464
|
+
template<typename T>
|
465
|
+
class From_Ruby<std::vector<T>&>
|
466
|
+
{
|
467
|
+
public:
|
468
|
+
From_Ruby() = default;
|
469
|
+
|
470
|
+
explicit From_Ruby(Arg * arg) : arg_(arg)
|
471
|
+
{
|
472
|
+
}
|
473
|
+
|
474
|
+
Convertible is_convertible(VALUE value)
|
475
|
+
{
|
476
|
+
switch (rb_type(value))
|
477
|
+
{
|
478
|
+
case RUBY_T_DATA:
|
479
|
+
return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
480
|
+
break;
|
481
|
+
case RUBY_T_ARRAY:
|
482
|
+
if constexpr (std::is_default_constructible_v<T>)
|
483
|
+
{
|
484
|
+
return Convertible::Cast;
|
485
|
+
}
|
486
|
+
default:
|
487
|
+
return Convertible::None;
|
488
|
+
}
|
489
|
+
}
|
490
|
+
|
491
|
+
std::vector<T>& convert(VALUE value)
|
492
|
+
{
|
493
|
+
switch (rb_type(value))
|
494
|
+
{
|
495
|
+
case RUBY_T_DATA:
|
496
|
+
{
|
497
|
+
// This is a wrapped vector (hopefully!)
|
498
|
+
return *detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
|
499
|
+
}
|
500
|
+
case RUBY_T_ARRAY:
|
501
|
+
{
|
502
|
+
// If this an Ruby array and the vector type is copyable
|
503
|
+
if constexpr (std::is_default_constructible_v<T>)
|
504
|
+
{
|
505
|
+
this->converted_ = Array(value).to_vector<T>();
|
506
|
+
return this->converted_;
|
507
|
+
}
|
508
|
+
}
|
509
|
+
default:
|
510
|
+
{
|
511
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
512
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
513
|
+
}
|
514
|
+
}
|
515
|
+
}
|
516
|
+
|
517
|
+
private:
|
518
|
+
Arg* arg_ = nullptr;
|
519
|
+
std::vector<T> converted_;
|
520
|
+
};
|
521
|
+
|
522
|
+
template<typename T>
|
523
|
+
class From_Ruby<std::vector<T>*>
|
524
|
+
{
|
525
|
+
public:
|
526
|
+
Convertible is_convertible(VALUE value)
|
527
|
+
{
|
528
|
+
switch (rb_type(value))
|
529
|
+
{
|
530
|
+
case RUBY_T_DATA:
|
531
|
+
return Data_Type<std::vector<T>>::is_descendant(value) ? Convertible::Exact : Convertible::None;
|
532
|
+
break;
|
533
|
+
case RUBY_T_NIL:
|
534
|
+
return Convertible::Exact;
|
535
|
+
break;
|
536
|
+
case RUBY_T_ARRAY:
|
537
|
+
if constexpr (std::is_default_constructible_v<T>)
|
538
|
+
{
|
539
|
+
return Convertible::Cast;
|
540
|
+
}
|
541
|
+
default:
|
542
|
+
return Convertible::None;
|
543
|
+
}
|
544
|
+
}
|
545
|
+
|
546
|
+
std::vector<T>* convert(VALUE value)
|
547
|
+
{
|
548
|
+
switch (rb_type(value))
|
549
|
+
{
|
550
|
+
case RUBY_T_DATA:
|
551
|
+
{
|
552
|
+
// This is a wrapped vector (hopefully!)
|
553
|
+
return detail::unwrap<std::vector<T>>(value, Data_Type<std::vector<T>>::ruby_data_type(), false);
|
554
|
+
}
|
555
|
+
case RUBY_T_ARRAY:
|
556
|
+
{
|
557
|
+
// If this a Ruby array and the vector type is copyable
|
558
|
+
if constexpr (std::is_default_constructible_v<T>)
|
559
|
+
{
|
560
|
+
this->converted_ = Array(value).to_vector<T>();
|
561
|
+
return &this->converted_;
|
562
|
+
}
|
563
|
+
}
|
564
|
+
default:
|
565
|
+
{
|
566
|
+
throw Exception(rb_eTypeError, "wrong argument type %s (expected % s)",
|
567
|
+
detail::protect(rb_obj_classname, value), "std::vector");
|
568
|
+
}
|
569
|
+
}
|
570
|
+
}
|
571
|
+
|
572
|
+
private:
|
573
|
+
std::vector<T> converted_;
|
574
|
+
};
|
575
|
+
}
|
576
|
+
|
577
|
+
// Special handling for std::vector<bool>
|
578
|
+
namespace detail
|
579
|
+
{
|
580
|
+
template<>
|
581
|
+
class To_Ruby<std::vector<bool>::reference>
|
582
|
+
{
|
583
|
+
public:
|
584
|
+
VALUE convert(const std::vector<bool>::reference& value)
|
585
|
+
{
|
586
|
+
return value ? Qtrue : Qfalse;
|
587
|
+
}
|
588
|
+
};
|
589
|
+
}
|
590
|
+
}
|
data/rice/stl.hpp
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
#ifndef Rice__stl__hpp_
|
2
2
|
#define Rice__stl__hpp_
|
3
3
|
|
4
|
+
#include "stl/exception.hpp"
|
5
|
+
#include "stl/exception_ptr.hpp"
|
4
6
|
#include "stl/string.hpp"
|
5
7
|
#include "stl/string_view.hpp"
|
6
8
|
#include "stl/complex.hpp"
|
7
9
|
#include "stl/optional.hpp"
|
8
10
|
#include "stl/reference_wrapper.hpp"
|
9
|
-
#include "stl/smart_ptr.hpp"
|
10
|
-
#include "stl/monostate.hpp"
|
11
|
-
#include "stl/variant.hpp"
|
12
11
|
#include "stl/pair.hpp"
|
13
12
|
#include "stl/map.hpp"
|
13
|
+
#include "stl/monostate.hpp"
|
14
|
+
#include "stl/multimap.hpp"
|
15
|
+
#include "stl/set.hpp"
|
16
|
+
#include "stl/shared_ptr.hpp"
|
17
|
+
#include "stl/tuple.hpp"
|
18
|
+
#include "stl/type_index.hpp"
|
19
|
+
#include "stl/type_info.hpp"
|
20
|
+
#include "stl/variant.hpp"
|
21
|
+
#include "stl/unique_ptr.hpp"
|
14
22
|
#include "stl/unordered_map.hpp"
|
15
23
|
#include "stl/vector.hpp"
|
16
24
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#ifndef Rice__detail__attribute_traits__hpp_
|
2
|
+
#define Rice__detail__attribute_traits__hpp_
|
3
|
+
|
4
|
+
#include <tuple>
|
5
|
+
|
6
|
+
namespace Rice::detail
|
7
|
+
{
|
8
|
+
// Base class
|
9
|
+
template<typename Attribute_T>
|
10
|
+
struct attribute_traits;
|
11
|
+
|
12
|
+
template<typename Attr_T>
|
13
|
+
struct attribute_traits<Attr_T*>
|
14
|
+
{
|
15
|
+
using attr_type = Attr_T;
|
16
|
+
using class_type = std::nullptr_t;
|
17
|
+
};
|
18
|
+
|
19
|
+
template<typename Attr_T, typename Class_T>
|
20
|
+
struct attribute_traits<Attr_T Class_T::*>
|
21
|
+
{
|
22
|
+
using attr_type = Attr_T;
|
23
|
+
using class_type = Class_T;
|
24
|
+
};
|
25
|
+
}
|
26
|
+
#endif // Rice__detail__attribute_traits__hpp_
|