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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -1
  3. data/CMakePresets.json +77 -50
  4. data/FindRuby.cmake +1 -1
  5. data/bin/rice-doc.rb +2 -0
  6. data/include/rice/api.hpp +14 -1
  7. data/include/rice/rice.hpp +351 -132
  8. data/include/rice/stl.hpp +319 -256
  9. data/lib/rice/doc/config.rb +57 -57
  10. data/lib/rice/doc/cpp_reference.rb +158 -158
  11. data/lib/rice/doc/doxygen.rb +289 -289
  12. data/lib/rice/doc/mkdocs.rb +332 -332
  13. data/lib/rice/doc/rice.rb +48 -47
  14. data/lib/rice/doc/ruby.rb +26 -26
  15. data/lib/rice/native.rb +15 -15
  16. data/lib/rice/native_registry.rb +12 -17
  17. data/lib/rice/parameter.rb +5 -5
  18. data/lib/rice/rbs.rb +72 -72
  19. data/lib/rice/version.rb +1 -1
  20. data/lib/rubygems/builder.rb +9 -9
  21. data/lib/rubygems_plugin.rb +8 -8
  22. data/rice/Data_Type.ipp +12 -7
  23. data/rice/cpp_api/Class.hpp +5 -0
  24. data/rice/cpp_api/Class.ipp +5 -0
  25. data/rice/cpp_api/Object.hpp +6 -0
  26. data/rice/cpp_api/Object.ipp +5 -0
  27. data/rice/detail/Forwards.hpp +18 -0
  28. data/rice/detail/Forwards.ipp +60 -0
  29. data/rice/detail/Native.ipp +2 -4
  30. data/rice/detail/NativeAttributeGet.ipp +1 -1
  31. data/rice/detail/NativeAttributeSet.hpp +5 -3
  32. data/rice/detail/NativeAttributeSet.ipp +41 -33
  33. data/rice/detail/NativeMethod.ipp +25 -22
  34. data/rice/detail/NativeRegistry.hpp +4 -2
  35. data/rice/detail/NativeRegistry.ipp +42 -9
  36. data/rice/detail/Parameter.ipp +3 -4
  37. data/rice/detail/Type.ipp +4 -0
  38. data/rice/detail/Wrapper.hpp +17 -12
  39. data/rice/detail/Wrapper.ipp +95 -36
  40. data/rice/rice.hpp +3 -0
  41. data/rice/rice_api/NativeRegistry.ipp +14 -1
  42. data/rice/stl/exception.ipp +1 -1
  43. data/rice/stl/filesystem.ipp +1 -1
  44. data/rice/stl/map.ipp +13 -11
  45. data/rice/stl/multimap.ipp +13 -11
  46. data/rice/stl/pair.ipp +14 -8
  47. data/rice/stl/set.ipp +16 -16
  48. data/rice/stl/shared_ptr.hpp +16 -0
  49. data/rice/stl/shared_ptr.ipp +74 -37
  50. data/rice/stl/type_index.ipp +1 -1
  51. data/rice/stl/unique_ptr.hpp +9 -3
  52. data/rice/stl/unique_ptr.ipp +80 -124
  53. data/rice/stl/unordered_map.ipp +14 -12
  54. data/rice/stl/vector.ipp +67 -31
  55. data/test/test_Attribute.cpp +72 -0
  56. data/test/test_Callback.cpp +3 -0
  57. data/test/test_Inheritance.cpp +14 -14
  58. data/test/test_Keep_Alive_No_Wrapper.cpp +6 -2
  59. data/test/test_Stl_Map.cpp +46 -0
  60. data/test/test_Stl_Multimap.cpp +46 -0
  61. data/test/test_Stl_Set.cpp +34 -0
  62. data/test/test_Stl_SharedPtr.cpp +160 -45
  63. data/test/test_Stl_UniquePtr.cpp +48 -3
  64. data/test/test_Stl_Unordered_Map.cpp +46 -0
  65. data/test/test_Stl_Variant.cpp +10 -14
  66. data/test/test_Stl_Vector.cpp +140 -13
  67. data/test/test_Tracking.cpp +3 -0
  68. metadata +3 -1
@@ -7,6 +7,22 @@ namespace Rice
7
7
  Data_Type<std::shared_ptr<T>> define_shared_ptr(std::string klassName = "");
8
8
  }
9
9
 
10
+ namespace Rice::detail
11
+ {
12
+ template<typename T>
13
+ class Wrapper<std::shared_ptr<T>> : public WrapperBase
14
+ {
15
+ public:
16
+ Wrapper(rb_data_type_t* rb_data_type, const std::shared_ptr<T>& data);
17
+ ~Wrapper();
18
+ void* get(rb_data_type_t* requestedType) override;
19
+
20
+ private:
21
+ std::shared_ptr<T> data_;
22
+ rb_data_type_t* inner_rb_data_type_;
23
+ };
24
+ }
25
+
10
26
  #include "shared_ptr.ipp"
11
27
 
12
28
  #endif // Rice__stl__shared_ptr__hpp_
@@ -1,6 +1,5 @@
1
1
  #include <memory>
2
2
 
3
- // --------- Enable creation of std::shared_ptr from Ruby ---------
4
3
  namespace Rice
5
4
  {
6
5
  template<typename T>
@@ -22,74 +21,112 @@ namespace Rice
22
21
  }
23
22
 
24
23
  Identifier id(klassName);
25
- Data_Type_T result = define_class_under<SharedPtr_T>(rb_mStd, id);
24
+ Data_Type_T result = define_class_under<detail::intrinsic_type<SharedPtr_T>>(rb_mStd, id).
25
+ define_method("get", &SharedPtr_T::get).
26
+ define_method("swap", &SharedPtr_T::swap, Arg("r")).
27
+ define_method("use_count", &SharedPtr_T::use_count).
28
+ define_method("empty?", [](SharedPtr_T& self)->bool
29
+ {
30
+ return !self;
31
+ });
26
32
 
27
- // std::shared_ptr<void> cannot be constructed from void* because void is incomplete
28
- // and the deleter cannot be determined. So skip the constructor for void.
29
- // std::shared_ptr<T[]> (array types) also skip constructor - arrays need special handling.
30
- if constexpr (!std::is_void_v<T> && !std::is_array_v<T>)
33
+ if constexpr (!std::is_void_v<T>)
31
34
  {
32
35
  result.define_constructor(Constructor<SharedPtr_T, typename SharedPtr_T::element_type*>(), Arg("value").takeOwnership());
33
36
  }
34
37
 
35
- result.
36
- define_method("get", &SharedPtr_T::get).
37
- define_method("use_count", &SharedPtr_T::use_count).
38
- define_method("empty?", &SharedPtr_T::operator bool);
38
+ // Setup delegation to forward T's methods via get (only for non-fundamental, non-void types)
39
+ if constexpr (!std::is_void_v<T> && !std::is_fundamental_v<T>)
40
+ {
41
+ detail::define_forwarding(result.klass(), Data_Type<T>::klass());
42
+ }
39
43
 
40
44
  return result;
41
45
  }
42
46
  }
43
47
 
44
- // --------- Type/To_Ruby/From_Ruby ---------
48
+ // --------- Wrapper ---------
45
49
  namespace Rice::detail
46
50
  {
47
51
  template<typename T>
48
- struct Type<std::shared_ptr<T>>
52
+ Wrapper<std::shared_ptr<T>>::Wrapper(rb_data_type_t* rb_data_type, const std::shared_ptr<T>& data)
53
+ : WrapperBase(rb_data_type), data_(data)
49
54
  {
50
- static bool verify()
55
+ using Intrinsic_T = intrinsic_type<T>;
56
+
57
+ if constexpr (std::is_fundamental_v<Intrinsic_T>)
51
58
  {
52
- if constexpr (std::is_fundamental_v<T>)
53
- {
54
- Type<Pointer<T>>::verify();
55
- Type<Buffer<T>>::verify();
56
- }
57
- else
58
- {
59
- if (!Type<intrinsic_type<T>>::verify())
60
- {
61
- return false;
62
- }
63
- }
59
+ inner_rb_data_type_ = Data_Type<Pointer<Intrinsic_T>>::ruby_data_type();
60
+ }
61
+ else
62
+ {
63
+ inner_rb_data_type_ = Data_Type<Intrinsic_T>::ruby_data_type();
64
+ }
65
+ }
64
66
 
65
- define_shared_ptr<T>();
67
+ template<typename T>
68
+ Wrapper<std::shared_ptr<T>>::~Wrapper()
69
+ {
70
+ Registries::instance.instances.remove(this->get(this->rb_data_type_));
71
+ }
66
72
 
67
- return true;
73
+ template<typename T>
74
+ void* Wrapper<std::shared_ptr<T>>::get(rb_data_type_t* requestedType)
75
+ {
76
+ if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
77
+ {
78
+ return &this->data_;
68
79
  }
69
- };
80
+ else if (rb_typeddata_inherited_p(this->inner_rb_data_type_, requestedType))
81
+ {
82
+ return this->data_.get();
83
+ }
84
+ else
85
+ {
86
+ throw Exception(rb_eTypeError, "wrong argument type (expected %s)",
87
+ requestedType->wrap_struct_name);
88
+ }
89
+ }
90
+ }
70
91
 
71
- // Specialization for array types std::shared_ptr<T[]>
92
+ // --------- Type ---------
93
+ namespace Rice::detail
94
+ {
72
95
  template<typename T>
73
- struct Type<std::shared_ptr<T[]>>
96
+ struct Type<std::shared_ptr<T>>
74
97
  {
75
98
  static bool verify()
76
99
  {
100
+ bool result = true;
77
101
  if constexpr (std::is_fundamental_v<T>)
78
102
  {
79
- Type<Pointer<T>>::verify();
80
- Type<Buffer<T>>::verify();
103
+ result = result && Type<Pointer<T>>::verify();
81
104
  }
82
105
  else
83
106
  {
84
- if (!Type<intrinsic_type<T>>::verify())
85
- {
86
- return false;
87
- }
107
+ result = result && Type<T>::verify();
88
108
  }
89
109
 
90
- define_shared_ptr<T[]>();
110
+ if (result)
111
+ {
112
+ define_shared_ptr<T>();
113
+ }
91
114
 
115
+ return result;
116
+ }
117
+ };
118
+
119
+ #ifdef __GLIBCXX__
120
+ // libstdc++ implementation detail: std::shared_ptr inherits from
121
+ // std::__shared_ptr<T, _Lock_policy>. Methods like swap() expose this
122
+ // internal type through their parameter signatures.
123
+ template<typename T, __gnu_cxx::_Lock_policy Policy>
124
+ struct Type<std::__shared_ptr<T, Policy>>
125
+ {
126
+ static bool verify()
127
+ {
92
128
  return true;
93
129
  }
94
130
  };
131
+ #endif
95
132
  }
@@ -6,7 +6,7 @@ namespace Rice::stl
6
6
  {
7
7
  Module rb_mStd = define_module("Std");
8
8
  return define_class_under<std::type_index>(rb_mStd, "TypeIndex").
9
- define_constructor(Constructor<std::type_index, const std::type_info&>()).
9
+ define_constructor(Constructor<std::type_index, const std::type_info&>(), Arg("target")).
10
10
  define_method("hash_code", &std::type_index::hash_code).
11
11
  define_method("name", &std::type_index::name);
12
12
  }
@@ -1,19 +1,25 @@
1
1
  #ifndef Rice__stl__unique_ptr__hpp_
2
2
  #define Rice__stl__unique_ptr__hpp_
3
3
 
4
+ namespace Rice
5
+ {
6
+ template<typename T>
7
+ Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName = "");
8
+ }
9
+
4
10
  namespace Rice::detail
5
11
  {
6
12
  template<typename T>
7
13
  class Wrapper<std::unique_ptr<T>> : public WrapperBase
8
14
  {
9
15
  public:
10
- Wrapper(std::unique_ptr<T>&& data);
16
+ Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data);
11
17
  ~Wrapper();
12
- void* get() override;
13
- std::unique_ptr<T>& data();
18
+ void* get(rb_data_type_t* requestedType) override;
14
19
 
15
20
  private:
16
21
  std::unique_ptr<T> data_;
22
+ rb_data_type_t* inner_rb_data_type_;
17
23
  };
18
24
  }
19
25
 
@@ -1,135 +1,123 @@
1
1
  #include <memory>
2
2
 
3
- namespace Rice::detail
3
+ namespace Rice
4
4
  {
5
5
  template<typename T>
6
- inline Wrapper<std::unique_ptr<T>>::Wrapper(std::unique_ptr<T>&& data)
7
- : data_(std::move(data))
8
- {
9
- }
10
-
11
- template<typename T>
12
- inline Wrapper<std::unique_ptr<T>>::~Wrapper()
13
- {
14
- Registries::instance.instances.remove(this->get());
15
- }
16
-
17
- template<typename T>
18
- inline void* Wrapper<std::unique_ptr<T>>::get()
19
- {
20
- return (void*)this->data_.get();
21
- }
22
-
23
- template<typename T>
24
- inline std::unique_ptr<T>& Wrapper<std::unique_ptr<T>>::data()
6
+ Data_Type<std::unique_ptr<T>> define_unique_ptr(std::string klassName)
25
7
  {
26
- return data_;
27
- }
8
+ using UniquePtr_T = std::unique_ptr<T>;
9
+ using Data_Type_T = Data_Type<UniquePtr_T>;
28
10
 
29
- template <typename T>
30
- class To_Ruby<std::unique_ptr<T>>
31
- {
32
- public:
33
- To_Ruby() = default;
34
-
35
- explicit To_Ruby(Arg* arg) : arg_(arg)
11
+ if (klassName.empty())
36
12
  {
13
+ detail::TypeMapper<UniquePtr_T> typeMapper;
14
+ klassName = typeMapper.rubyName();
37
15
  }
38
16
 
39
- VALUE convert(std::unique_ptr<T>& data)
17
+ Module rb_mStd = define_module("Std");
18
+ if (Data_Type_T::check_defined(klassName, rb_mStd))
40
19
  {
41
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
42
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
20
+ return Data_Type_T();
43
21
  }
44
22
 
45
- VALUE convert(std::unique_ptr<T>&& data)
23
+ Identifier id(klassName);
24
+ Data_Type_T result = define_class_under<detail::intrinsic_type<UniquePtr_T>>(rb_mStd, id).
25
+ define_method("get", &UniquePtr_T::get).
26
+ define_method("release", &UniquePtr_T::release).
27
+ define_method("reset", &UniquePtr_T::reset, Arg("ptr")).
28
+ define_method("swap", &UniquePtr_T::swap, Arg("other")).
29
+ define_method("empty?", [](UniquePtr_T& self)->bool
30
+ {
31
+ return !self;
32
+ });
33
+
34
+ // Setup delegation to forward T's methods via get (only for non-fundamental, non-void types)
35
+ if constexpr (!std::is_void_v<T> && !std::is_fundamental_v<T>)
46
36
  {
47
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
48
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
37
+ detail::define_forwarding(result.klass(), Data_Type<T>::klass());
49
38
  }
50
39
 
51
- private:
52
- Arg* arg_ = nullptr;
53
- };
40
+ return result;
41
+ }
42
+ }
54
43
 
55
- template <typename T>
56
- class To_Ruby<std::unique_ptr<T>&>
44
+ // --------- Wrapper ---------
45
+ namespace Rice::detail
46
+ {
47
+ template<typename T>
48
+ Wrapper<std::unique_ptr<T>>::Wrapper(rb_data_type_t* rb_data_type, std::unique_ptr<T>&& data)
49
+ : WrapperBase(rb_data_type), data_(std::move(data))
57
50
  {
58
- public:
59
- To_Ruby() = default;
51
+ using Intrinsic_T = intrinsic_type<T>;
60
52
 
61
- explicit To_Ruby(Arg* arg) : arg_(arg)
53
+ if constexpr (std::is_fundamental_v<Intrinsic_T>)
62
54
  {
55
+ inner_rb_data_type_ = Data_Type<Pointer<Intrinsic_T>>::ruby_data_type();
63
56
  }
64
-
65
- VALUE convert(std::unique_ptr<T>& data)
57
+ else
66
58
  {
67
- std::pair<VALUE, rb_data_type_t*> rubyTypeInfo = detail::Registries::instance.types.figureType<T>(*data);
68
- return detail::wrap<std::unique_ptr<T>>(rubyTypeInfo.first, rubyTypeInfo.second, data, true);
59
+ inner_rb_data_type_ = Data_Type<Intrinsic_T>::ruby_data_type();
69
60
  }
61
+ }
70
62
 
71
- private:
72
- Arg* arg_ = nullptr;
73
- };
63
+ template<typename T>
64
+ Wrapper<std::unique_ptr<T>>::~Wrapper()
65
+ {
66
+ Registries::instance.instances.remove(this->get(this->rb_data_type_));
67
+ }
74
68
 
75
- template <typename T>
76
- class From_Ruby<std::unique_ptr<T>>
69
+ template<typename T>
70
+ void* Wrapper<std::unique_ptr<T>>::get(rb_data_type_t* requestedType)
77
71
  {
78
- public:
79
- Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
72
+ if (rb_typeddata_inherited_p(this->rb_data_type_, requestedType))
80
73
  {
81
- WrapperBase* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
82
- return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
74
+ return &this->data_;
83
75
  }
84
-
85
- From_Ruby() = default;
86
-
87
- explicit From_Ruby(Arg* arg) : arg_(arg)
76
+ else if (rb_typeddata_inherited_p(this->inner_rb_data_type_, requestedType))
77
+ {
78
+ return this->data_.get();
79
+ }
80
+ else
88
81
  {
82
+ throw Exception(rb_eTypeError, "wrong argument type (expected %s)",
83
+ requestedType->wrap_struct_name);
89
84
  }
85
+ }
90
86
 
91
- double is_convertible(VALUE value)
87
+ }
88
+
89
+ // --------- Type ---------
90
+ namespace Rice::detail
91
+ {
92
+ template<typename T>
93
+ struct Type<std::unique_ptr<T>>
94
+ {
95
+ static bool verify()
92
96
  {
93
- if (!is_same_smart_ptr(value))
97
+ bool result = true;
98
+ if constexpr (std::is_fundamental_v<T>)
94
99
  {
95
- return Convertible::None;
100
+ result = result && Type<Pointer<T>>::verify();
96
101
  }
97
-
98
- switch (rb_type(value))
102
+ else
99
103
  {
100
- case RUBY_T_DATA:
101
- return Convertible::Exact;
102
- break;
103
- default:
104
- return Convertible::None;
104
+ result = result && Type<T>::verify();
105
105
  }
106
- }
107
106
 
108
- std::unique_ptr<T> convert(VALUE value)
109
- {
110
- Wrapper<std::unique_ptr<T>>* wrapper = is_same_smart_ptr(value);
111
- if (!wrapper)
107
+ if (result)
112
108
  {
113
- std::string message = "Invalid smart pointer wrapper";
114
- throw std::runtime_error(message.c_str());
109
+ define_unique_ptr<T>();
115
110
  }
116
- return std::move(wrapper->data());
117
- }
118
111
 
119
- private:
120
- Arg* arg_ = nullptr;
112
+ return result;
113
+ }
121
114
  };
122
115
 
116
+ // --------- From_Ruby ---------
123
117
  template <typename T>
124
- class From_Ruby<std::unique_ptr<T>&>
118
+ class From_Ruby<std::unique_ptr<T>>
125
119
  {
126
120
  public:
127
- Wrapper<std::unique_ptr<T>>* is_same_smart_ptr(VALUE value)
128
- {
129
- WrapperBase* wrapper = detail::getWrapper(value, Data_Type<T>::ruby_data_type());
130
- return dynamic_cast<Wrapper<std::unique_ptr<T>>*>(wrapper);
131
- }
132
-
133
121
  From_Ruby() = default;
134
122
 
135
123
  explicit From_Ruby(Arg* arg) : arg_(arg)
@@ -138,11 +126,6 @@ namespace Rice::detail
138
126
 
139
127
  double is_convertible(VALUE value)
140
128
  {
141
- if (!is_same_smart_ptr(value))
142
- {
143
- return Convertible::None;
144
- }
145
-
146
129
  switch (rb_type(value))
147
130
  {
148
131
  case RUBY_T_DATA:
@@ -153,41 +136,14 @@ namespace Rice::detail
153
136
  }
154
137
  }
155
138
 
156
- std::unique_ptr<T>& convert(VALUE value)
139
+ std::unique_ptr<T> convert(VALUE value)
157
140
  {
158
- Wrapper<std::unique_ptr<T>>* wrapper = is_same_smart_ptr(value);
159
- if (!wrapper)
160
- {
161
- std::string message = "Invalid smart pointer wrapper";
162
- throw std::runtime_error(message.c_str());
163
- }
164
- return wrapper->data();
141
+ std::unique_ptr<T>* result = detail::unwrap<std::unique_ptr<T>>(value, Data_Type<std::unique_ptr<T>>::ruby_data_type(), this->arg_ && this->arg_->isOwner());
142
+ // The reason we need this overriden From_Ruby is to do this std::move.
143
+ return std::move(*result);
165
144
  }
166
145
 
167
146
  private:
168
147
  Arg* arg_ = nullptr;
169
148
  };
170
-
171
- template<typename T>
172
- struct Type<std::unique_ptr<T>>
173
- {
174
- static bool verify()
175
- {
176
- if constexpr (std::is_fundamental_v<T>)
177
- {
178
- return Type<Pointer<T>>::verify();
179
- return Type<Buffer<T>>::verify();
180
- }
181
- else
182
- {
183
- return Type<T>::verify();
184
- }
185
- }
186
-
187
- static VALUE rubyKlass()
188
- {
189
- TypeMapper<T> typeMapper;
190
- return typeMapper.rubyKlass();
191
- }
192
- };
193
149
  }
@@ -14,6 +14,8 @@ namespace Rice
14
14
  using Size_T = typename T::size_type;
15
15
  using Difference_T = typename T::difference_type;
16
16
  using To_Ruby_T = typename detail::remove_cv_recursive_t<Mapped_T>;
17
+ // For pointer types, use the pointer directly; for non-pointer types, use a reference
18
+ using Mapped_Parameter_T = std::conditional_t<std::is_pointer_v<Mapped_T>, Mapped_T, Mapped_T&>;
17
19
 
18
20
  public:
19
21
  UnorderedMapHelper(Data_Type<T> klass) : klass_(klass)
@@ -33,7 +35,7 @@ namespace Rice
33
35
 
34
36
  void register_pair()
35
37
  {
36
- define_pair<const Key_T, T>();
38
+ define_pair<const Key_T, Mapped_T>();
37
39
  }
38
40
 
39
41
  void define_constructors()
@@ -42,7 +44,7 @@ namespace Rice
42
44
 
43
45
  if constexpr (std::is_copy_constructible_v<Key_T> && std::is_copy_constructible_v<Value_T>)
44
46
  {
45
- klass_.define_constructor(Constructor<T, const T&>());
47
+ klass_.define_constructor(Constructor<T, const T&>(), Arg("other"));
46
48
  }
47
49
  }
48
50
 
@@ -71,11 +73,11 @@ namespace Rice
71
73
  {
72
74
  return std::nullopt;
73
75
  }
74
- })
76
+ }, Arg("key"))
75
77
  .define_method("include?", [](T& unordered_map, Key_T& key) -> bool
76
78
  {
77
79
  return unordered_map.find(key) != unordered_map.end();
78
- })
80
+ }, Arg("key"))
79
81
  .define_method("keys", [](T& unordered_map) -> std::vector<Key_T>
80
82
  {
81
83
  std::vector<Key_T> result;
@@ -110,8 +112,8 @@ namespace Rice
110
112
  klass_.define_method("==", [](T& unordered_map, T& other)->bool
111
113
  {
112
114
  return unordered_map == other;
113
- })
114
- .define_method("value?", [](T& unordered_map, Mapped_T& value) -> bool
115
+ }, Arg("other"))
116
+ .define_method("value?", [](T& unordered_map, Mapped_Parameter_T value) -> bool
115
117
  {
116
118
  auto it = std::find_if(unordered_map.begin(), unordered_map.end(),
117
119
  [&value](auto& pair)
@@ -120,15 +122,15 @@ namespace Rice
120
122
  });
121
123
 
122
124
  return it != unordered_map.end();
123
- });
125
+ }, Arg("value"));
124
126
  rb_define_alias(klass_, "eql?", "==");
125
127
  }
126
128
  else
127
129
  {
128
- klass_.define_method("value?", [](T&, Mapped_T&) -> bool
130
+ klass_.define_method("value?", [](T&, Mapped_Parameter_T) -> bool
129
131
  {
130
132
  return false;
131
- });
133
+ }, Arg("value"));
132
134
  }
133
135
 
134
136
  rb_define_alias(klass_, "has_value", "value?");
@@ -151,12 +153,12 @@ namespace Rice
151
153
  {
152
154
  return std::nullopt;
153
155
  }
154
- })
155
- .define_method("[]=", [](T& unordered_map, Key_T key, Mapped_T& value) -> Mapped_T
156
+ }, Arg("key"))
157
+ .define_method("[]=", [](T& unordered_map, Key_T key, Mapped_Parameter_T value) -> Mapped_T
156
158
  {
157
159
  unordered_map[key] = value;
158
160
  return value;
159
- });
161
+ }, Arg("key").keepAlive(), Arg("value").keepAlive());
160
162
 
161
163
  rb_define_alias(klass_, "store", "[]=");
162
164
  }