rice 4.3.0 → 4.3.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 +174 -169
- data/CONTRIBUTORS.md +1 -0
- data/README.md +4 -4
- data/include/rice/rice.hpp +8762 -8762
- data/lib/version.rb +3 -3
- data/rice/Data_Object.ipp +386 -386
- data/rice/Identifier.hpp +50 -50
- data/rice/Identifier.ipp +28 -28
- data/rice/detail/NativeFunction.hpp +119 -119
- data/rice/detail/NativeFunction.ipp +300 -300
- data/rice/detail/NativeIterator.ipp +101 -101
- data/test/test_Array.cpp +301 -301
- data/test/test_Iterator.cpp +356 -356
- data/test/test_Stl_String_View.cpp +88 -88
- data/test/test_Stl_Vector.cpp +871 -871
- data/test/test_Symbol.cpp +7 -0
- metadata +10 -10
@@ -1,102 +1,102 @@
|
|
1
|
-
#include <iterator>
|
2
|
-
#include <functional>
|
3
|
-
#include <type_traits>
|
4
|
-
|
5
|
-
#include "cpp_protect.hpp"
|
6
|
-
#include "NativeRegistry.hpp"
|
7
|
-
|
8
|
-
namespace Rice::detail
|
9
|
-
{
|
10
|
-
template <typename T, typename Iterator_Func_T>
|
11
|
-
inline void NativeIterator<T, Iterator_Func_T>::define(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end)
|
12
|
-
{
|
13
|
-
// Tell Ruby to invoke the static method call on this class
|
14
|
-
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&NativeIterator_T::call, 0);
|
15
|
-
|
16
|
-
// Now create a NativeIterator instance and save it to the natives registry keyed on
|
17
|
-
// Ruby klass and method id. There may be multiple NativeIterator instances
|
18
|
-
// because the same C++ method could be mapped to multiple Ruby methods.
|
19
|
-
NativeIterator_T* native = new NativeIterator_T(klass, method_name, begin, end);
|
20
|
-
detail::Registries::instance.natives.add(klass, Identifier(method_name).id(), native);
|
21
|
-
}
|
22
|
-
|
23
|
-
template<typename T, typename Iterator_Func_T>
|
24
|
-
inline VALUE NativeIterator<T, Iterator_Func_T>::call(VALUE self)
|
25
|
-
{
|
26
|
-
// Look up the native function based on the Ruby klass and method id
|
27
|
-
NativeIterator_T* nativeIterator = detail::Registries::instance.natives.lookup<NativeIterator_T*>();
|
28
|
-
|
29
|
-
return cpp_protect([&]
|
30
|
-
{
|
31
|
-
return nativeIterator->operator()(self);
|
32
|
-
});
|
33
|
-
}
|
34
|
-
|
35
|
-
template <typename T, typename Iterator_Func_T>
|
36
|
-
inline NativeIterator<T, Iterator_Func_T>::NativeIterator(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end) :
|
37
|
-
klass_(klass), method_name_(method_name), begin_(begin), end_(end)
|
38
|
-
{
|
39
|
-
}
|
40
|
-
|
41
|
-
template<typename T, typename Iterator_Func_T>
|
42
|
-
inline VALUE NativeIterator<T, Iterator_Func_T>::createRubyEnumerator(VALUE self)
|
43
|
-
{
|
44
|
-
auto rb_size_function = [](VALUE recv, VALUE argv, VALUE eobj) -> VALUE
|
45
|
-
{
|
46
|
-
// Since we can't capture VALUE self from above (because then we can't send
|
47
|
-
// this lambda to rb_enumeratorize_with_size), extract it from recv
|
48
|
-
return cpp_protect([&]
|
49
|
-
{
|
50
|
-
// Get the iterator instance
|
51
|
-
using Iter_T = NativeIterator<T, Iterator_Func_T>;
|
52
|
-
// Class is easy
|
53
|
-
VALUE klass = protect(rb_class_of, recv);
|
54
|
-
// Read the method_id from an attribute we added to the enumerator instance
|
55
|
-
ID method_id = protect(rb_ivar_get, eobj, rb_intern("rice_method"));
|
56
|
-
Iter_T* iterator = detail::Registries::instance.natives.lookup<Iter_T*>(klass, method_id);
|
57
|
-
|
58
|
-
// Get the wrapped C++ instance
|
59
|
-
T* receiver = detail::From_Ruby<T*>().convert(recv);
|
60
|
-
|
61
|
-
// Get the distance
|
62
|
-
Iterator_T begin = std::invoke(iterator->begin_, *receiver);
|
63
|
-
Iterator_T end = std::invoke(iterator->end_, *receiver);
|
64
|
-
Difference_T distance = std::distance(begin, end);
|
65
|
-
|
66
|
-
return detail::To_Ruby<Difference_T>().convert(distance);
|
67
|
-
});
|
68
|
-
};
|
69
|
-
|
70
|
-
VALUE method_sym = Identifier(this->method_name_).to_sym();
|
71
|
-
VALUE enumerator = protect(rb_enumeratorize_with_size, self, method_sym, 0, nullptr, rb_size_function);
|
72
|
-
|
73
|
-
// Hack the enumerator object by storing name_ on the enumerator object so
|
74
|
-
// the rb_size_function above has access to it
|
75
|
-
ID method_id = Identifier(this->method_name_).id();
|
76
|
-
protect(rb_ivar_set, enumerator, rb_intern("rice_method"), method_id);
|
77
|
-
|
78
|
-
return enumerator;
|
79
|
-
}
|
80
|
-
|
81
|
-
template<typename T, typename Iterator_Func_T>
|
82
|
-
inline VALUE NativeIterator<T, Iterator_Func_T>::operator()(VALUE self)
|
83
|
-
{
|
84
|
-
if (!protect(rb_block_given_p))
|
85
|
-
{
|
86
|
-
return createRubyEnumerator(self);
|
87
|
-
}
|
88
|
-
else
|
89
|
-
{
|
90
|
-
T* receiver = detail::From_Ruby<T*>().convert(self);
|
91
|
-
Iterator_T it = std::invoke(this->begin_, *receiver);
|
92
|
-
Iterator_T end = std::invoke(this->end_, *receiver);
|
93
|
-
|
94
|
-
for (; it != end; ++it)
|
95
|
-
{
|
96
|
-
protect(rb_yield, detail::To_Ruby<Value_T&>().convert(*it));
|
97
|
-
}
|
98
|
-
|
99
|
-
return self;
|
100
|
-
}
|
101
|
-
}
|
1
|
+
#include <iterator>
|
2
|
+
#include <functional>
|
3
|
+
#include <type_traits>
|
4
|
+
|
5
|
+
#include "cpp_protect.hpp"
|
6
|
+
#include "NativeRegistry.hpp"
|
7
|
+
|
8
|
+
namespace Rice::detail
|
9
|
+
{
|
10
|
+
template <typename T, typename Iterator_Func_T>
|
11
|
+
inline void NativeIterator<T, Iterator_Func_T>::define(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end)
|
12
|
+
{
|
13
|
+
// Tell Ruby to invoke the static method call on this class
|
14
|
+
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&NativeIterator_T::call, 0);
|
15
|
+
|
16
|
+
// Now create a NativeIterator instance and save it to the natives registry keyed on
|
17
|
+
// Ruby klass and method id. There may be multiple NativeIterator instances
|
18
|
+
// because the same C++ method could be mapped to multiple Ruby methods.
|
19
|
+
NativeIterator_T* native = new NativeIterator_T(klass, method_name, begin, end);
|
20
|
+
detail::Registries::instance.natives.add(klass, Identifier(method_name).id(), native);
|
21
|
+
}
|
22
|
+
|
23
|
+
template<typename T, typename Iterator_Func_T>
|
24
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::call(VALUE self)
|
25
|
+
{
|
26
|
+
// Look up the native function based on the Ruby klass and method id
|
27
|
+
NativeIterator_T* nativeIterator = detail::Registries::instance.natives.lookup<NativeIterator_T*>();
|
28
|
+
|
29
|
+
return cpp_protect([&]
|
30
|
+
{
|
31
|
+
return nativeIterator->operator()(self);
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
template <typename T, typename Iterator_Func_T>
|
36
|
+
inline NativeIterator<T, Iterator_Func_T>::NativeIterator(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end) :
|
37
|
+
klass_(klass), method_name_(method_name), begin_(begin), end_(end)
|
38
|
+
{
|
39
|
+
}
|
40
|
+
|
41
|
+
template<typename T, typename Iterator_Func_T>
|
42
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::createRubyEnumerator(VALUE self)
|
43
|
+
{
|
44
|
+
auto rb_size_function = [](VALUE recv, VALUE argv, VALUE eobj) -> VALUE
|
45
|
+
{
|
46
|
+
// Since we can't capture VALUE self from above (because then we can't send
|
47
|
+
// this lambda to rb_enumeratorize_with_size), extract it from recv
|
48
|
+
return cpp_protect([&]
|
49
|
+
{
|
50
|
+
// Get the iterator instance
|
51
|
+
using Iter_T = NativeIterator<T, Iterator_Func_T>;
|
52
|
+
// Class is easy
|
53
|
+
VALUE klass = protect(rb_class_of, recv);
|
54
|
+
// Read the method_id from an attribute we added to the enumerator instance
|
55
|
+
ID method_id = protect(rb_ivar_get, eobj, rb_intern("rice_method"));
|
56
|
+
Iter_T* iterator = detail::Registries::instance.natives.lookup<Iter_T*>(klass, method_id);
|
57
|
+
|
58
|
+
// Get the wrapped C++ instance
|
59
|
+
T* receiver = detail::From_Ruby<T*>().convert(recv);
|
60
|
+
|
61
|
+
// Get the distance
|
62
|
+
Iterator_T begin = std::invoke(iterator->begin_, *receiver);
|
63
|
+
Iterator_T end = std::invoke(iterator->end_, *receiver);
|
64
|
+
Difference_T distance = std::distance(begin, end);
|
65
|
+
|
66
|
+
return detail::To_Ruby<Difference_T>().convert(distance);
|
67
|
+
});
|
68
|
+
};
|
69
|
+
|
70
|
+
VALUE method_sym = Identifier(this->method_name_).to_sym();
|
71
|
+
VALUE enumerator = protect(rb_enumeratorize_with_size, self, method_sym, 0, nullptr, rb_size_function);
|
72
|
+
|
73
|
+
// Hack the enumerator object by storing name_ on the enumerator object so
|
74
|
+
// the rb_size_function above has access to it
|
75
|
+
ID method_id = Identifier(this->method_name_).id();
|
76
|
+
protect(rb_ivar_set, enumerator, rb_intern("rice_method"), method_id);
|
77
|
+
|
78
|
+
return enumerator;
|
79
|
+
}
|
80
|
+
|
81
|
+
template<typename T, typename Iterator_Func_T>
|
82
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::operator()(VALUE self)
|
83
|
+
{
|
84
|
+
if (!protect(rb_block_given_p))
|
85
|
+
{
|
86
|
+
return createRubyEnumerator(self);
|
87
|
+
}
|
88
|
+
else
|
89
|
+
{
|
90
|
+
T* receiver = detail::From_Ruby<T*>().convert(self);
|
91
|
+
Iterator_T it = std::invoke(this->begin_, *receiver);
|
92
|
+
Iterator_T end = std::invoke(this->end_, *receiver);
|
93
|
+
|
94
|
+
for (; it != end; ++it)
|
95
|
+
{
|
96
|
+
protect(rb_yield, detail::To_Ruby<Value_T&>().convert(*it));
|
97
|
+
}
|
98
|
+
|
99
|
+
return self;
|
100
|
+
}
|
101
|
+
}
|
102
102
|
}
|