rice 4.9.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 +17 -1
- data/CMakePresets.json +77 -50
- data/FindRuby.cmake +1 -1
- data/include/rice/rice.hpp +114 -81
- data/include/rice/stl.hpp +157 -95
- 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 -48
- data/lib/rice/doc/ruby.rb +26 -26
- data/lib/rice/native.rb +15 -15
- data/lib/rice/native_registry.rb +12 -12
- data/lib/rice/parameter.rb +5 -5
- data/lib/rice/rbs.rb +71 -71
- 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 +1 -1
- 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 +3 -2
- data/rice/detail/NativeRegistry.ipp +13 -9
- data/rice/detail/Parameter.ipp +3 -4
- data/rice/detail/Wrapper.hpp +5 -1
- data/rice/detail/Wrapper.ipp +15 -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.ipp +15 -1
- data/rice/stl/type_index.ipp +1 -1
- data/rice/stl/unique_ptr.ipp +2 -2
- 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_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_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 +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6482695048d122782acef1d7ee310c47c85cff57eb39c8740db46013a4af0e87
|
|
4
|
+
data.tar.gz: a4b3c772ac9d5baff75ad80dbc404dde8a3fc67c821836203dfdcef948877091
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 553618d580f7734d23a0c0278636fe725f48cacd68572fa9d6cee828fed68b2af84cda1fecdad4bb65633ada077bf4b34a703e2bd25173bd4f3ae0de91c54c26
|
|
7
|
+
data.tar.gz: '0368ac5a1d1d957ab8a94dcec8a25c6e5cc539930848db9f78077c6006b86a6d81299af839ab1daed52fab9ce743496cebcff6e3698483961c0fc6cc2bef82b4'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 4.9.1 (2026-01-04)
|
|
4
|
+
This release focuses on improving memory management for STL containers and attribute setters.
|
|
5
|
+
|
|
6
|
+
Enhancements:
|
|
7
|
+
* Support `takeOwnership` and `keepAlive` when setting attributes via `Arg("value").takeOwnership()` and `Arg("value").keepAlive()`
|
|
8
|
+
* Add `Arg` parameter names to all STL container methods for keyword argument support
|
|
9
|
+
* Add `keepAlive` support for STL container operations (vector push/insert, set insert, map/multimap store)
|
|
10
|
+
* Add `keepAlive` for map/unordered_map/multimap keys to prevent GC of pointer-type keys
|
|
11
|
+
|
|
12
|
+
Bug Fixes:
|
|
13
|
+
* Fix error when multiple overloaded methods take different types of vectors
|
|
14
|
+
* Fix type unknown errors when using `std::shared_ptr` with g++
|
|
15
|
+
* Fix CMake `_Ruby_DLEXT` variable type (string, not path)
|
|
16
|
+
* Fix crash caused by static variable in keepAlive implementation
|
|
17
|
+
* Fix incorrect attribute overloading behavior
|
|
2
18
|
|
|
3
19
|
## 4.9.0 (2026-01-01)
|
|
4
20
|
This release revamps smart pointer support for `std::shared_ptr` and `std::unique_ptr`.
|
data/CMakePresets.json
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"hidden": true,
|
|
7
7
|
"generator": "Ninja",
|
|
8
8
|
"binaryDir": "${sourceDir}/build/${presetName}",
|
|
9
|
-
"installDir": "${sourceDir}/install/${presetName}"
|
|
9
|
+
"installDir": "${sourceDir}/install/${presetName}",
|
|
10
|
+
"cacheVariables": {
|
|
11
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
|
12
|
+
"CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden"
|
|
13
|
+
}
|
|
10
14
|
},
|
|
11
15
|
{
|
|
12
16
|
"name": "linux-debug",
|
|
@@ -14,7 +18,7 @@
|
|
|
14
18
|
"displayName": "Linux Debug",
|
|
15
19
|
"cacheVariables": {
|
|
16
20
|
"CMAKE_BUILD_TYPE": "Debug",
|
|
17
|
-
"
|
|
21
|
+
"CMAKE_CXX_FLAGS_DEBUG": "-ggdb3 -O0 -fno-omit-frame-pointer -fno-inline -fno-optimize-sibling-calls"
|
|
18
22
|
},
|
|
19
23
|
"condition": {
|
|
20
24
|
"type": "equals",
|
|
@@ -28,7 +32,9 @@
|
|
|
28
32
|
"displayName": "Linux Release",
|
|
29
33
|
"cacheVariables": {
|
|
30
34
|
"CMAKE_BUILD_TYPE": "Release",
|
|
31
|
-
"
|
|
35
|
+
"CMAKE_CXX_FLAGS_RELEASE": "-O3 -DNDEBUG",
|
|
36
|
+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON",
|
|
37
|
+
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "-Wl,--exclude-libs,ALL -Wl,--strip-all"
|
|
32
38
|
},
|
|
33
39
|
"condition": {
|
|
34
40
|
"type": "equals",
|
|
@@ -42,7 +48,8 @@
|
|
|
42
48
|
"displayName": "macOS Debug",
|
|
43
49
|
"cacheVariables": {
|
|
44
50
|
"CMAKE_BUILD_TYPE": "Debug",
|
|
45
|
-
"CMAKE_CXX_FLAGS": "-Wall -Wno-unused-private-field -ftemplate-backtrace-limit=0 -
|
|
51
|
+
"CMAKE_CXX_FLAGS": "-Wall -Wno-unused-private-field -ftemplate-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden",
|
|
52
|
+
"CMAKE_CXX_FLAGS_DEBUG": "-g3 -Og -fno-omit-frame-pointer -fno-inline -gsplit-dwarf"
|
|
46
53
|
},
|
|
47
54
|
"condition": {
|
|
48
55
|
"type": "equals",
|
|
@@ -56,7 +63,10 @@
|
|
|
56
63
|
"displayName": "macOS Release",
|
|
57
64
|
"cacheVariables": {
|
|
58
65
|
"CMAKE_BUILD_TYPE": "Release",
|
|
59
|
-
"CMAKE_CXX_FLAGS": "-Wall -Wno-unused-private-field -ftemplate-backtrace-limit=0 -
|
|
66
|
+
"CMAKE_CXX_FLAGS": "-Wall -Wno-unused-private-field -ftemplate-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden",
|
|
67
|
+
"CMAKE_CXX_FLAGS_RELEASE": "-O3 -DNDEBUG",
|
|
68
|
+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON",
|
|
69
|
+
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "-Wl,-dead_strip -Wl,-x"
|
|
60
70
|
},
|
|
61
71
|
"condition": {
|
|
62
72
|
"type": "equals",
|
|
@@ -65,99 +75,116 @@
|
|
|
65
75
|
}
|
|
66
76
|
},
|
|
67
77
|
{
|
|
68
|
-
"name": "
|
|
69
|
-
"
|
|
78
|
+
"name": "mingw-debug",
|
|
79
|
+
"inherits": "base",
|
|
80
|
+
"displayName": "Mingw x64 Debug",
|
|
81
|
+
"cacheVariables": {
|
|
82
|
+
"CMAKE_BUILD_TYPE": "Debug",
|
|
83
|
+
"CMAKE_CXX_COMPILER": "g++.exe",
|
|
84
|
+
"CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
|
|
85
|
+
"CMAKE_CXX_FLAGS_DEBUG": "-g3 -Og -fno-omit-frame-pointer -fno-inline -gsplit-dwarf"
|
|
86
|
+
},
|
|
87
|
+
"condition": {
|
|
88
|
+
"type": "equals",
|
|
89
|
+
"lhs": "${hostSystemName}",
|
|
90
|
+
"rhs": "Windows"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "mingw-release",
|
|
70
95
|
"inherits": "base",
|
|
96
|
+
"displayName": "Mingw x64 Release",
|
|
97
|
+
"cacheVariables": {
|
|
98
|
+
"CMAKE_BUILD_TYPE": "Release",
|
|
99
|
+
"CMAKE_CXX_COMPILER": "g++.exe",
|
|
100
|
+
"CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
|
|
101
|
+
"CMAKE_CXX_FLAGS_RELEASE": "-O3 -DNDEBUG",
|
|
102
|
+
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "-Wl,--exclude-all-symbols"
|
|
103
|
+
},
|
|
71
104
|
"condition": {
|
|
72
105
|
"type": "equals",
|
|
73
106
|
"lhs": "${hostSystemName}",
|
|
74
107
|
"rhs": "Windows"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "windows-base",
|
|
112
|
+
"hidden": true,
|
|
113
|
+
"generator": "Ninja",
|
|
114
|
+
"binaryDir": "${sourceDir}/build/${presetName}",
|
|
115
|
+
"installDir": "${sourceDir}/install/${presetName}",
|
|
116
|
+
"toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake",
|
|
117
|
+
"cacheVariables": {
|
|
118
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
|
119
|
+
"CMAKE_CXX_FLAGS": "/EHs /W4 /bigobj /utf-8 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE"
|
|
75
120
|
},
|
|
76
|
-
"
|
|
121
|
+
"condition": {
|
|
122
|
+
"type": "equals",
|
|
123
|
+
"lhs": "${hostSystemName}",
|
|
124
|
+
"rhs": "Windows"
|
|
125
|
+
}
|
|
77
126
|
},
|
|
78
127
|
{
|
|
79
128
|
"name": "msvc-debug",
|
|
80
|
-
"inherits": "windows",
|
|
129
|
+
"inherits": "windows-base",
|
|
81
130
|
"displayName": "MSVC x64 Debug",
|
|
82
131
|
"cacheVariables": {
|
|
83
132
|
"CMAKE_BUILD_TYPE": "Debug",
|
|
84
133
|
"CMAKE_CXX_COMPILER": "cl.exe",
|
|
85
|
-
"
|
|
86
|
-
"CMAKE_MSVC_DEBUG_INFORMATION_FORMAT": "
|
|
134
|
+
"CMAKE_CXX_FLAGS_DEBUG": "/Od",
|
|
135
|
+
"CMAKE_MSVC_DEBUG_INFORMATION_FORMAT": "ProgramDatabase"
|
|
87
136
|
}
|
|
88
137
|
},
|
|
89
138
|
{
|
|
90
139
|
"name": "msvc-release",
|
|
91
|
-
"inherits": "windows",
|
|
140
|
+
"inherits": "windows-base",
|
|
92
141
|
"displayName": "MSVC x64 Release",
|
|
93
142
|
"cacheVariables": {
|
|
94
143
|
"CMAKE_BUILD_TYPE": "Release",
|
|
95
144
|
"CMAKE_CXX_COMPILER": "cl.exe",
|
|
96
|
-
"
|
|
145
|
+
"CMAKE_CXX_FLAGS_RELEASE": "/O2 /DNDEBUG",
|
|
146
|
+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON",
|
|
97
147
|
"CMAKE_MSVC_DEBUG_INFORMATION_FORMAT": "ProgramDatabase"
|
|
98
148
|
}
|
|
99
149
|
},
|
|
150
|
+
|
|
100
151
|
{
|
|
101
152
|
"name": "clang-windows-debug",
|
|
102
|
-
"inherits": "windows",
|
|
153
|
+
"inherits": "windows-base",
|
|
103
154
|
"displayName": "Clang Windows Debug",
|
|
104
155
|
"cacheVariables": {
|
|
105
156
|
"CMAKE_BUILD_TYPE": "Debug",
|
|
106
157
|
"CMAKE_CXX_COMPILER": "clang-cl.exe",
|
|
107
|
-
"CMAKE_CXX_FLAGS": "/EHs /W4 /bigobj /utf-8 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /clang:-Wno-unused-private-field"
|
|
158
|
+
"CMAKE_CXX_FLAGS": "/EHs /W4 /bigobj /utf-8 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /clang:-Wno-unused-private-field",
|
|
159
|
+
"CMAKE_CXX_FLAGS_DEBUG": "/Od /Zi"
|
|
108
160
|
}
|
|
109
161
|
},
|
|
110
162
|
{
|
|
111
163
|
"name": "clang-windows-release",
|
|
112
|
-
"inherits": "windows",
|
|
164
|
+
"inherits": "windows-base",
|
|
113
165
|
"displayName": "Clang Windows Release",
|
|
114
166
|
"cacheVariables": {
|
|
115
167
|
"CMAKE_BUILD_TYPE": "Release",
|
|
116
168
|
"CMAKE_CXX_COMPILER": "clang-cl.exe",
|
|
117
|
-
"CMAKE_CXX_FLAGS": "/EHs /W4 /bigobj /utf-8 /
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
{
|
|
121
|
-
"name": "mingw-debug",
|
|
122
|
-
"inherits": "base",
|
|
123
|
-
"displayName": "Mingw x64 Debug",
|
|
124
|
-
"cacheVariables": {
|
|
125
|
-
"CMAKE_BUILD_TYPE": "Debug",
|
|
126
|
-
"CMAKE_CXX_COMPILER": "g++.exe",
|
|
127
|
-
"CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -Og"
|
|
128
|
-
},
|
|
129
|
-
"condition": {
|
|
130
|
-
"type": "equals",
|
|
131
|
-
"lhs": "${hostSystemName}",
|
|
132
|
-
"rhs": "Windows"
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
"name": "mingw-release",
|
|
137
|
-
"inherits": "base",
|
|
138
|
-
"displayName": "Mingw x64 Release",
|
|
139
|
-
"cacheVariables": {
|
|
140
|
-
"CMAKE_BUILD_TYPE": "Release",
|
|
141
|
-
"CMAKE_CXX_COMPILER": "g++.exe",
|
|
142
|
-
"CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -O3 -DNDEBUG"
|
|
143
|
-
},
|
|
144
|
-
"condition": {
|
|
145
|
-
"type": "equals",
|
|
146
|
-
"lhs": "${hostSystemName}",
|
|
147
|
-
"rhs": "Windows"
|
|
169
|
+
"CMAKE_CXX_FLAGS": "/EHs /W4 /bigobj /utf-8 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /clang:-Wno-unused-private-field",
|
|
170
|
+
"CMAKE_CXX_FLAGS_RELEASE": "/O2 /DNDEBUG",
|
|
171
|
+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON"
|
|
148
172
|
}
|
|
149
173
|
}
|
|
150
174
|
],
|
|
175
|
+
|
|
151
176
|
"buildPresets": [
|
|
152
177
|
{
|
|
153
178
|
"name": "linux-debug",
|
|
154
179
|
"displayName": "Build Linux Debug",
|
|
155
|
-
"configurePreset": "linux-debug"
|
|
180
|
+
"configurePreset": "linux-debug",
|
|
181
|
+
"jobs": 6
|
|
156
182
|
},
|
|
157
183
|
{
|
|
158
184
|
"name": "linux-release",
|
|
159
185
|
"displayName": "Build Linux Release",
|
|
160
|
-
"configurePreset": "linux-release"
|
|
186
|
+
"configurePreset": "linux-release",
|
|
187
|
+
"jobs": 6
|
|
161
188
|
},
|
|
162
189
|
{
|
|
163
190
|
"name": "macos-debug",
|
|
@@ -200,4 +227,4 @@
|
|
|
200
227
|
"configurePreset": "mingw-release"
|
|
201
228
|
}
|
|
202
229
|
]
|
|
203
|
-
}
|
|
230
|
+
}
|
data/FindRuby.cmake
CHANGED
|
@@ -428,7 +428,7 @@ if (Ruby_EXECUTABLE AND NOT Ruby_EXECUTABLE STREQUAL "${_Ruby_EXECUTABLE_LAST_QU
|
|
|
428
428
|
set(_Ruby_POSSIBLE_LIB_DIR ${_Ruby_POSSIBLE_LIB_DIR} CACHE INTERNAL "The Ruby lib dir" FORCE)
|
|
429
429
|
set(Ruby_RUBY_LIB_DIR ${Ruby_RUBY_LIB_DIR} CACHE INTERNAL "The Ruby ruby-lib dir" FORCE)
|
|
430
430
|
set(_Ruby_SO_NAME ${_Ruby_SO_NAME} CACHE PATH "The Ruby shared library name" FORCE)
|
|
431
|
-
set(_Ruby_DLEXT ${_Ruby_DLEXT} CACHE
|
|
431
|
+
set(_Ruby_DLEXT ${_Ruby_DLEXT} CACHE STRING "Ruby extensions extension" FORCE)
|
|
432
432
|
set(Ruby_SITEARCH_DIR ${Ruby_SITEARCH_DIR} CACHE INTERNAL "The Ruby site arch dir" FORCE)
|
|
433
433
|
set(Ruby_SITELIB_DIR ${Ruby_SITELIB_DIR} CACHE INTERNAL "The Ruby site lib dir" FORCE)
|
|
434
434
|
set(Ruby_HAS_VENDOR_RUBY ${Ruby_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
|
data/include/rice/rice.hpp
CHANGED
|
@@ -599,6 +599,10 @@ namespace Rice::detail
|
|
|
599
599
|
{
|
|
600
600
|
class WrapperBase
|
|
601
601
|
{
|
|
602
|
+
public:
|
|
603
|
+
static void addKeepAlive(VALUE object, VALUE keepAlive);
|
|
604
|
+
static bool isConst(VALUE object);
|
|
605
|
+
|
|
602
606
|
public:
|
|
603
607
|
WrapperBase(rb_data_type_t* rb_data_type);
|
|
604
608
|
virtual ~WrapperBase() = default;
|
|
@@ -672,7 +676,7 @@ namespace Rice::detail
|
|
|
672
676
|
|
|
673
677
|
// ---- Helper Functions ---------
|
|
674
678
|
template <typename T>
|
|
675
|
-
|
|
679
|
+
Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data);
|
|
676
680
|
|
|
677
681
|
template <typename T>
|
|
678
682
|
VALUE wrap(VALUE klass, rb_data_type_t* rb_data_type, T& data, bool isOwner);
|
|
@@ -3020,8 +3024,9 @@ namespace Rice
|
|
|
3020
3024
|
using Receiver_T = typename attribute_traits<Attribute_T>::class_type;
|
|
3021
3025
|
|
|
3022
3026
|
public:
|
|
3023
|
-
// Register attribute
|
|
3024
|
-
|
|
3027
|
+
// Register attribute setter with Ruby
|
|
3028
|
+
template<typename...Arg_Ts>
|
|
3029
|
+
static void define(VALUE klass, std::string name, Attribute_T attribute, Arg_Ts&...args);
|
|
3025
3030
|
|
|
3026
3031
|
public:
|
|
3027
3032
|
// Disallow creating/copying/moving
|
|
@@ -3039,11 +3044,12 @@ namespace Rice
|
|
|
3039
3044
|
VALUE returnKlass() override;
|
|
3040
3045
|
|
|
3041
3046
|
protected:
|
|
3042
|
-
NativeAttributeSet(VALUE klass, std::string name, Attribute_T attr);
|
|
3047
|
+
NativeAttributeSet(VALUE klass, std::string name, Attribute_T attr, std::unique_ptr<Parameter<T_Unqualified>> parameter);
|
|
3043
3048
|
|
|
3044
3049
|
private:
|
|
3045
3050
|
VALUE klass_;
|
|
3046
3051
|
Attribute_T attribute_;
|
|
3052
|
+
std::unique_ptr<Parameter<T_Unqualified>> parameter_;
|
|
3047
3053
|
};
|
|
3048
3054
|
} // detail
|
|
3049
3055
|
} // Rice
|
|
@@ -3804,10 +3810,11 @@ namespace Rice::detail
|
|
|
3804
3810
|
NativeRegistry& operator=(const NativeRegistry& other) = delete;
|
|
3805
3811
|
|
|
3806
3812
|
void add(VALUE klass, ID methodId, std::unique_ptr<Native>& native);
|
|
3813
|
+
void replace(VALUE klass, ID methodId, std::unique_ptr<Native>& native);
|
|
3807
3814
|
void reset(VALUE klass);
|
|
3808
3815
|
|
|
3809
|
-
|
|
3810
|
-
|
|
3816
|
+
std::vector<Native*> lookup(VALUE klass);
|
|
3817
|
+
std::vector<std::unique_ptr<Native>>& lookup(VALUE klass, ID methodId);
|
|
3811
3818
|
std::vector<Native*> lookup(VALUE klass, NativeKind kind);
|
|
3812
3819
|
|
|
3813
3820
|
private:
|
|
@@ -3976,17 +3983,16 @@ namespace Rice::detail
|
|
|
3976
3983
|
// One caveat - procs are also RUBY_T_DATA so don't check if this is a function type
|
|
3977
3984
|
if (result == Convertible::Exact && rb_type(value) == RUBY_T_DATA && !std::is_function_v<std::remove_pointer_t<T>>)
|
|
3978
3985
|
{
|
|
3979
|
-
|
|
3980
|
-
WrapperBase* wrapper = getWrapper(value);
|
|
3986
|
+
bool isConst = WrapperBase::isConst(value);
|
|
3981
3987
|
|
|
3982
3988
|
// Do not send a const value to a non-const parameter
|
|
3983
|
-
if (
|
|
3989
|
+
if (isConst && !is_const_any_v<T>)
|
|
3984
3990
|
{
|
|
3985
3991
|
result = Convertible::None;
|
|
3986
3992
|
}
|
|
3987
3993
|
// It is ok to send a non-const value to a const parameter but
|
|
3988
3994
|
// prefer non-const to non-const by slightly decreasing the score
|
|
3989
|
-
else if (!
|
|
3995
|
+
else if (!isConst && is_const_any_v<T>)
|
|
3990
3996
|
{
|
|
3991
3997
|
result = Convertible::ConstMismatch;
|
|
3992
3998
|
}
|
|
@@ -8929,17 +8935,21 @@ namespace Rice::detail
|
|
|
8929
8935
|
{
|
|
8930
8936
|
inline void NativeRegistry::add(VALUE klass, ID methodId, std::unique_ptr<Native>& native)
|
|
8931
8937
|
{
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
klass = detail::protect(rb_class_of, klass);
|
|
8935
|
-
}
|
|
8938
|
+
// Lookup items for method
|
|
8939
|
+
std::vector<std::unique_ptr<Native>>& natives = NativeRegistry::lookup(klass, methodId);
|
|
8936
8940
|
|
|
8937
|
-
//
|
|
8938
|
-
std::
|
|
8941
|
+
// Add new native
|
|
8942
|
+
natives.push_back(std::move(native));
|
|
8943
|
+
}
|
|
8939
8944
|
|
|
8945
|
+
inline void NativeRegistry::replace(VALUE klass, ID methodId, std::unique_ptr<Native>& native)
|
|
8946
|
+
{
|
|
8940
8947
|
// Lookup items for method
|
|
8941
|
-
std::vector<std::unique_ptr<Native>>& natives =
|
|
8948
|
+
std::vector<std::unique_ptr<Native>>& natives = NativeRegistry::lookup(klass, methodId);
|
|
8942
8949
|
|
|
8950
|
+
// Clear existing natives
|
|
8951
|
+
natives.clear();
|
|
8952
|
+
// Add new native
|
|
8943
8953
|
natives.push_back(std::move(native));
|
|
8944
8954
|
}
|
|
8945
8955
|
|
|
@@ -8959,7 +8969,7 @@ namespace Rice::detail
|
|
|
8959
8969
|
}
|
|
8960
8970
|
}
|
|
8961
8971
|
|
|
8962
|
-
inline
|
|
8972
|
+
inline std::vector<Native*> NativeRegistry::lookup(VALUE klass)
|
|
8963
8973
|
{
|
|
8964
8974
|
std::vector<Native*> result;
|
|
8965
8975
|
|
|
@@ -8985,7 +8995,7 @@ namespace Rice::detail
|
|
|
8985
8995
|
return result;
|
|
8986
8996
|
}
|
|
8987
8997
|
|
|
8988
|
-
inline
|
|
8998
|
+
inline std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
|
|
8989
8999
|
{
|
|
8990
9000
|
if (rb_type(klass) == T_ICLASS)
|
|
8991
9001
|
{
|
|
@@ -9577,6 +9587,18 @@ namespace Rice::detail
|
|
|
9577
9587
|
|
|
9578
9588
|
namespace Rice::detail
|
|
9579
9589
|
{
|
|
9590
|
+
inline void WrapperBase::addKeepAlive(VALUE object, VALUE keepAlive)
|
|
9591
|
+
{
|
|
9592
|
+
WrapperBase* wrapper = getWrapper(object);
|
|
9593
|
+
wrapper->addKeepAlive(keepAlive);
|
|
9594
|
+
}
|
|
9595
|
+
|
|
9596
|
+
inline bool WrapperBase::isConst(VALUE object)
|
|
9597
|
+
{
|
|
9598
|
+
WrapperBase* wrapper = getWrapper(object);
|
|
9599
|
+
return wrapper->isConst();
|
|
9600
|
+
}
|
|
9601
|
+
|
|
9580
9602
|
inline WrapperBase::WrapperBase(rb_data_type_t* rb_data_type) : rb_data_type_(rb_data_type)
|
|
9581
9603
|
{
|
|
9582
9604
|
}
|
|
@@ -9874,7 +9896,7 @@ namespace Rice::detail
|
|
|
9874
9896
|
}
|
|
9875
9897
|
|
|
9876
9898
|
template <typename T>
|
|
9877
|
-
inline
|
|
9899
|
+
inline Wrapper<T*>* wrapConstructed(VALUE value, rb_data_type_t* rb_data_type, T* data)
|
|
9878
9900
|
{
|
|
9879
9901
|
using Wrapper_T = Wrapper<T*>;
|
|
9880
9902
|
|
|
@@ -9890,6 +9912,8 @@ namespace Rice::detail
|
|
|
9890
9912
|
RTYPEDDATA_DATA(value) = wrapper;
|
|
9891
9913
|
|
|
9892
9914
|
Registries::instance.instances.add(data, value);
|
|
9915
|
+
|
|
9916
|
+
return wrapper;
|
|
9893
9917
|
}
|
|
9894
9918
|
}
|
|
9895
9919
|
|
|
@@ -10072,16 +10096,14 @@ namespace Rice::detail
|
|
|
10072
10096
|
Arg* arg = parameters_[i]->arg();
|
|
10073
10097
|
if (arg->isKeepAlive())
|
|
10074
10098
|
{
|
|
10075
|
-
|
|
10076
|
-
selfWrapper->addKeepAlive(rubyValues[i].value());
|
|
10099
|
+
WrapperBase::addKeepAlive(self, rubyValues[i].value());
|
|
10077
10100
|
}
|
|
10078
10101
|
}
|
|
10079
10102
|
|
|
10080
10103
|
// Check return value
|
|
10081
10104
|
if (this->returnInfo_->isKeepAlive())
|
|
10082
10105
|
{
|
|
10083
|
-
WrapperBase
|
|
10084
|
-
returnWrapper->addKeepAlive(self);
|
|
10106
|
+
WrapperBase::addKeepAlive(returnValue, self);
|
|
10085
10107
|
}
|
|
10086
10108
|
}
|
|
10087
10109
|
|
|
@@ -10420,7 +10442,7 @@ namespace Rice::detail
|
|
|
10420
10442
|
// matches or calls function pointer. Instead Ruby can call the static call method defined on
|
|
10421
10443
|
// this class (&NativeAttribute_T::get).
|
|
10422
10444
|
Identifier identifier(name);
|
|
10423
|
-
detail::Registries::instance.natives.
|
|
10445
|
+
detail::Registries::instance.natives.replace(klass, identifier.id(), native);
|
|
10424
10446
|
}
|
|
10425
10447
|
|
|
10426
10448
|
template<typename Attribute_T>
|
|
@@ -10525,28 +10547,46 @@ namespace Rice::detail
|
|
|
10525
10547
|
namespace Rice::detail
|
|
10526
10548
|
{
|
|
10527
10549
|
template<typename Attribute_T>
|
|
10528
|
-
|
|
10550
|
+
template<typename...Arg_Ts>
|
|
10551
|
+
void NativeAttributeSet<Attribute_T>::define(VALUE klass, std::string name, Attribute_T attribute, Arg_Ts&...args)
|
|
10529
10552
|
{
|
|
10530
|
-
//
|
|
10531
|
-
|
|
10553
|
+
// Extract Arg from Arg_Ts if present, otherwise create default
|
|
10554
|
+
using Arg_Tuple = std::tuple<Arg_Ts...>;
|
|
10555
|
+
constexpr std::size_t index = tuple_element_index_v<Arg_Tuple, Arg, ArgBuffer>;
|
|
10556
|
+
|
|
10557
|
+
std::unique_ptr<Arg> arg;
|
|
10558
|
+
if constexpr (index < std::tuple_size_v<Arg_Tuple>)
|
|
10559
|
+
{
|
|
10560
|
+
using Arg_T_Local = std::decay_t<std::tuple_element_t<index, Arg_Tuple>>;
|
|
10561
|
+
const Arg_T_Local& argInfo = std::get<index>(std::forward_as_tuple(std::forward<Arg_Ts>(args)...));
|
|
10562
|
+
arg = std::make_unique<Arg_T_Local>(argInfo);
|
|
10563
|
+
}
|
|
10564
|
+
else
|
|
10565
|
+
{
|
|
10566
|
+
arg = std::make_unique<Arg>("value");
|
|
10567
|
+
}
|
|
10568
|
+
|
|
10569
|
+
// Create the parameter
|
|
10570
|
+
auto parameter = std::make_unique<Parameter<T_Unqualified>>(std::move(arg));
|
|
10571
|
+
|
|
10572
|
+
// Create a NativeAttributeSet that Ruby will call to write C++ variables
|
|
10573
|
+
NativeAttribute_T* nativeAttribute = new NativeAttribute_T(klass, name, std::forward<Attribute_T>(attribute), std::move(parameter));
|
|
10532
10574
|
std::unique_ptr<Native> native(nativeAttribute);
|
|
10533
10575
|
|
|
10534
10576
|
// Define the write method name
|
|
10535
10577
|
std::string setter = name + "=";
|
|
10536
10578
|
|
|
10537
|
-
// Tell Ruby to invoke the static method
|
|
10579
|
+
// Tell Ruby to invoke the static method resolve to set the attribute value
|
|
10538
10580
|
detail::protect(rb_define_method, klass, setter.c_str(), (RUBY_METHOD_FUNC)&Native::resolve, -1);
|
|
10539
10581
|
|
|
10540
|
-
// Add to native registry
|
|
10541
|
-
// matches or calls function pointer. Instead Ruby can call the static call method defined on
|
|
10542
|
-
// this class (&NativeAttribute_T::set).
|
|
10582
|
+
// Add to native registry
|
|
10543
10583
|
Identifier identifier(setter);
|
|
10544
|
-
detail::Registries::instance.natives.
|
|
10584
|
+
detail::Registries::instance.natives.replace(klass, identifier.id(), native);
|
|
10545
10585
|
}
|
|
10546
10586
|
|
|
10547
10587
|
template<typename Attribute_T>
|
|
10548
|
-
NativeAttributeSet<Attribute_T>::NativeAttributeSet(VALUE klass, std::string name, Attribute_T attribute)
|
|
10549
|
-
: Native(name), klass_(klass), attribute_(attribute)
|
|
10588
|
+
NativeAttributeSet<Attribute_T>::NativeAttributeSet(VALUE klass, std::string name, Attribute_T attribute, std::unique_ptr<Parameter<T_Unqualified>> parameter)
|
|
10589
|
+
: Native(name), klass_(klass), attribute_(attribute), parameter_(std::move(parameter))
|
|
10550
10590
|
{
|
|
10551
10591
|
}
|
|
10552
10592
|
|
|
@@ -10567,25 +10607,25 @@ namespace Rice::detail
|
|
|
10567
10607
|
throw std::runtime_error("Incorrect number of parameters for setting attribute. Attribute: " + this->name_);
|
|
10568
10608
|
}
|
|
10569
10609
|
|
|
10610
|
+
// Get the Ruby value and convert to native
|
|
10570
10611
|
VALUE value = values.begin()->second;
|
|
10612
|
+
std::optional<VALUE> valueOpt(value);
|
|
10613
|
+
T_Unqualified nativeValue = this->parameter_->convertToNative(valueOpt);
|
|
10571
10614
|
|
|
10572
10615
|
if constexpr (!std::is_null_pointer_v<Receiver_T>)
|
|
10573
10616
|
{
|
|
10574
10617
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
|
10575
|
-
|
|
10576
|
-
// Deal with pointers to pointes, see Parameter::convertToNative commment
|
|
10577
|
-
if constexpr (is_pointer_pointer_v<Attr_T> && !std::is_convertible_v<remove_cv_recursive_t<Attr_T>, Attr_T>)
|
|
10578
|
-
{
|
|
10579
|
-
nativeSelf->*attribute_ = (Attr_T)From_Ruby<T_Unqualified>().convert(value);
|
|
10580
|
-
}
|
|
10581
|
-
else
|
|
10582
|
-
{
|
|
10583
|
-
nativeSelf->*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
|
10584
|
-
}
|
|
10618
|
+
nativeSelf->*attribute_ = (Attr_T)nativeValue;
|
|
10585
10619
|
}
|
|
10586
10620
|
else
|
|
10587
10621
|
{
|
|
10588
|
-
*attribute_ =
|
|
10622
|
+
*attribute_ = nativeValue;
|
|
10623
|
+
}
|
|
10624
|
+
|
|
10625
|
+
// Check if we need to prevent the value from being garbage collected
|
|
10626
|
+
if (this->parameter_->arg()->isKeepAlive())
|
|
10627
|
+
{
|
|
10628
|
+
WrapperBase::addKeepAlive(self, value);
|
|
10589
10629
|
}
|
|
10590
10630
|
|
|
10591
10631
|
return value;
|
|
@@ -10606,18 +10646,8 @@ namespace Rice::detail
|
|
|
10606
10646
|
template<typename Attribute_T>
|
|
10607
10647
|
inline VALUE NativeAttributeSet<Attribute_T>::returnKlass()
|
|
10608
10648
|
{
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
if (isBuffer)
|
|
10612
|
-
{
|
|
10613
|
-
TypeMapper<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Attr_T>>>> typeMapper;
|
|
10614
|
-
return typeMapper.rubyKlass();
|
|
10615
|
-
}
|
|
10616
|
-
else
|
|
10617
|
-
{
|
|
10618
|
-
TypeMapper<Attr_T> typeMapper;
|
|
10619
|
-
return typeMapper.rubyKlass();
|
|
10620
|
-
}
|
|
10649
|
+
TypeMapper<Attr_T> typeMapper;
|
|
10650
|
+
return typeMapper.rubyKlass();
|
|
10621
10651
|
}
|
|
10622
10652
|
}
|
|
10623
10653
|
|
|
@@ -11257,30 +11287,33 @@ namespace Rice::detail
|
|
|
11257
11287
|
{
|
|
11258
11288
|
return self;
|
|
11259
11289
|
}
|
|
11260
|
-
/* This case happens when a class wrapped by Rice is calling a method
|
|
11261
|
-
defined on an ancestor class. For example, the std::map size method
|
|
11262
|
-
is defined on _Tree not map. Rice needs to know the actual type
|
|
11263
|
-
that was wrapped so it can correctly extract the C++ object from
|
|
11264
|
-
the Ruby object. */
|
|
11265
|
-
else if constexpr (!std::is_same_v<intrinsic_type<Receiver_T>, Class_T> &&
|
|
11266
|
-
std::is_base_of_v<intrinsic_type<Receiver_T>, Class_T> &&
|
|
11267
|
-
std::is_pointer_v<Receiver_T>)
|
|
11268
|
-
{
|
|
11269
|
-
Class_T* instance = From_Ruby<Class_T*>().convert(self);
|
|
11270
|
-
return dynamic_cast<Receiver_T>(instance);
|
|
11271
|
-
}
|
|
11272
|
-
else if constexpr (!std::is_same_v<intrinsic_type<Receiver_T>, Class_T> &&
|
|
11273
|
-
std::is_base_of_v<intrinsic_type<Receiver_T>, Class_T> &&
|
|
11274
|
-
std::is_reference_v<Receiver_T>)
|
|
11275
|
-
{
|
|
11276
|
-
Class_T& instance = From_Ruby<Class_T&>().convert(self);
|
|
11277
|
-
return dynamic_cast<Receiver_T>(instance);
|
|
11278
|
-
}
|
|
11279
|
-
// Self parameter could be derived from Object or it is an C++ instance and
|
|
11280
|
-
// needs to be unwrapped from Ruby
|
|
11281
11290
|
else
|
|
11282
11291
|
{
|
|
11283
|
-
|
|
11292
|
+
/* When a class wrapped by Rice calls a method defined on an ancestor class
|
|
11293
|
+
(e.g., std::map calling a method from _Tree), we need to unwrap as Class_T
|
|
11294
|
+
and dynamic_cast to the base class. Otherwise unwrap directly as Receiver_T. */
|
|
11295
|
+
constexpr bool isDerived = !std::is_same_v<intrinsic_type<Receiver_T>, Class_T> &&
|
|
11296
|
+
std::is_base_of_v<intrinsic_type<Receiver_T>, Class_T>;
|
|
11297
|
+
|
|
11298
|
+
if constexpr (isDerived)
|
|
11299
|
+
{
|
|
11300
|
+
if constexpr (std::is_pointer_v<Receiver_T>)
|
|
11301
|
+
{
|
|
11302
|
+
Class_T* instance = From_Ruby<Class_T*>().convert(self);
|
|
11303
|
+
return dynamic_cast<Receiver_T>(instance);
|
|
11304
|
+
}
|
|
11305
|
+
else if constexpr (std::is_reference_v<Receiver_T>)
|
|
11306
|
+
{
|
|
11307
|
+
Class_T& instance = From_Ruby<Class_T&>().convert(self);
|
|
11308
|
+
return dynamic_cast<Receiver_T>(instance);
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
else
|
|
11312
|
+
{
|
|
11313
|
+
// Note GCC has a false warning: function may return address of local variable [-Wreturn-local-addr].
|
|
11314
|
+
// From_Ruby returns a reference to data in the Ruby object, not the temporary.
|
|
11315
|
+
return From_Ruby<Receiver_T>().convert(self);
|
|
11316
|
+
}
|
|
11284
11317
|
}
|
|
11285
11318
|
}
|
|
11286
11319
|
|
|
@@ -14548,7 +14581,7 @@ namespace Rice
|
|
|
14548
14581
|
}
|
|
14549
14582
|
else
|
|
14550
14583
|
{
|
|
14551
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
14584
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
14552
14585
|
}
|
|
14553
14586
|
}
|
|
14554
14587
|
|