rice 4.2.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }
@@ -99,16 +99,26 @@ namespace Rice::detail
99
99
 
100
100
  Wrapper* wrapper = nullptr;
101
101
 
102
- if constexpr (!std::is_void_v<Wrapper_T>)
102
+ // Is this a pointer but cannot be copied? For example a std::unique_ptr
103
+ if constexpr (!std::is_void_v<Wrapper_T> && !std::is_copy_constructible_v<Wrapper_T>)
104
+ {
105
+ wrapper = new Wrapper_T(std::move(data));
106
+ result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
107
+ }
108
+ // Is this a pointer or smart pointer like std::shared_ptr
109
+ else if constexpr (!std::is_void_v<Wrapper_T>)
103
110
  {
104
111
  wrapper = new Wrapper_T(data);
105
112
  result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
106
113
  }
114
+ // Is this a pointer and it cannot copied? This is for std::unique_ptr
115
+ // If ruby is the owner than copy the object
107
116
  else if (isOwner)
108
117
  {
109
118
  wrapper = new WrapperValue<T>(data);
110
119
  result = TypedData_Wrap_Struct(klass, rb_type, wrapper);
111
120
  }
121
+ // Ruby is not the owner so just wrap the reference
112
122
  else
113
123
  {
114
124
  wrapper = new WrapperReference<T>(data);
data/rice/stl.hpp CHANGED
@@ -2,6 +2,7 @@
2
2
  #define Rice__stl__hpp_
3
3
 
4
4
  #include "stl/string.hpp"
5
+ #include "stl/string_view.hpp"
5
6
  #include "stl/complex.hpp"
6
7
  #include "stl/optional.hpp"
7
8
  #include "stl/reference_wrapper.hpp"
data/test/embed_ruby.cpp CHANGED
@@ -17,8 +17,8 @@ void embed_ruby()
17
17
 
18
18
  #if RUBY_API_VERSION_MAJOR == 3 && RUBY_API_VERSION_MINOR >= 3
19
19
  // Force the prelude / builtins
20
- char *opts[] = { "ruby", "-e;" };
21
- ruby_options(2, opts);
20
+ const char* opts[] = { "ruby", "-e;" };
21
+ ruby_options(2, (char**)opts);
22
22
  #endif
23
23
 
24
24
  initialized__ = true;