rice 4.2.1 → 4.3.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.
@@ -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;