rice 4.8.0 → 4.9.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 +25 -1
- data/CMakePresets.json +77 -50
- data/FindRuby.cmake +1 -1
- data/bin/rice-doc.rb +2 -0
- data/include/rice/api.hpp +14 -1
- data/include/rice/rice.hpp +351 -132
- data/include/rice/stl.hpp +319 -256
- data/lib/rice/doc/config.rb +57 -57
- data/lib/rice/doc/cpp_reference.rb +158 -158
- data/lib/rice/doc/doxygen.rb +289 -289
- data/lib/rice/doc/mkdocs.rb +332 -332
- data/lib/rice/doc/rice.rb +48 -47
- data/lib/rice/doc/ruby.rb +26 -26
- data/lib/rice/native.rb +15 -15
- data/lib/rice/native_registry.rb +12 -17
- data/lib/rice/parameter.rb +5 -5
- data/lib/rice/rbs.rb +72 -72
- data/lib/rice/version.rb +1 -1
- data/lib/rubygems/builder.rb +9 -9
- data/lib/rubygems_plugin.rb +8 -8
- data/rice/Data_Type.ipp +12 -7
- data/rice/cpp_api/Class.hpp +5 -0
- data/rice/cpp_api/Class.ipp +5 -0
- data/rice/cpp_api/Object.hpp +6 -0
- data/rice/cpp_api/Object.ipp +5 -0
- data/rice/detail/Forwards.hpp +18 -0
- data/rice/detail/Forwards.ipp +60 -0
- data/rice/detail/Native.ipp +2 -4
- data/rice/detail/NativeAttributeGet.ipp +1 -1
- data/rice/detail/NativeAttributeSet.hpp +5 -3
- data/rice/detail/NativeAttributeSet.ipp +41 -33
- data/rice/detail/NativeMethod.ipp +25 -22
- data/rice/detail/NativeRegistry.hpp +4 -2
- data/rice/detail/NativeRegistry.ipp +42 -9
- data/rice/detail/Parameter.ipp +3 -4
- data/rice/detail/Type.ipp +4 -0
- data/rice/detail/Wrapper.hpp +17 -12
- data/rice/detail/Wrapper.ipp +95 -36
- data/rice/rice.hpp +3 -0
- data/rice/rice_api/NativeRegistry.ipp +14 -1
- data/rice/stl/exception.ipp +1 -1
- data/rice/stl/filesystem.ipp +1 -1
- data/rice/stl/map.ipp +13 -11
- data/rice/stl/multimap.ipp +13 -11
- data/rice/stl/pair.ipp +14 -8
- data/rice/stl/set.ipp +16 -16
- data/rice/stl/shared_ptr.hpp +16 -0
- data/rice/stl/shared_ptr.ipp +74 -37
- data/rice/stl/type_index.ipp +1 -1
- data/rice/stl/unique_ptr.hpp +9 -3
- data/rice/stl/unique_ptr.ipp +80 -124
- data/rice/stl/unordered_map.ipp +14 -12
- data/rice/stl/vector.ipp +67 -31
- data/test/test_Attribute.cpp +72 -0
- data/test/test_Callback.cpp +3 -0
- data/test/test_Inheritance.cpp +14 -14
- data/test/test_Keep_Alive_No_Wrapper.cpp +6 -2
- data/test/test_Stl_Map.cpp +46 -0
- data/test/test_Stl_Multimap.cpp +46 -0
- data/test/test_Stl_Set.cpp +34 -0
- data/test/test_Stl_SharedPtr.cpp +160 -45
- data/test/test_Stl_UniquePtr.cpp +48 -3
- data/test/test_Stl_Unordered_Map.cpp +46 -0
- data/test/test_Stl_Variant.cpp +10 -14
- data/test/test_Stl_Vector.cpp +140 -13
- data/test/test_Tracking.cpp +3 -0
- metadata +3 -1
data/lib/rice/doc/rice.rb
CHANGED
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
2
|
+
module Doc
|
|
3
|
+
class Rice
|
|
4
|
+
ROOT = "https://ruby-rice.github.io/4.x"
|
|
5
|
+
|
|
6
|
+
CLASS_DOCS = {
|
|
7
|
+
/^Rice::Buffer/ => "ruby_api/buffer",
|
|
8
|
+
/^Rice::Pointer/ => "ruby_api/pointer",
|
|
9
|
+
/^Rice::Reference/ => "ruby_api/reference"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def class_url(klass)
|
|
13
|
+
CLASS_DOCS.each do |pattern, path|
|
|
14
|
+
if klass.name.match?(pattern)
|
|
15
|
+
return "#{ROOT}/#{path}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def module_url(klass)
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def union_url(klass)
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def enum_url(klass)
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def enum_value_url(klass, enum_value)
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def singleton_method_url(klass, native)
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def method_url(klass, native)
|
|
42
|
+
class_url(klass)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def attribute_url(klass, native)
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
49
50
|
end
|
data/lib/rice/doc/ruby.rb
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
module Doc
|
|
3
|
+
class Ruby
|
|
4
|
+
ROOT = "https://docs.ruby-lang.org/en/master"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
def initialize
|
|
7
|
+
end
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
def class_url(klass)
|
|
10
|
+
name = klass.name.split('::').last
|
|
11
|
+
name[0].upcase! # Can't use capitalize because it lowercases other letters which breaks links like NilClass
|
|
12
|
+
"#{ROOT}/#{name}.html"
|
|
13
|
+
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
def module_url(klass)
|
|
16
|
+
end
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
def union_url(klass)
|
|
19
|
+
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def enum_url(klass)
|
|
22
|
+
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
def enum_value_url(klass, enum_value)
|
|
25
|
+
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
def singleton_method_url(klass, native)
|
|
28
|
+
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
def method_url(klass, native)
|
|
31
|
+
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
def attribute_url(klass, native)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
37
|
end
|
data/lib/rice/native.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
class Native
|
|
3
|
+
include Comparable
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
def <=>(other)
|
|
6
|
+
case
|
|
7
|
+
when self.name == other.name
|
|
8
|
+
self.parameters.size <=> other.parameters.size
|
|
9
|
+
when self.name == "initialize"
|
|
10
|
+
-1
|
|
11
|
+
when self.name == "initialize"
|
|
12
|
+
1
|
|
13
|
+
else
|
|
14
|
+
self.name <=> other.name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
18
|
end
|
data/lib/rice/native_registry.rb
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
class NativeRegistry
|
|
3
|
+
def native_attributes(klass)
|
|
4
|
+
self.lookup_by_kind(klass, Rice::NativeKind::AttributeReader) +
|
|
5
|
+
self.lookup_by_kind(klass, Rice::NativeKind::AttributeWriter)
|
|
6
|
+
end
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
def native_methods(klass)
|
|
9
|
+
self.lookup_by_kind(klass, Rice::NativeKind::Method)
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def native_by_kind(klass, kinds)
|
|
16
|
-
self.lookup(klass).find_all do |native|
|
|
17
|
-
kinds.include?(native.kind)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
12
|
+
def native_functions(klass)
|
|
13
|
+
self.lookup_by_kind(klass, Rice::NativeKind::Function)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
21
16
|
end
|
data/lib/rice/parameter.rb
CHANGED
data/lib/rice/rbs.rb
CHANGED
|
@@ -2,87 +2,87 @@ require 'erb'
|
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
|
|
4
4
|
module Rice
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
class Rbs
|
|
6
|
+
attr_reader :extension, :output
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def initialize(extension, output)
|
|
9
|
+
@extension = extension
|
|
10
|
+
@output = output
|
|
11
|
+
end
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
require self.extension
|
|
16
|
-
types = Registries.instance.types
|
|
17
|
-
types.klasses.each do |klass|
|
|
18
|
-
process_class(klass)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
13
|
+
def generate
|
|
14
|
+
STDOUT << "Writing rbs files to #{@output}" << "\n"
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
16
|
+
# Add the extension directory the path in case it ships with extra libraries
|
|
17
|
+
ENV["PATH"] = "#{File.dirname(self.extension)}#{File::PATH_SEPARATOR}#{ENV["PATH"]}"
|
|
18
|
+
require self.extension
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
types = Registries.instance.types
|
|
21
|
+
types.klasses.each do |klass|
|
|
22
|
+
process_class(klass)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
native_methods = Registries.instance.natives.native_methods(klass).sort.group_by(&:name)
|
|
32
|
-
content = render_template("class", :klass => klass,
|
|
33
|
-
:native_attributes => native_attributes,
|
|
34
|
-
:native_functions => native_functions,
|
|
35
|
-
:native_methods => native_methods)
|
|
36
|
-
write_file(klass, content)
|
|
37
|
-
end
|
|
26
|
+
def process_class(klass)
|
|
27
|
+
STDOUT << " " << klass << "\n"
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
native_attributes = Registries.instance.natives.native_attributes(klass).sort.group_by(&:name)
|
|
30
|
+
native_functions = Registries.instance.natives.native_functions(klass).sort.group_by(&:name)
|
|
31
|
+
native_methods = Registries.instance.natives.native_methods(klass).sort.group_by(&:name)
|
|
32
|
+
content = render_template("class", :klass => klass,
|
|
33
|
+
:native_attributes => native_attributes,
|
|
34
|
+
:native_functions => native_functions,
|
|
35
|
+
:native_methods => native_methods)
|
|
36
|
+
write_file(klass, content)
|
|
37
|
+
end
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
def write_file(klass, content)
|
|
40
|
+
parts = klass.name.split("::")
|
|
41
|
+
file_name = "#{parts.pop}.rbs"
|
|
42
|
+
dir = File.join(self.output, *parts)
|
|
43
|
+
FileUtils.mkdir_p(dir)
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
elsif native_attributes.first.kind == Rice::NativeKind::AttributeReader
|
|
53
|
-
"attr_reader"
|
|
54
|
-
else
|
|
55
|
-
"attr_writer"
|
|
56
|
-
end
|
|
57
|
-
"#{attr_type} #{native_attributes.first.name}: #{native_attributes.first.return_klass}"
|
|
58
|
-
end
|
|
45
|
+
path = File.join(dir, file_name)
|
|
46
|
+
File.write(path, content, mode: "wb")
|
|
47
|
+
end
|
|
59
48
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
def attribute_sig(native_attributes)
|
|
50
|
+
attr_type = if native_attributes.size == 2
|
|
51
|
+
"attr_accessor"
|
|
52
|
+
elsif native_attributes.first.kind == Rice::NativeKind::AttributeReader
|
|
53
|
+
"attr_reader"
|
|
54
|
+
else
|
|
55
|
+
"attr_writer"
|
|
56
|
+
end
|
|
57
|
+
"#{attr_type} #{native_attributes.first.name}: #{native_attributes.first.return_klass}"
|
|
58
|
+
end
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
def method_sigs(native_methods, indent = 0)
|
|
61
|
+
join_string = "\n" + (" " * indent) + "| "
|
|
62
|
+
a = native_methods.map do |native_method|
|
|
63
|
+
method_sig(native_method)
|
|
64
|
+
end
|
|
65
|
+
a.join(join_string)
|
|
66
|
+
end
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
template.result(b)
|
|
82
|
-
end
|
|
68
|
+
def method_sig(native)
|
|
69
|
+
params = native.parameters.map do |parameter|
|
|
70
|
+
"#{parameter.arg.name}: #{parameter.klass}"
|
|
71
|
+
end.join(", ")
|
|
72
|
+
"(#{params}) -> #{native.return_klass}"
|
|
73
|
+
end
|
|
83
74
|
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
def render_template(template, local_variables = {})
|
|
76
|
+
template = ERB.new(self.template, :trim_mode => '-')
|
|
77
|
+
b = self.binding
|
|
78
|
+
local_variables.each do |key, value|
|
|
79
|
+
b.local_variable_set(key, value)
|
|
80
|
+
end
|
|
81
|
+
template.result(b)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def template
|
|
85
|
+
<<~EOS
|
|
86
86
|
module <%= klass.name.split("::")[0..-2].join("::") %>
|
|
87
87
|
class <%= klass.name.split("::").last %>
|
|
88
88
|
<%- native_functions.each do |name, functions| -%>
|
|
@@ -98,7 +98,7 @@ module Rice
|
|
|
98
98
|
<%- end -%>
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
EOS
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
104
|
end
|
data/lib/rice/version.rb
CHANGED
data/lib/rubygems/builder.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
class Gem::Ext::Builder
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
alias :builder_for_original :builder_for
|
|
3
|
+
def builder_for(extension)
|
|
4
|
+
case extension
|
|
5
|
+
when /CMakeLists.txt/ then
|
|
6
|
+
Gem::Ext::CmakeBuilder.new
|
|
7
|
+
else
|
|
8
|
+
builder_for_original(extension)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
11
|
end
|
data/lib/rubygems_plugin.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# For older versions of RubyGems replace the default CMakeBuilder with a
|
|
2
2
|
# more modern one
|
|
3
3
|
if Gem.rubygems_version < Gem::Version.new('4.0')
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
Gem.pre_install do |installer|
|
|
5
|
+
extensions = installer.package&.spec&.extensions
|
|
6
|
+
if extensions && extensions.grep(/CMakeLists/)
|
|
7
|
+
require_relative 'rubygems/builder'
|
|
8
|
+
require_relative 'rubygems/cmake_builder'
|
|
9
|
+
end
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
12
|
end
|
data/rice/Data_Type.ipp
CHANGED
|
@@ -5,17 +5,22 @@ namespace Rice
|
|
|
5
5
|
template<typename T>
|
|
6
6
|
inline void ruby_mark_internal(detail::WrapperBase* wrapper)
|
|
7
7
|
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
detail::cpp_protect([&]
|
|
9
|
+
{
|
|
10
|
+
// Tell the wrapper to mark the objects its keeping alive
|
|
11
|
+
wrapper->ruby_mark();
|
|
12
|
+
|
|
13
|
+
// Get the underlying data and call custom mark function (if any)
|
|
14
|
+
// Use the wrapper's stored rb_data_type to avoid type mismatch
|
|
15
|
+
T* data = static_cast<T*>(wrapper->get(Data_Type<T>::ruby_data_type()));
|
|
16
|
+
ruby_mark<T>(data);
|
|
17
|
+
});
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
template<typename T>
|
|
17
21
|
inline void ruby_free_internal(detail::WrapperBase* wrapper)
|
|
18
22
|
{
|
|
23
|
+
// Destructors are noexcept so we cannot use cpp_protect here
|
|
19
24
|
delete wrapper;
|
|
20
25
|
}
|
|
21
26
|
|
|
@@ -380,7 +385,7 @@ namespace Rice
|
|
|
380
385
|
}
|
|
381
386
|
else
|
|
382
387
|
{
|
|
383
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
388
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
384
389
|
}
|
|
385
390
|
}
|
|
386
391
|
|
data/rice/cpp_api/Class.hpp
CHANGED
data/rice/cpp_api/Class.ipp
CHANGED
|
@@ -33,6 +33,11 @@ namespace Rice
|
|
|
33
33
|
return result;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
inline Class Class::superclass() const
|
|
37
|
+
{
|
|
38
|
+
return detail::protect(rb_class_superclass, this->value());
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
inline Class define_class_under(Object parent, Identifier id, const Class& superclass)
|
|
37
42
|
{
|
|
38
43
|
VALUE klass = detail::protect(rb_define_class_id_under, parent.value(), id, superclass.value());
|
data/rice/cpp_api/Object.hpp
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
namespace Rice
|
|
10
10
|
{
|
|
11
11
|
class Class;
|
|
12
|
+
class Module;
|
|
12
13
|
class String;
|
|
13
14
|
class Array;
|
|
14
15
|
|
|
@@ -116,6 +117,11 @@ namespace Rice
|
|
|
116
117
|
*/
|
|
117
118
|
bool is_a(Object klass) const;
|
|
118
119
|
|
|
120
|
+
//! Extend the object with a module.
|
|
121
|
+
/*! \param mod the module to extend with.
|
|
122
|
+
*/
|
|
123
|
+
void extend(Module const& mod);
|
|
124
|
+
|
|
119
125
|
//! Determine if the objects responds to a method.
|
|
120
126
|
/*! \param id the name of the method
|
|
121
127
|
* \return true if the objects responds to the method, false
|
data/rice/cpp_api/Object.ipp
CHANGED
|
@@ -99,6 +99,11 @@ namespace Rice
|
|
|
99
99
|
return RB_TEST(result);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
inline void Object::extend(Module const& mod)
|
|
103
|
+
{
|
|
104
|
+
detail::protect(rb_extend_object, this->value(), mod.value());
|
|
105
|
+
}
|
|
106
|
+
|
|
102
107
|
inline bool Object::respond_to(Identifier id) const
|
|
103
108
|
{
|
|
104
109
|
return bool(rb_respond_to(this->value(), id.id()));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#ifndef Rice__detail__Forwards__hpp_
|
|
2
|
+
#define Rice__detail__Forwards__hpp_
|
|
3
|
+
|
|
4
|
+
namespace Rice::detail
|
|
5
|
+
{
|
|
6
|
+
// Setup method forwarding from a wrapper class to its wrapped type using Ruby's Forwardable.
|
|
7
|
+
// This allows calling methods on the wrapper that get delegated to the wrapped object via
|
|
8
|
+
// a "get" method that returns the wrapped object.
|
|
9
|
+
//
|
|
10
|
+
// Parameters:
|
|
11
|
+
// wrapper_klass - The Ruby class to add forwarding to (e.g., SharedPtr_MyClass)
|
|
12
|
+
// wrapped_klass - The Ruby class whose methods should be forwarded (e.g., MyClass)
|
|
13
|
+
void define_forwarding(VALUE wrapper_klass, VALUE wrapped_klass);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#include "Forwards.ipp"
|
|
17
|
+
|
|
18
|
+
#endif // Rice__detail__Forwards__hpp_
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
namespace Rice::detail
|
|
2
|
+
{
|
|
3
|
+
inline void define_forwarding(VALUE wrapper_klass, VALUE wrapped_klass)
|
|
4
|
+
{
|
|
5
|
+
protect(rb_require, "forwardable");
|
|
6
|
+
Object forwardable = Object(rb_cObject).const_get("Forwardable");
|
|
7
|
+
Object(wrapper_klass).extend(forwardable.value());
|
|
8
|
+
|
|
9
|
+
// Get wrapper class's method names to avoid conflicts
|
|
10
|
+
std::set<std::string> wrapperMethodSet;
|
|
11
|
+
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::Method))
|
|
12
|
+
{
|
|
13
|
+
wrapperMethodSet.insert(native->name());
|
|
14
|
+
}
|
|
15
|
+
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::AttributeReader))
|
|
16
|
+
{
|
|
17
|
+
wrapperMethodSet.insert(native->name());
|
|
18
|
+
}
|
|
19
|
+
for (Native* native : Registries::instance.natives.lookup(wrapper_klass, NativeKind::AttributeWriter))
|
|
20
|
+
{
|
|
21
|
+
wrapperMethodSet.insert(native->name() + "=");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Get wrapped class's method names from the registry, including ancestor classes
|
|
25
|
+
std::set<std::string> wrappedMethodSet;
|
|
26
|
+
Class klass(wrapped_klass);
|
|
27
|
+
while (klass.value() != rb_cObject && klass.value() != Qnil)
|
|
28
|
+
{
|
|
29
|
+
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::Method))
|
|
30
|
+
{
|
|
31
|
+
wrappedMethodSet.insert(native->name());
|
|
32
|
+
}
|
|
33
|
+
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::AttributeReader))
|
|
34
|
+
{
|
|
35
|
+
wrappedMethodSet.insert(native->name());
|
|
36
|
+
}
|
|
37
|
+
for (Native* native : Registries::instance.natives.lookup(klass.value(), NativeKind::AttributeWriter))
|
|
38
|
+
{
|
|
39
|
+
wrappedMethodSet.insert(native->name() + "=");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
klass = klass.superclass();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Build the arguments array for def_delegators: [:get, :method1, :method2, ...]
|
|
46
|
+
// Skip methods that are already defined on the wrapper class
|
|
47
|
+
Array args;
|
|
48
|
+
args.push(Symbol("get"));
|
|
49
|
+
for (const std::string& method : wrappedMethodSet)
|
|
50
|
+
{
|
|
51
|
+
if (wrapperMethodSet.find(method) == wrapperMethodSet.end())
|
|
52
|
+
{
|
|
53
|
+
args.push(Symbol(method));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Call def_delegators(*args)
|
|
58
|
+
Object(wrapper_klass).vcall("def_delegators", args);
|
|
59
|
+
}
|
|
60
|
+
}
|
data/rice/detail/Native.ipp
CHANGED
|
@@ -176,16 +176,14 @@ namespace Rice::detail
|
|
|
176
176
|
Arg* arg = parameters_[i]->arg();
|
|
177
177
|
if (arg->isKeepAlive())
|
|
178
178
|
{
|
|
179
|
-
|
|
180
|
-
selfWrapper->addKeepAlive(rubyValues[i].value());
|
|
179
|
+
WrapperBase::addKeepAlive(self, rubyValues[i].value());
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
// Check return value
|
|
185
184
|
if (this->returnInfo_->isKeepAlive())
|
|
186
185
|
{
|
|
187
|
-
WrapperBase
|
|
188
|
-
returnWrapper->addKeepAlive(self);
|
|
186
|
+
WrapperBase::addKeepAlive(returnValue, self);
|
|
189
187
|
}
|
|
190
188
|
}
|
|
191
189
|
|