rice 4.5.0 → 4.6.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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/CMakeLists.txt +31 -0
  4. data/CMakePresets.json +75 -0
  5. data/COPYING +3 -2
  6. data/FindRuby.cmake +437 -0
  7. data/Rakefile +5 -4
  8. data/include/rice/rice.hpp +5436 -3201
  9. data/include/rice/stl.hpp +2355 -1269
  10. data/lib/make_rice_headers.rb +79 -0
  11. data/lib/mkmf-rice.rb +4 -0
  12. data/lib/rice/version.rb +3 -0
  13. data/lib/rice.rb +1 -0
  14. data/lib/rubygems/builder.rb +11 -0
  15. data/lib/rubygems/cmake_builder.rb +113 -0
  16. data/lib/rubygems_plugin.rb +9 -0
  17. data/rice/Arg.hpp +7 -1
  18. data/rice/Arg.ipp +11 -2
  19. data/rice/Buffer.hpp +123 -0
  20. data/rice/Buffer.ipp +599 -0
  21. data/rice/Constructor.ipp +3 -3
  22. data/rice/Data_Object.hpp +2 -3
  23. data/rice/Data_Object.ipp +188 -188
  24. data/rice/Data_Type.hpp +4 -5
  25. data/rice/Data_Type.ipp +42 -26
  26. data/rice/Enum.hpp +0 -1
  27. data/rice/Enum.ipp +26 -23
  28. data/rice/Init.hpp +8 -0
  29. data/rice/Init.ipp +8 -0
  30. data/rice/MemoryView.ipp +1 -41
  31. data/rice/Return.hpp +1 -1
  32. data/rice/Return.ipp +6 -0
  33. data/rice/cpp_api/Array.hpp +209 -0
  34. data/rice/cpp_api/Array.ipp +304 -0
  35. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  36. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  37. data/rice/cpp_api/Class.hpp +70 -0
  38. data/rice/cpp_api/Class.ipp +97 -0
  39. data/rice/cpp_api/Encoding.hpp +32 -0
  40. data/rice/cpp_api/Encoding.ipp +59 -0
  41. data/rice/cpp_api/Hash.hpp +194 -0
  42. data/rice/cpp_api/Hash.ipp +257 -0
  43. data/rice/cpp_api/Identifier.hpp +46 -0
  44. data/rice/cpp_api/Identifier.ipp +31 -0
  45. data/rice/cpp_api/Module.hpp +72 -0
  46. data/rice/cpp_api/Module.ipp +101 -0
  47. data/rice/cpp_api/Object.hpp +272 -0
  48. data/rice/cpp_api/Object.ipp +235 -0
  49. data/rice/cpp_api/String.hpp +74 -0
  50. data/rice/cpp_api/String.ipp +120 -0
  51. data/rice/cpp_api/Struct.hpp +113 -0
  52. data/rice/cpp_api/Struct.ipp +92 -0
  53. data/rice/cpp_api/Symbol.hpp +46 -0
  54. data/rice/cpp_api/Symbol.ipp +93 -0
  55. data/rice/cpp_api/shared_methods.hpp +134 -0
  56. data/rice/detail/MethodInfo.hpp +1 -9
  57. data/rice/detail/MethodInfo.ipp +5 -72
  58. data/rice/detail/Native.hpp +3 -2
  59. data/rice/detail/Native.ipp +32 -4
  60. data/rice/detail/NativeAttributeGet.hpp +3 -2
  61. data/rice/detail/NativeAttributeGet.ipp +8 -2
  62. data/rice/detail/NativeAttributeSet.hpp +3 -2
  63. data/rice/detail/NativeAttributeSet.ipp +8 -2
  64. data/rice/detail/NativeCallbackFFI.ipp +1 -1
  65. data/rice/detail/NativeFunction.hpp +17 -6
  66. data/rice/detail/NativeFunction.ipp +168 -64
  67. data/rice/detail/NativeIterator.hpp +3 -2
  68. data/rice/detail/NativeIterator.ipp +8 -2
  69. data/rice/detail/RubyType.hpp +2 -5
  70. data/rice/detail/RubyType.ipp +50 -5
  71. data/rice/detail/Type.hpp +3 -1
  72. data/rice/detail/Type.ipp +61 -31
  73. data/rice/detail/Wrapper.hpp +68 -33
  74. data/rice/detail/Wrapper.ipp +103 -113
  75. data/rice/detail/from_ruby.hpp +5 -4
  76. data/rice/detail/from_ruby.ipp +737 -365
  77. data/rice/detail/to_ruby.ipp +1092 -186
  78. data/rice/global_function.ipp +1 -1
  79. data/rice/libc/file.hpp +11 -0
  80. data/rice/libc/file.ipp +32 -0
  81. data/rice/rice.hpp +23 -16
  82. data/rice/stl/complex.hpp +6 -0
  83. data/rice/stl/complex.ipp +93 -0
  84. data/rice/stl/exception.hpp +11 -0
  85. data/rice/stl/exception.ipp +29 -0
  86. data/rice/stl/exception_ptr.hpp +6 -0
  87. data/rice/stl/exception_ptr.ipp +27 -0
  88. data/rice/stl/map.hpp +12 -0
  89. data/rice/stl/map.ipp +469 -0
  90. data/rice/stl/monostate.hpp +6 -0
  91. data/rice/stl/monostate.ipp +80 -0
  92. data/rice/stl/multimap.hpp +14 -0
  93. data/rice/stl/multimap.ipp +448 -0
  94. data/rice/stl/optional.hpp +6 -0
  95. data/rice/stl/optional.ipp +118 -0
  96. data/rice/stl/pair.hpp +13 -0
  97. data/rice/stl/pair.ipp +155 -0
  98. data/rice/stl/reference_wrapper.hpp +6 -0
  99. data/rice/stl/reference_wrapper.ipp +41 -0
  100. data/rice/stl/set.hpp +12 -0
  101. data/rice/stl/set.ipp +495 -0
  102. data/rice/stl/shared_ptr.hpp +28 -0
  103. data/rice/stl/shared_ptr.ipp +224 -0
  104. data/rice/stl/string.hpp +6 -0
  105. data/rice/stl/string.ipp +158 -0
  106. data/rice/stl/string_view.hpp +6 -0
  107. data/rice/stl/string_view.ipp +65 -0
  108. data/rice/stl/tuple.hpp +6 -0
  109. data/rice/stl/tuple.ipp +128 -0
  110. data/rice/stl/type_index.hpp +6 -0
  111. data/rice/stl/type_index.ipp +30 -0
  112. data/rice/stl/type_info.hpp +6 -0
  113. data/rice/stl/type_info.ipp +29 -0
  114. data/rice/stl/unique_ptr.hpp +22 -0
  115. data/rice/stl/unique_ptr.ipp +139 -0
  116. data/rice/stl/unordered_map.hpp +12 -0
  117. data/rice/stl/unordered_map.ipp +469 -0
  118. data/rice/stl/variant.hpp +6 -0
  119. data/rice/stl/variant.ipp +242 -0
  120. data/rice/stl/vector.hpp +12 -0
  121. data/rice/stl/vector.ipp +590 -0
  122. data/rice/stl.hpp +7 -3
  123. data/rice/traits/attribute_traits.hpp +26 -0
  124. data/rice/traits/function_traits.hpp +95 -0
  125. data/rice/traits/method_traits.hpp +47 -0
  126. data/rice/traits/rice_traits.hpp +160 -0
  127. data/rice.gemspec +85 -0
  128. data/test/embed_ruby.cpp +3 -0
  129. data/test/ruby/test_multiple_extensions_same_class.rb +14 -14
  130. data/test/test_Array.cpp +6 -3
  131. data/test/test_Attribute.cpp +34 -1
  132. data/test/test_Buffer.cpp +285 -0
  133. data/test/test_Callback.cpp +2 -3
  134. data/test/test_Data_Object.cpp +88 -34
  135. data/test/test_Data_Type.cpp +106 -65
  136. data/test/test_Director.cpp +7 -3
  137. data/test/test_Enum.cpp +5 -2
  138. data/test/test_File.cpp +1 -1
  139. data/test/test_From_Ruby.cpp +181 -114
  140. data/test/test_Iterator.cpp +1 -1
  141. data/test/{test_JumpException.cpp → test_Jump_Exception.cpp} +1 -0
  142. data/test/test_Keep_Alive.cpp +7 -18
  143. data/test/test_Keep_Alive_No_Wrapper.cpp +0 -1
  144. data/test/test_Module.cpp +13 -6
  145. data/test/test_Native_Registry.cpp +0 -1
  146. data/test/test_Overloads.cpp +180 -5
  147. data/test/test_Ownership.cpp +100 -57
  148. data/test/test_Proc.cpp +0 -1
  149. data/test/test_Self.cpp +4 -4
  150. data/test/test_Stl_Map.cpp +37 -39
  151. data/test/test_Stl_Multimap.cpp +693 -0
  152. data/test/test_Stl_Pair.cpp +8 -8
  153. data/test/test_Stl_Reference_Wrapper.cpp +4 -2
  154. data/test/test_Stl_Set.cpp +790 -0
  155. data/test/{test_Stl_SmartPointer.cpp → test_Stl_SharedPtr.cpp} +97 -127
  156. data/test/test_Stl_Tuple.cpp +116 -0
  157. data/test/test_Stl_Type.cpp +1 -1
  158. data/test/test_Stl_UniquePtr.cpp +202 -0
  159. data/test/test_Stl_Unordered_Map.cpp +28 -34
  160. data/test/test_Stl_Variant.cpp +217 -89
  161. data/test/test_Stl_Vector.cpp +209 -83
  162. data/test/test_To_Ruby.cpp +373 -1
  163. data/test/test_Type.cpp +85 -14
  164. data/test/test_global_functions.cpp +17 -4
  165. metadata +94 -10
  166. data/rice/detail/TupleIterator.hpp +0 -14
@@ -0,0 +1,194 @@
1
+ #ifndef Rice__Hash__hpp_
2
+ #define Rice__Hash__hpp_
3
+
4
+ #include <iterator>
5
+ #include <type_traits>
6
+
7
+ namespace Rice
8
+ {
9
+ //! A wrapper for the ruby Hash class.
10
+ //! This class provides a C++-style interface to ruby's Hash class and
11
+ //! its associated rb_hash_* functions.
12
+ //! Example:
13
+ //! \code
14
+ //! Hash h;
15
+ //! h[42] = String("foo");
16
+ //! h[10] = String("bar");
17
+ //! std::cout << String(h[42]) << std::endl;
18
+ //! \endcode
19
+ class Hash: public Builtin_Object<T_HASH>
20
+ {
21
+ public:
22
+ //! Construct a new hash.
23
+ Hash();
24
+
25
+ //! Wrap an existing hash.
26
+ /*! \param v the hash to wrap.
27
+ */
28
+ Hash(Object v);
29
+
30
+ //! Return the number of elements in the hash.
31
+ size_t size() const;
32
+
33
+ private:
34
+ //! A helper class so hash[key]=value can work.
35
+ class Proxy;
36
+
37
+ public:
38
+ //! Get the value for the given key.
39
+ /*! \param key the key whose value should be retrieved from the hash.
40
+ * \return the value associated with the given key.
41
+ */
42
+ template<typename Key_T>
43
+ Proxy const operator[](Key_T const& key) const;
44
+
45
+ //! Get the value for the given key.
46
+ /*! \param key the key whose value should be retrieved from the hash.
47
+ * \return the value associated with the given key.
48
+ */
49
+ template<typename Key_T>
50
+ Proxy operator[](Key_T const& key);
51
+
52
+ //! Get the value for the given key
53
+ /*! The returned value is converted to the type given by Value_T.
54
+ * \param key the key whose value should be retrieved from the hash.
55
+ * \return the value associated with the given key, converted to C++
56
+ * type Value_T.
57
+ */
58
+ template<typename Value_T, typename Key_T>
59
+ Value_T get(Key_T const& key);
60
+
61
+ //! A helper class for dereferencing iterators
62
+ class Entry;
63
+
64
+ //! A helper class for implementing iterators for a Hash.
65
+ template<typename Hash_Ptr_T, typename Value_T>
66
+ class Iterator;
67
+
68
+ public:
69
+ //! An iterator.
70
+ typedef Iterator<Hash*, Entry> iterator;
71
+
72
+ //! A const iterator.
73
+ typedef Iterator<Hash const*, Entry const> const_iterator;
74
+
75
+ public:
76
+ //! Return an iterator to the beginning of the hash.
77
+ iterator begin();
78
+
79
+ //! Return a const iterator to the beginning of the hash.
80
+ const_iterator begin() const;
81
+
82
+ //! Return an iterator to the end of the hash.
83
+ iterator end();
84
+
85
+ //! Return a const to the end of the hash.
86
+ const_iterator end() const;
87
+ };
88
+
89
+ //! A helper class so hash[key]=value can work.
90
+ class Hash::Proxy
91
+ {
92
+ public:
93
+ //! Construct a new Proxy.
94
+ Proxy(Hash* hash, Object key);
95
+
96
+ //! Implicit conversion to Object.
97
+ operator Object() const;
98
+
99
+ //! Explicit conversion to VALUE.
100
+ VALUE value() const;
101
+
102
+ //! Assignment operator.
103
+ template<typename T>
104
+ Object operator=(T const& value);
105
+
106
+ private:
107
+ Hash* hash_;
108
+ Object key_;
109
+ };
110
+
111
+ //! A helper class for dereferencing iterators
112
+ /*! This class is intended to look similar to an std::pair.
113
+ */
114
+ class Hash::Entry
115
+ {
116
+ public:
117
+ //! Construct a new Entry.
118
+ Entry(Hash* hash, Object key);
119
+
120
+ //! Copy constructor.
121
+ Entry(Entry const& entry);
122
+
123
+ Object const key; //!< The key
124
+ Object const& first; //!< An alias for the key
125
+
126
+ Proxy value; //!< The value
127
+ Proxy& second; //!< An alias for the value
128
+
129
+ Entry& operator=(Entry const& rhs);
130
+
131
+ friend bool operator<(Entry const& lhs, Entry const& rhs);
132
+ };
133
+
134
+ bool operator<(Hash::Entry const& lhs, Hash::Entry const& rhs);
135
+
136
+ //! A helper class for implementing iterators for a Hash.
137
+ template<typename Hash_Ptr_T, typename Value_T>
138
+ class Hash::Iterator
139
+ {
140
+ public:
141
+ using iterator_category = std::input_iterator_tag;
142
+ using value_type = Value_T;
143
+ using difference_type = long;
144
+ using pointer = Object*;
145
+ using reference = Value_T&;
146
+
147
+ //! Construct a new Iterator.
148
+ Iterator(Hash_Ptr_T hash);
149
+
150
+ //! Construct a new Iterator with a given start-at index point
151
+ Iterator(Hash_Ptr_T hash, int start_at);
152
+
153
+ //! Construct an Iterator from another Iterator of a different const
154
+ //! qualification.
155
+ template<typename Iterator_T>
156
+ Iterator(Iterator_T const& iterator);
157
+
158
+ //! Preincrement operator.
159
+ Iterator& operator++();
160
+
161
+ //! Postincrement operator.
162
+ Iterator operator++(int);
163
+
164
+ //! Dereference operator.
165
+ Value_T operator*();
166
+
167
+ //! Dereference operator.
168
+ Value_T* operator->();
169
+
170
+ //! Equality operator.
171
+ bool operator==(Iterator const& rhs) const;
172
+
173
+ //! Inequality operator.
174
+ bool operator!=(Iterator const& rhs) const;
175
+
176
+ template<typename Hash_Ptr_T_, typename Value_T_>
177
+ friend class Hash::Iterator;
178
+
179
+ protected:
180
+ Object current_key();
181
+
182
+ Array hash_keys();
183
+
184
+ private:
185
+ Hash_Ptr_T hash_;
186
+ long current_index_;
187
+ VALUE keys_;
188
+
189
+ mutable typename std::remove_const<Value_T>::type tmp_;
190
+ };
191
+ } // namespace Rice
192
+
193
+ #endif // Rice__Hash__hpp_
194
+
@@ -0,0 +1,257 @@
1
+ #include <algorithm>
2
+
3
+ namespace Rice
4
+ {
5
+ inline Hash::Hash() : Builtin_Object<T_HASH>(detail::protect(rb_hash_new))
6
+ {
7
+ }
8
+
9
+ inline Hash::Hash(Object v) : Builtin_Object<T_HASH>(v)
10
+ {
11
+ }
12
+
13
+ inline size_t Hash::size() const
14
+ {
15
+ return RHASH_SIZE(this->value());
16
+ }
17
+
18
+ inline Hash::Proxy::Proxy(Hash* hash, Object key) : hash_(hash), key_(key)
19
+ {
20
+ }
21
+
22
+ inline Hash::Proxy::operator Object() const
23
+ {
24
+ return value();
25
+ }
26
+
27
+ inline VALUE Hash::Proxy::value() const
28
+ {
29
+ return detail::protect(rb_hash_aref, hash_->value(), key_.value());
30
+ }
31
+
32
+ template<typename T>
33
+ inline Object Hash::Proxy::operator=(T const& value)
34
+ {
35
+ return detail::protect(rb_hash_aset, hash_->value(), key_.value(), detail::To_Ruby<T>().convert(value));
36
+ }
37
+
38
+ template<typename Key_T>
39
+ inline Hash::Proxy const Hash::operator[](Key_T const& key) const
40
+ {
41
+ return Proxy(*this, detail::To_Ruby<Key_T>().convert(key));
42
+ }
43
+
44
+ template<typename Key_T>
45
+ inline Hash::Proxy Hash::operator[](Key_T const& key)
46
+ {
47
+ return Proxy(this, detail::To_Ruby<Key_T>().convert(key));
48
+ }
49
+
50
+ template<typename Value_T, typename Key_T>
51
+ inline Value_T Hash::get(Key_T const& key)
52
+ {
53
+ Object ruby_key(detail::To_Ruby<Key_T>().convert(key));
54
+ Object value = operator[](ruby_key);
55
+ try
56
+ {
57
+ return detail::From_Ruby<Value_T>().convert(value);
58
+ }
59
+ catch (Exception const& ex)
60
+ {
61
+ String s_key(ruby_key.to_s());
62
+ throw Exception(
63
+ ex,
64
+ "%s while converting value for key %s",
65
+ ex.what(),
66
+ s_key.c_str());
67
+ }
68
+ }
69
+
70
+ inline Hash::Entry::Entry(Hash* hash, Object key) :
71
+ key(key), first(Hash::Entry::key), value(hash, key), second(Hash::Entry::value)
72
+ {
73
+ }
74
+
75
+ inline Hash::Entry::Entry(Entry const& entry) :
76
+ key(entry.key), first(Hash::Entry::key), value(entry.value), second(Hash::Entry::value)
77
+ {
78
+ }
79
+
80
+ inline Hash::Entry& Hash::Entry::operator=(Hash::Entry const& other)
81
+ {
82
+ const_cast<Object&>(key) = const_cast<Object&>(other.key);
83
+
84
+ this->value = other.value;
85
+ this->second = this->value;
86
+
87
+ return *this;
88
+ }
89
+
90
+ template<typename Hash_Ptr_T, typename Value_T>
91
+ inline Hash::Iterator<Hash_Ptr_T, Value_T>::Iterator(Hash_Ptr_T hash)
92
+ : hash_(hash), current_index_(0), keys_(Qnil), tmp_(const_cast<Hash*>(hash), Qnil)
93
+ {
94
+ }
95
+
96
+ template<typename Hash_Ptr_T, typename Value_T>
97
+ inline Hash::Iterator<Hash_Ptr_T, Value_T>::Iterator(Hash_Ptr_T hash, int start_at)
98
+ : hash_(hash), current_index_(start_at), keys_(Qnil), tmp_(const_cast<Hash*>(hash), Qnil)
99
+ {
100
+ }
101
+
102
+ template<typename Hash_Ptr_T, typename Value_T>
103
+ template<typename Iterator_T>
104
+ inline Hash::Iterator<Hash_Ptr_T, Value_T>::Iterator(Iterator_T const& iterator) :
105
+ hash_(iterator.hash_), current_index_(iterator.current_index_), keys_(Qnil), tmp_(iterator.hash_, Qnil)
106
+ {
107
+ }
108
+
109
+ template<typename Hash_Ptr_T, typename Value_T>
110
+ inline Hash::Iterator<Hash_Ptr_T, Value_T>& Hash::Iterator<Hash_Ptr_T, Value_T>::operator++()
111
+ {
112
+ // Ensure we're within the range
113
+ if (current_index_ < hash_keys().size())
114
+ {
115
+ current_index_++;
116
+ }
117
+
118
+ return *this;
119
+ }
120
+
121
+ template<typename Hash_Ptr_T, typename Value_T>
122
+ inline Hash::Iterator<Hash_Ptr_T, Value_T> Hash::Iterator<Hash_Ptr_T, Value_T>::operator++(int)
123
+ {
124
+ Iterator copy(*this);
125
+ ++(*this);
126
+ return copy;
127
+ }
128
+
129
+ template<typename Hash_Ptr_T, typename Value_T>
130
+ inline Value_T Hash::Iterator<Hash_Ptr_T, Value_T>::operator*()
131
+ {
132
+ return Value_T(const_cast<Hash*>(hash_), current_key());
133
+ }
134
+
135
+ template<typename Hash_Ptr_T, typename Value_T>
136
+ inline Value_T* Hash::Iterator<Hash_Ptr_T, Value_T>::operator->()
137
+ {
138
+ this->tmp_ = Entry(const_cast<Hash*>(hash_), current_key());
139
+ return &tmp_;
140
+ }
141
+
142
+ template<typename Hash_Ptr_T, typename Value_T>
143
+ inline bool Hash::Iterator<Hash_Ptr_T, Value_T>::operator==(Iterator const& rhs) const
144
+ {
145
+ return hash_->value() == rhs.hash_->value()
146
+ && current_index_ == rhs.current_index_;
147
+ }
148
+
149
+ template<typename Hash_Ptr_T, typename Value_T>
150
+ inline bool Hash::Iterator<Hash_Ptr_T, Value_T>::operator!=(Iterator const& rhs) const
151
+ {
152
+ return !(*this == rhs);
153
+ }
154
+
155
+ template<typename Hash_Ptr_T, typename Value_T>
156
+ inline Object Hash::Iterator<Hash_Ptr_T, Value_T>::current_key()
157
+ {
158
+ return hash_keys()[current_index_];
159
+ }
160
+
161
+ template<typename Hash_Ptr_T, typename Value_T>
162
+ inline Array Hash::Iterator<Hash_Ptr_T, Value_T>::hash_keys()
163
+ {
164
+ if (NIL_P(keys_))
165
+ {
166
+ keys_ = rb_funcall(hash_->value(), rb_intern("keys"), 0, 0);
167
+ }
168
+
169
+ return Array(keys_);
170
+ }
171
+
172
+ inline Hash::iterator Hash::begin()
173
+ {
174
+ return iterator(this);
175
+ }
176
+
177
+ inline Hash::const_iterator Hash::begin() const
178
+ {
179
+ return const_iterator(this);
180
+ }
181
+
182
+ inline Hash::iterator Hash::end()
183
+ {
184
+ return iterator(this, (int)size());
185
+ }
186
+
187
+ inline Hash::const_iterator Hash::end() const
188
+ {
189
+ return const_iterator(this, (int)size());
190
+ }
191
+
192
+ inline bool operator<(Rice::Hash::Entry const& lhs, Rice::Hash::Entry const& rhs)
193
+ {
194
+ Rice::Object lhs_key(lhs.key);
195
+ Rice::Object rhs_key(rhs.key);
196
+ if (lhs_key < rhs_key)
197
+ {
198
+ return true;
199
+ }
200
+ else if (lhs_key > rhs_key)
201
+ {
202
+ return false;
203
+ }
204
+ else if (Rice::Object(lhs.value.value()) < Rice::Object(rhs.value.value()))
205
+ {
206
+ return true;
207
+ }
208
+ else
209
+ {
210
+ return false;
211
+ }
212
+ }
213
+ }
214
+
215
+ namespace Rice::detail
216
+ {
217
+ template<>
218
+ struct Type<Hash>
219
+ {
220
+ static bool verify()
221
+ {
222
+ return true;
223
+ }
224
+ };
225
+
226
+ template<>
227
+ class To_Ruby<Hash>
228
+ {
229
+ public:
230
+ VALUE convert(Hash const& x)
231
+ {
232
+ return x.value();
233
+ }
234
+ };
235
+
236
+ template<>
237
+ class From_Ruby<Hash>
238
+ {
239
+ public:
240
+ Convertible is_convertible(VALUE value)
241
+ {
242
+ switch (rb_type(value))
243
+ {
244
+ case RUBY_T_HASH:
245
+ return Convertible::Exact;
246
+ break;
247
+ default:
248
+ return Convertible::None;
249
+ }
250
+ }
251
+
252
+ Hash convert(VALUE value)
253
+ {
254
+ return Hash(value);
255
+ }
256
+ };
257
+ }
@@ -0,0 +1,46 @@
1
+ #ifndef Rice__Identifier__hpp_
2
+ #define Rice__Identifier__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+ class Symbol;
7
+
8
+ //! A wrapper for the ID type
9
+ /*! An ID is ruby's internal representation of a Symbol object.
10
+ */
11
+ class Identifier
12
+ {
13
+ public:
14
+ //! Construct a new Identifier from an ID.
15
+ Identifier(ID id);
16
+
17
+ //! Construct a new Identifier from a Symbol.
18
+ Identifier(Symbol const& symbol);
19
+
20
+ //! Construct a new Identifier from a c string.
21
+ Identifier(char const* s, Encoding encoding = Encoding::utf8());
22
+
23
+ //! Construct a new Identifier from a string.
24
+ Identifier(std::string const& string, Encoding encoding = Encoding::utf8());
25
+
26
+ //! Return a string representation of the Identifier.
27
+ char const* c_str() const;
28
+
29
+ //! Return a string representation of the Identifier.
30
+ std::string str() const;
31
+
32
+ //! Return the underlying ID
33
+ ID id() const { return id_; }
34
+
35
+ //! Return the underlying ID
36
+ operator ID() const { return id_; }
37
+
38
+ //! Return the ID as a Symbol
39
+ VALUE to_sym() const;
40
+
41
+ private:
42
+ ID id_;
43
+ };
44
+ } // namespace Rice
45
+
46
+ #endif // Rice__Identifier__hpp_
@@ -0,0 +1,31 @@
1
+ namespace Rice
2
+ {
3
+ inline Identifier::Identifier(ID id) : id_(id)
4
+ {
5
+ }
6
+
7
+ inline Identifier::Identifier(char const* name, Encoding encoding)
8
+ {
9
+ this->id_ = detail::protect(rb_intern3, name, (long)strlen(name), encoding);
10
+ }
11
+
12
+ inline Identifier::Identifier(const std::string& name, Encoding encoding)
13
+ {
14
+ this->id_ = detail::protect(rb_intern3, name.c_str(), (long)name.size(), encoding);
15
+ }
16
+
17
+ inline char const* Identifier::c_str() const
18
+ {
19
+ return detail::protect(rb_id2name, id_);
20
+ }
21
+
22
+ inline std::string Identifier::str() const
23
+ {
24
+ return c_str();
25
+ }
26
+
27
+ inline VALUE Identifier::to_sym() const
28
+ {
29
+ return ID2SYM(id_);
30
+ }
31
+ }
@@ -0,0 +1,72 @@
1
+ #ifndef Rice__Module__hpp_
2
+ #define Rice__Module__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+ template <typename T>
7
+ void validateType();
8
+
9
+ //! A helper for defining a Module and its methods.
10
+ /*! This class provides a C++-style interface to ruby's Module class and
11
+ * for defining methods on that module.
12
+ *
13
+ * Many of the methods are defined in Module_impl.hpp so that they can
14
+ * return a reference to the most derived type.
15
+ */
16
+ // TODO: we can't inherit from Builtin_Object, because Class needs
17
+ // type T_CLASS and Module needs type T_MODULE
18
+ class Module : public Object
19
+ {
20
+ public:
21
+ //! Default construct a Module and initialize it to rb_cObject.
22
+ Module();
23
+
24
+ //! Construct a Module from an existing Module object.
25
+ Module(VALUE v);
26
+
27
+ //! Construct a Module from an string that references a Module
28
+ Module(std::string name, Object under = rb_cObject);
29
+
30
+ //! Return the name of the module.
31
+ String name() const;
32
+
33
+ //! Return an array containing the Module's ancestors.
34
+ /*! You will need to include Array.hpp to use this function.
35
+ */
36
+ Array ancestors() const;
37
+
38
+ //! Return the module's singleton class.
39
+ /*! You will need to include Class.hpp to use this function.
40
+ */
41
+ Class singleton_class() const;
42
+
43
+ //! Evaluate the given string in the context of the module.
44
+ /*! This is equivalant to calling obj.module_eval(s) from inside the
45
+ * interpreter.
46
+ * \return the result of the expression.
47
+ */
48
+ Object module_eval(String const& s);
49
+
50
+ #include "shared_methods.hpp"
51
+ protected:
52
+ template<bool IsMethod, typename Function_T>
53
+ void wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo);
54
+ };
55
+
56
+ //! Define a new module in the namespace given by module.
57
+ /*! \param module the module in which to define the new module.
58
+ * \param name the name of the new module.
59
+ */
60
+ Module define_module_under(Object module, char const * name);
61
+
62
+ //! Define a new module in the default namespace.
63
+ /*! \param name the name of the new module.
64
+ */
65
+ Module define_module(char const * name);
66
+
67
+ //! Create a new anonymous module.
68
+ /*! \return the new module.
69
+ */
70
+ Module anonymous_module();
71
+ }
72
+ #endif // Rice__Module__hpp_
@@ -0,0 +1,101 @@
1
+
2
+ namespace Rice
3
+ {
4
+ inline Module::Module() : Object(rb_cObject)
5
+ {
6
+ }
7
+
8
+ inline Module::Module(VALUE value) : Object(value)
9
+ {
10
+ if (::rb_type(value) != T_CLASS && ::rb_type(value) != T_MODULE)
11
+ {
12
+ throw Exception(
13
+ rb_eTypeError,
14
+ "Expected a Module but got a %s",
15
+ detail::protect(rb_obj_classname, value)); // TODO: might raise an exception
16
+ }
17
+ }
18
+
19
+ //! Construct a Module from an string that references a Module
20
+ inline Module::Module(std::string name, Object under)
21
+ {
22
+ VALUE result = under.const_get(name);
23
+
24
+ if (::rb_type(result) != T_MODULE)
25
+ {
26
+ throw Exception(
27
+ rb_eTypeError,
28
+ "Expected a Module but got a %s",
29
+ detail::protect(rb_obj_classname, result)); // TODO: might raise an exception
30
+ }
31
+
32
+ this->set_value(result);
33
+ }
34
+
35
+ template<bool IsMethod, typename Function_T>
36
+ inline void Module::wrap_native_call(VALUE klass, std::string name, Function_T&& function, MethodInfo* methodInfo)
37
+ {
38
+ // Make sure the return type and arguments have been previously seen by Rice
39
+ using traits = detail::method_traits<Function_T, IsMethod>;
40
+ detail::verifyType<typename traits::Return_T>();
41
+ detail::verifyTypes<typename traits::Arg_Ts>();
42
+
43
+ // Define a NativeFunction to bridge Ruby to C++
44
+ detail::NativeFunction<VALUE, Function_T, IsMethod>::define(klass, name, std::forward<Function_T>(function), methodInfo);
45
+ }
46
+
47
+ inline Module define_module_under(Object module, char const* name)
48
+ {
49
+ return detail::protect(rb_define_module_under, module.value(), name);
50
+ }
51
+
52
+ inline Module define_module(char const* name)
53
+ {
54
+ return detail::protect(rb_define_module, name);
55
+ }
56
+
57
+ inline Module anonymous_module()
58
+ {
59
+ VALUE klass = detail::protect(rb_module_new);
60
+ VALUE singleton = detail::protect(rb_singleton_class, klass);
61
+
62
+ // Ruby will reuse addresses previously assigned to other modules
63
+ // that have subsequently been garbage collected
64
+ detail::Registries::instance.natives.reset(klass);
65
+ detail::Registries::instance.natives.reset(singleton);
66
+
67
+ return klass;
68
+ }
69
+ }
70
+
71
+ namespace Rice::detail
72
+ {
73
+ template<>
74
+ struct Type<Module>
75
+ {
76
+ static bool verify()
77
+ {
78
+ return true;
79
+ }
80
+ };
81
+
82
+ template<>
83
+ class To_Ruby<Module>
84
+ {
85
+ public:
86
+ VALUE convert(Module const& x)
87
+ {
88
+ return x.value();
89
+ }
90
+ };
91
+
92
+ template<>
93
+ class From_Ruby<Module>
94
+ {
95
+ public:
96
+ Module convert(VALUE value)
97
+ {
98
+ return Module(value);
99
+ }
100
+ };
101
+ }