rice 4.3.3 → 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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -26
  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/README.md +7 -2
  8. data/Rakefile +12 -5
  9. data/include/rice/rice.hpp +9522 -4426
  10. data/include/rice/stl.hpp +2831 -1198
  11. data/lib/make_rice_headers.rb +79 -0
  12. data/lib/mkmf-rice.rb +40 -94
  13. data/lib/rice/version.rb +3 -0
  14. data/lib/rice.rb +1 -0
  15. data/lib/rubygems/builder.rb +11 -0
  16. data/lib/rubygems/cmake_builder.rb +113 -0
  17. data/lib/rubygems_plugin.rb +9 -0
  18. data/rice/Address_Registration_Guard.hpp +72 -3
  19. data/rice/Arg.hpp +26 -6
  20. data/rice/Arg.ipp +35 -2
  21. data/rice/Buffer.hpp +123 -0
  22. data/rice/Buffer.ipp +599 -0
  23. data/rice/Callback.hpp +21 -0
  24. data/rice/Callback.ipp +13 -0
  25. data/rice/Constructor.hpp +4 -27
  26. data/rice/Constructor.ipp +79 -0
  27. data/rice/Data_Object.hpp +73 -3
  28. data/rice/Data_Object.ipp +388 -96
  29. data/rice/Data_Type.hpp +214 -3
  30. data/rice/Data_Type.ipp +144 -67
  31. data/rice/Director.hpp +0 -2
  32. data/rice/Enum.hpp +4 -7
  33. data/rice/Enum.ipp +102 -55
  34. data/rice/Exception.hpp +62 -2
  35. data/rice/Exception.ipp +7 -12
  36. data/rice/Init.hpp +8 -0
  37. data/rice/Init.ipp +8 -0
  38. data/rice/JumpException.hpp +44 -0
  39. data/rice/JumpException.ipp +48 -0
  40. data/rice/MemoryView.hpp +11 -0
  41. data/rice/MemoryView.ipp +3 -0
  42. data/rice/Return.hpp +7 -27
  43. data/rice/Return.ipp +13 -13
  44. data/rice/cpp_api/Array.hpp +209 -0
  45. data/rice/cpp_api/Array.ipp +304 -0
  46. data/rice/cpp_api/Builtin_Object.hpp +31 -0
  47. data/rice/cpp_api/Builtin_Object.ipp +37 -0
  48. data/rice/cpp_api/Class.hpp +70 -0
  49. data/rice/cpp_api/Class.ipp +97 -0
  50. data/rice/cpp_api/Encoding.hpp +32 -0
  51. data/rice/cpp_api/Encoding.ipp +59 -0
  52. data/rice/cpp_api/Hash.hpp +194 -0
  53. data/rice/cpp_api/Hash.ipp +257 -0
  54. data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
  55. data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
  56. data/rice/cpp_api/Module.hpp +72 -0
  57. data/rice/cpp_api/Module.ipp +101 -0
  58. data/rice/cpp_api/Object.hpp +272 -0
  59. data/rice/cpp_api/Object.ipp +235 -0
  60. data/rice/cpp_api/String.hpp +74 -0
  61. data/rice/cpp_api/String.ipp +120 -0
  62. data/rice/cpp_api/Struct.hpp +113 -0
  63. data/rice/cpp_api/Struct.ipp +92 -0
  64. data/rice/cpp_api/Symbol.hpp +46 -0
  65. data/rice/cpp_api/Symbol.ipp +93 -0
  66. data/rice/cpp_api/shared_methods.hpp +134 -0
  67. data/rice/detail/DefaultHandler.hpp +12 -0
  68. data/rice/detail/DefaultHandler.ipp +8 -0
  69. data/rice/detail/HandlerRegistry.hpp +5 -35
  70. data/rice/detail/HandlerRegistry.ipp +7 -11
  71. data/rice/detail/InstanceRegistry.hpp +1 -4
  72. data/rice/detail/MethodInfo.hpp +12 -10
  73. data/rice/detail/MethodInfo.ipp +26 -21
  74. data/rice/detail/Native.hpp +33 -0
  75. data/rice/detail/Native.ipp +157 -0
  76. data/rice/detail/NativeAttributeGet.hpp +52 -0
  77. data/rice/detail/NativeAttributeGet.ipp +57 -0
  78. data/rice/detail/NativeAttributeSet.hpp +44 -0
  79. data/rice/detail/NativeAttributeSet.ipp +88 -0
  80. data/rice/detail/NativeCallbackFFI.hpp +55 -0
  81. data/rice/detail/NativeCallbackFFI.ipp +151 -0
  82. data/rice/detail/NativeCallbackSimple.hpp +30 -0
  83. data/rice/detail/NativeCallbackSimple.ipp +29 -0
  84. data/rice/detail/NativeFunction.hpp +33 -23
  85. data/rice/detail/NativeFunction.ipp +309 -70
  86. data/rice/detail/NativeIterator.hpp +9 -11
  87. data/rice/detail/NativeIterator.ipp +33 -31
  88. data/rice/detail/NativeRegistry.hpp +24 -15
  89. data/rice/detail/NativeRegistry.ipp +23 -48
  90. data/rice/detail/Proc.hpp +4 -0
  91. data/rice/detail/Proc.ipp +85 -0
  92. data/rice/detail/Registries.hpp +0 -7
  93. data/rice/detail/Registries.ipp +0 -18
  94. data/rice/detail/RubyFunction.hpp +0 -3
  95. data/rice/detail/RubyFunction.ipp +4 -8
  96. data/rice/detail/RubyType.hpp +16 -0
  97. data/rice/detail/RubyType.ipp +232 -0
  98. data/rice/detail/Type.hpp +7 -6
  99. data/rice/detail/Type.ipp +192 -45
  100. data/rice/detail/TypeRegistry.hpp +15 -7
  101. data/rice/detail/TypeRegistry.ipp +105 -12
  102. data/rice/detail/Wrapper.hpp +68 -32
  103. data/rice/detail/Wrapper.ipp +121 -109
  104. data/rice/detail/cpp_protect.hpp +5 -6
  105. data/rice/detail/default_allocation_func.ipp +0 -2
  106. data/rice/detail/from_ruby.hpp +38 -3
  107. data/rice/detail/from_ruby.ipp +1321 -492
  108. data/rice/detail/ruby.hpp +18 -0
  109. data/rice/detail/to_ruby.hpp +41 -3
  110. data/rice/detail/to_ruby.ipp +1424 -194
  111. data/rice/global_function.hpp +0 -4
  112. data/rice/global_function.ipp +0 -1
  113. data/rice/libc/file.hpp +11 -0
  114. data/rice/libc/file.ipp +32 -0
  115. data/rice/rice.hpp +116 -26
  116. data/rice/ruby_mark.hpp +4 -3
  117. data/rice/stl/complex.hpp +6 -0
  118. data/rice/stl/complex.ipp +93 -0
  119. data/rice/stl/exception.hpp +11 -0
  120. data/rice/stl/exception.ipp +29 -0
  121. data/rice/stl/exception_ptr.hpp +6 -0
  122. data/rice/stl/exception_ptr.ipp +27 -0
  123. data/rice/stl/map.hpp +12 -0
  124. data/rice/stl/map.ipp +469 -0
  125. data/rice/stl/monostate.hpp +6 -0
  126. data/rice/stl/monostate.ipp +80 -0
  127. data/rice/stl/multimap.hpp +14 -0
  128. data/rice/stl/multimap.ipp +448 -0
  129. data/rice/stl/optional.hpp +6 -0
  130. data/rice/stl/optional.ipp +118 -0
  131. data/rice/stl/pair.hpp +13 -0
  132. data/rice/stl/pair.ipp +155 -0
  133. data/rice/stl/reference_wrapper.hpp +6 -0
  134. data/rice/stl/reference_wrapper.ipp +41 -0
  135. data/rice/stl/set.hpp +12 -0
  136. data/rice/stl/set.ipp +495 -0
  137. data/rice/stl/shared_ptr.hpp +28 -0
  138. data/rice/stl/shared_ptr.ipp +224 -0
  139. data/rice/stl/string.hpp +6 -0
  140. data/rice/stl/string.ipp +158 -0
  141. data/rice/stl/string_view.hpp +6 -0
  142. data/rice/stl/string_view.ipp +65 -0
  143. data/rice/stl/tuple.hpp +6 -0
  144. data/rice/stl/tuple.ipp +128 -0
  145. data/rice/stl/type_index.hpp +6 -0
  146. data/rice/stl/type_index.ipp +30 -0
  147. data/rice/stl/type_info.hpp +6 -0
  148. data/rice/stl/type_info.ipp +29 -0
  149. data/rice/stl/unique_ptr.hpp +22 -0
  150. data/rice/stl/unique_ptr.ipp +139 -0
  151. data/rice/stl/unordered_map.hpp +12 -0
  152. data/rice/stl/unordered_map.ipp +469 -0
  153. data/rice/stl/variant.hpp +6 -0
  154. data/rice/stl/variant.ipp +242 -0
  155. data/rice/stl/vector.hpp +12 -0
  156. data/rice/stl/vector.ipp +590 -0
  157. data/rice/stl.hpp +11 -3
  158. data/rice/traits/attribute_traits.hpp +26 -0
  159. data/rice/traits/function_traits.hpp +95 -0
  160. data/rice/traits/method_traits.hpp +47 -0
  161. data/rice/traits/rice_traits.hpp +160 -0
  162. data/rice.gemspec +85 -0
  163. data/test/embed_ruby.cpp +7 -1
  164. data/test/extconf.rb +2 -0
  165. data/test/test_Address_Registration_Guard.cpp +5 -0
  166. data/test/test_Array.cpp +18 -4
  167. data/test/test_Attribute.cpp +136 -21
  168. data/test/test_Buffer.cpp +285 -0
  169. data/test/test_Builtin_Object.cpp +5 -0
  170. data/test/test_Callback.cpp +230 -0
  171. data/test/test_Class.cpp +5 -31
  172. data/test/test_Constructor.cpp +69 -6
  173. data/test/test_Data_Object.cpp +97 -38
  174. data/test/test_Data_Type.cpp +470 -65
  175. data/test/test_Director.cpp +17 -8
  176. data/test/test_Enum.cpp +155 -40
  177. data/test/test_Exception.cpp +235 -0
  178. data/test/test_File.cpp +70 -0
  179. data/test/test_From_Ruby.cpp +609 -0
  180. data/test/test_Hash.cpp +5 -0
  181. data/test/test_Identifier.cpp +5 -0
  182. data/test/test_Inheritance.cpp +6 -1
  183. data/test/test_Iterator.cpp +6 -1
  184. data/test/test_Jump_Exception.cpp +23 -0
  185. data/test/test_Keep_Alive.cpp +13 -19
  186. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
  187. data/test/test_Memory_Management.cpp +5 -0
  188. data/test/test_Module.cpp +128 -67
  189. data/test/test_Native_Registry.cpp +2 -34
  190. data/test/test_Object.cpp +5 -0
  191. data/test/test_Overloads.cpp +806 -0
  192. data/test/test_Ownership.cpp +160 -54
  193. data/test/test_Proc.cpp +44 -0
  194. data/test/test_Self.cpp +9 -4
  195. data/test/test_Stl_Exception.cpp +109 -0
  196. data/test/test_Stl_Map.cpp +54 -42
  197. data/test/test_Stl_Multimap.cpp +693 -0
  198. data/test/test_Stl_Optional.cpp +5 -0
  199. data/test/test_Stl_Pair.cpp +14 -9
  200. data/test/test_Stl_Reference_Wrapper.cpp +9 -2
  201. data/test/test_Stl_Set.cpp +790 -0
  202. data/test/test_Stl_SharedPtr.cpp +458 -0
  203. data/test/test_Stl_String.cpp +5 -0
  204. data/test/test_Stl_String_View.cpp +5 -0
  205. data/test/test_Stl_Tuple.cpp +116 -0
  206. data/test/test_Stl_Type.cpp +147 -0
  207. data/test/test_Stl_UniquePtr.cpp +202 -0
  208. data/test/test_Stl_Unordered_Map.cpp +43 -38
  209. data/test/test_Stl_Variant.cpp +217 -84
  210. data/test/test_Stl_Vector.cpp +306 -58
  211. data/test/test_String.cpp +5 -0
  212. data/test/test_Struct.cpp +5 -0
  213. data/test/test_Symbol.cpp +5 -0
  214. data/test/test_Template.cpp +192 -0
  215. data/test/test_To_Ruby.cpp +524 -0
  216. data/test/test_Tracking.cpp +1 -0
  217. data/test/test_Type.cpp +171 -0
  218. data/test/test_global_functions.cpp +67 -7
  219. data/test/unittest.cpp +8 -0
  220. metadata +127 -26
  221. data/lib/version.rb +0 -3
  222. data/rice/Address_Registration_Guard_defn.hpp +0 -79
  223. data/rice/Data_Object_defn.hpp +0 -84
  224. data/rice/Data_Type_defn.hpp +0 -190
  225. data/rice/Exception_defn.hpp +0 -68
  226. data/rice/HandlerRegistration.hpp +0 -15
  227. data/rice/detail/ExceptionHandler.hpp +0 -8
  228. data/rice/detail/ExceptionHandler.ipp +0 -28
  229. data/rice/detail/ExceptionHandler_defn.hpp +0 -77
  230. data/rice/detail/Jump_Tag.hpp +0 -21
  231. data/rice/detail/NativeAttribute.hpp +0 -64
  232. data/rice/detail/NativeAttribute.ipp +0 -112
  233. data/rice/detail/from_ruby_defn.hpp +0 -38
  234. data/rice/detail/to_ruby_defn.hpp +0 -48
  235. data/test/test_Jump_Tag.cpp +0 -17
  236. data/test/test_Stl_SmartPointer.cpp +0 -283
  237. data/test/test_To_From_Ruby.cpp +0 -399
@@ -0,0 +1,232 @@
1
+ namespace Rice::detail
2
+ {
3
+ template<>
4
+ class RubyType<bool>
5
+ {
6
+ public:
7
+ using FromRuby_T = bool(*)(VALUE);
8
+
9
+ static inline FromRuby_T fromRuby = RB_TEST;
10
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_TRUE, RUBY_T_FALSE };
11
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_NIL };
12
+ static inline std::set<ruby_value_type> Narrowable = { };
13
+ static inline std::string packTemplate = "not supported";
14
+ };
15
+
16
+ template<>
17
+ class RubyType<char>
18
+ {
19
+ public:
20
+ using FromRuby_T = char(*)(VALUE);
21
+
22
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
23
+ static inline std::set<ruby_value_type> Exact = { };
24
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
25
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
26
+ static inline std::string packTemplate = CHAR_MIN < 0 ? "c*" : "C*";
27
+ };
28
+
29
+ template<>
30
+ class RubyType<signed char>
31
+ {
32
+ public:
33
+ // Hack - need to later typecast
34
+ using FromRuby_T = char(*)(VALUE);
35
+
36
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
37
+ static inline std::set<ruby_value_type> Exact = { };
38
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
39
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
40
+ static inline std::string packTemplate = "c*";
41
+ };
42
+
43
+ template<>
44
+ class RubyType<unsigned char>
45
+ {
46
+ public:
47
+ // Hack - need to later typecast, although char's in ruby are unsigned
48
+ using FromRuby_T = char(*)(VALUE);
49
+
50
+ static inline FromRuby_T fromRuby = rb_num2char_inline;
51
+ static inline std::set<ruby_value_type> Exact = { };
52
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_STRING };
53
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
54
+ static inline std::string packTemplate = "C*";
55
+ };
56
+
57
+ template<>
58
+ class RubyType<short>
59
+ {
60
+ public:
61
+ using FromRuby_T = short(*)(VALUE);
62
+
63
+ static inline FromRuby_T fromRuby = rb_num2short_inline;
64
+ static inline std::set<ruby_value_type> Exact = { };
65
+ static inline std::set<ruby_value_type> Castable = { };
66
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
67
+ static inline std::string packTemplate = "s*";
68
+ };
69
+
70
+ template<>
71
+ class RubyType<unsigned short>
72
+ {
73
+ public:
74
+ using FromRuby_T = unsigned short(*)(VALUE);
75
+
76
+ static inline FromRuby_T fromRuby = rb_num2ushort;
77
+ static inline std::set<ruby_value_type> Exact = { };
78
+ static inline std::set<ruby_value_type> Castable = { };
79
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FIXNUM };
80
+ static inline std::string packTemplate = "S*";
81
+ };
82
+
83
+ template<>
84
+ class RubyType<int>
85
+ {
86
+ public:
87
+ using FromRuby_T = int(*)(VALUE);
88
+
89
+ static inline FromRuby_T fromRuby = rb_num2int_inline;
90
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
91
+ static inline std::set<ruby_value_type> Castable = { };
92
+ // We allow bignum to integer because Ruby switches to bignum at about 2 billion on 64 bit systems,
93
+ // while int can go up to 4 billion
94
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
95
+ static inline std::string packTemplate = "i*";
96
+ };
97
+
98
+ template<>
99
+ class RubyType<unsigned int>
100
+ {
101
+ public:
102
+ using FromRuby_T = unsigned int(*)(VALUE);
103
+
104
+ static inline FromRuby_T fromRuby = RB_NUM2UINT;
105
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
106
+ static inline std::set<ruby_value_type> Castable = { };
107
+ // We allow bignum to integer because Ruby switches to bignum at about 2 billion on 64 bit systems,
108
+ // while int can go up to 4 billion
109
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
110
+ static inline std::string packTemplate = "I*";
111
+ };
112
+
113
+ template<>
114
+ class RubyType<long>
115
+ {
116
+ public:
117
+ using FromRuby_T = long(*)(VALUE);
118
+
119
+ static inline FromRuby_T fromRuby = rb_num2long_inline;
120
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
121
+ static inline std::set<ruby_value_type> Castable = { };
122
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM };
123
+ static inline std::string packTemplate = "l_*";
124
+ };
125
+
126
+ template<>
127
+ class RubyType<unsigned long>
128
+ {
129
+ public:
130
+ using FromRuby_T = unsigned long(*)(VALUE);
131
+
132
+ static inline FromRuby_T fromRuby = rb_num2ulong_inline;
133
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM };
134
+ static inline std::set<ruby_value_type> Castable = { };
135
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_BIGNUM};
136
+ static inline std::string packTemplate = "L_*";
137
+ };
138
+
139
+ template<>
140
+ class RubyType<long long>
141
+ {
142
+ public:
143
+ using FromRuby_T = long long(*)(VALUE);
144
+
145
+ static inline FromRuby_T fromRuby = rb_num2ll_inline;
146
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
147
+ static inline std::set<ruby_value_type> Castable = { };
148
+ static inline std::set<ruby_value_type> Narrowable = { };
149
+ static inline std::string packTemplate = "q_*";
150
+ };
151
+
152
+ template<>
153
+ class RubyType<unsigned long long>
154
+ {
155
+ public:
156
+ using FromRuby_T = unsigned long long(*)(VALUE);
157
+
158
+ static inline FromRuby_T fromRuby = RB_NUM2ULL;
159
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
160
+ static inline std::set<ruby_value_type> Castable = { };
161
+ static inline std::set<ruby_value_type> Narrowable = { };
162
+ static inline std::string packTemplate = "Q_*";
163
+ };
164
+
165
+ template<>
166
+ class RubyType<float>
167
+ {
168
+ public:
169
+ using FromRuby_T = double(*)(VALUE);
170
+
171
+ static inline FromRuby_T fromRuby = rb_num2dbl;
172
+ static inline std::set<ruby_value_type> Exact = { };
173
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM };
174
+ static inline std::set<ruby_value_type> Narrowable = { RUBY_T_FLOAT };
175
+ static inline std::string packTemplate = "f*";
176
+ };
177
+
178
+ template<>
179
+ class RubyType<double>
180
+ {
181
+ public:
182
+ using FromRuby_T = double(*)(VALUE);
183
+
184
+ static inline FromRuby_T fromRuby = rb_num2dbl;
185
+ static inline std::set<ruby_value_type> Exact = { RUBY_T_FLOAT };
186
+ static inline std::set<ruby_value_type> Castable = { RUBY_T_FIXNUM, RUBY_T_BIGNUM };
187
+ static inline std::set<ruby_value_type> Narrowable = { };
188
+ static inline std::string packTemplate = "d*";
189
+ };
190
+
191
+ template<>
192
+ class RubyType<void>
193
+ {
194
+ public:
195
+ static inline std::set<ruby_value_type> Exact = { };
196
+ static inline std::set<ruby_value_type> Castable = { };
197
+ static inline std::set<ruby_value_type> Narrowable = { };
198
+ };
199
+ }
200
+
201
+ namespace Rice::detail
202
+ {
203
+ template<typename T>
204
+ inline Data_Type<T> define_ruby_type()
205
+ {
206
+ std::string name = detail::typeName(typeid(T*));
207
+ std::string klassName = detail::rubyClassName(name);
208
+ Identifier id(klassName);
209
+
210
+ Module rb_mRice = define_module("Rice");
211
+ return define_class_under<T>(rb_mRice, id);
212
+ }
213
+
214
+ inline void define_ruby_types()
215
+ {
216
+ define_ruby_type<bool>();
217
+ define_ruby_type<char>();
218
+ define_ruby_type<signed char>();
219
+ define_ruby_type<unsigned char>();
220
+ define_ruby_type<short>();
221
+ define_ruby_type<unsigned short>();
222
+ define_ruby_type<int>();
223
+ define_ruby_type<unsigned int>();
224
+ define_ruby_type<long>();
225
+ define_ruby_type<unsigned long>();
226
+ define_ruby_type<long long>();
227
+ define_ruby_type<unsigned long long>();
228
+ define_ruby_type<float>();
229
+ define_ruby_type<double>();
230
+ define_ruby_type<void>();
231
+ }
232
+ }
data/rice/detail/Type.hpp CHANGED
@@ -1,9 +1,7 @@
1
1
  #ifndef Rice__Type__hpp_
2
2
  #define Rice__Type__hpp_
3
3
 
4
- #include <string>
5
- #include <typeinfo>
6
- #include "../traits/rice_traits.hpp"
4
+ #include <regex>
7
5
 
8
6
  namespace Rice::detail
9
7
  {
@@ -15,7 +13,12 @@ namespace Rice::detail
15
13
 
16
14
  // Return the name of a type
17
15
  std::string typeName(const std::type_info& typeInfo);
18
- std::string makeClassName(const std::type_info& typeInfo);
16
+ std::string typeName(const std::type_index& typeIndex);
17
+ std::string cppClassName(const std::string& typeInfoName);
18
+ std::string rubyClassName(const std::string& typeInfoName);
19
+ std::string findGroup(std::string& string, size_t start = 0);
20
+ void replaceGroup(std::string& string, std::regex regex, std::string replacement);
21
+ void replaceAll(std::string& string, std::regex regex, std::string replacement);
19
22
 
20
23
  template<typename T>
21
24
  void verifyType();
@@ -24,6 +27,4 @@ namespace Rice::detail
24
27
  void verifyTypes();
25
28
  }
26
29
 
27
- #include "Type.ipp"
28
-
29
30
  #endif // Rice__Type__hpp_
data/rice/detail/Type.ipp CHANGED
@@ -1,12 +1,3 @@
1
- #include "../traits/rice_traits.hpp"
2
-
3
- #include <iosfwd>
4
- #include <iterator>
5
- #include <numeric>
6
- #include <regex>
7
- #include <sstream>
8
- #include <tuple>
9
-
10
1
  #ifdef __GNUC__
11
2
  #include <cxxabi.h>
12
3
  #include <cstdlib>
@@ -15,14 +6,22 @@
15
6
 
16
7
  namespace Rice::detail
17
8
  {
18
- template<>
19
- struct Type<void>
9
+ template<typename T>
10
+ bool Type<T>::verify()
20
11
  {
21
- static bool verify()
12
+ if constexpr (std::is_fundamental_v<T>)
22
13
  {
23
14
  return true;
24
15
  }
25
- };
16
+ else if constexpr (std::is_array_v<T> && std::is_fundamental_v<std::remove_extent_t<T>>)
17
+ {
18
+ return true;
19
+ }
20
+ else
21
+ {
22
+ return Registries::instance.types.verify<T>();
23
+ }
24
+ }
26
25
 
27
26
  template<typename T>
28
27
  void verifyType()
@@ -31,7 +30,7 @@ namespace Rice::detail
31
30
  }
32
31
 
33
32
  template<typename Tuple_T, size_t...Is>
34
- void verifyTypesImpl()
33
+ void verifyTypesImpl(std::index_sequence<Is...> indexes)
35
34
  {
36
35
  (verifyType<typename std::tuple_element<Is, Tuple_T>::type>(), ...);
37
36
  }
@@ -39,10 +38,8 @@ namespace Rice::detail
39
38
  template<typename Tuple_T>
40
39
  void verifyTypes()
41
40
  {
42
- if constexpr (std::tuple_size<Tuple_T>::value > 0)
43
- {
44
- verifyTypesImpl<Tuple_T, std::tuple_size<Tuple_T>::value - 1>();
45
- }
41
+ std::make_index_sequence<std::tuple_size_v<Tuple_T>> indexes;
42
+ verifyTypesImpl<Tuple_T>(indexes);
46
43
  }
47
44
 
48
45
  inline std::string demangle(char const* mangled_name)
@@ -89,13 +86,87 @@ namespace Rice::detail
89
86
  return demangle(typeInfo.name());
90
87
  }
91
88
 
92
- inline std::string makeClassName(const std::type_info& typeInfo)
89
+ inline std::string typeName(const std::type_index& typeIndex)
90
+ {
91
+ return demangle(typeIndex.name());
92
+ }
93
+
94
+ // Find text inside of < > taking into account nested groups.
95
+ //
96
+ // Example:
97
+ //
98
+ // std::vector<std::vector<int>, std::allocator<std::vector, std::allocator<int>>>
99
+ inline std::string findGroup(std::string& string, size_t offset)
93
100
  {
94
- std::string base = demangle(typeInfo.name());
101
+ int depth = 0;
102
+
103
+ auto begin = string.begin() + offset;
104
+ auto start = begin;
105
+ for (auto iter = begin; iter != string.end(); iter++)
106
+ {
107
+ if (*iter == '<')
108
+ {
109
+ if (depth == 0)
110
+ {
111
+ start = iter;
112
+ }
113
+ depth++;
114
+ }
115
+ else if (*iter == '>')
116
+ {
117
+ depth--;
118
+ if (depth == 0)
119
+ {
120
+ // Add + 1 to include current ">" character
121
+ return string.substr(offset + (start - begin), 1 + (iter - start));
122
+ }
123
+ else if (depth < 0)
124
+ {
125
+ throw std::runtime_error("Unbalanced Group");
126
+ }
127
+ }
128
+ }
129
+ throw std::runtime_error("Unbalanced Group");
130
+ }
131
+
132
+ inline void replaceAll(std::string& string, std::regex regex, std::string replacement)
133
+ {
134
+ std::smatch match;
135
+ while (std::regex_search(string, match, regex))
136
+ {
137
+ string = std::regex_replace(string, regex, replacement);
138
+ }
139
+ }
140
+
141
+ inline void removeGroup(std::string& string, std::regex regex)
142
+ {
143
+ std::smatch match;
144
+ while (std::regex_search(string, match, regex))
145
+ {
146
+ std::string group = findGroup(string, match.position());
147
+ group = match.str() + group;
148
+ string.erase(match.position(), group.length());
149
+ }
150
+ }
151
+
152
+ inline void replaceGroup(std::string& string, std::regex regex, std::string replacement)
153
+ {
154
+ std::smatch match;
155
+ while (std::regex_search(string, match, regex))
156
+ {
157
+ std::string group = findGroup(string, match.position());
158
+ group = match.str() + group;
159
+ string.replace(match.position(), group.length(), replacement);
160
+ }
161
+ }
162
+
163
+ inline std::string cppClassName(const std::string& typeInfoName)
164
+ {
165
+ std::string base = typeInfoName;
95
166
 
96
167
  // Remove class keyword
97
168
  auto classRegex = std::regex("class +");
98
- base = std::regex_replace(base, classRegex, "");
169
+ base = std::regex_replace(typeInfoName, classRegex, "");
99
170
 
100
171
  // Remove struct keyword
101
172
  auto structRegex = std::regex("struct +");
@@ -103,37 +174,113 @@ namespace Rice::detail
103
174
 
104
175
  // Remove std::__[^:]*::
105
176
  auto stdClangRegex = std::regex("std::__[^:]+::");
106
- base = std::regex_replace(base, stdClangRegex, "");
107
-
108
- // Remove std::
177
+ base = std::regex_replace(base, stdClangRegex, "std::");
178
+
179
+ // Remove allocators
180
+ std::regex allocatorRegex(R"(,\s*std::allocator)");
181
+ removeGroup(base, allocatorRegex);
182
+
183
+ // Remove char_traits
184
+ std::regex charTraitsRegex(R"(,\s*std::char_traits)");
185
+ removeGroup(base, charTraitsRegex);
186
+
187
+ // Remove less (std::map)
188
+ std::regex lessRegex(R"(,\s*std::less)");
189
+ removeGroup(base, lessRegex);
190
+
191
+ // Remove hash (std::unordered_map)
192
+ std::regex hashRegex(R"(,\s*std::hash)");
193
+ removeGroup(base, hashRegex);
194
+
195
+ // Remove equal_to (std::unordered_map)
196
+ std::regex equalRegex(R"(,\s*std::equal_to)");
197
+ removeGroup(base, equalRegex);
198
+
199
+ // Remove spaces before pointers
200
+ auto ptrRegex = std::regex(R"(\s+\*)");
201
+ base = std::regex_replace(base, ptrRegex, "*");
202
+
203
+ // Remove __ptr64
204
+ std::regex ptr64Regex(R"(\s*__ptr64\s*)");
205
+ base = std::regex_replace(base, ptr64Regex, "");
206
+
207
+ // Replace " >" with ">"
208
+ auto trailingAngleBracketSpaceRegex = std::regex(R"(\s+>)");
209
+ replaceAll(base, trailingAngleBracketSpaceRegex, ">");
210
+
211
+ // One space after a comma (MSVC has no spaces, GCC one space)
212
+ auto commaSpaceRegex = std::regex(R"(,(\S))");
213
+ replaceAll(base, commaSpaceRegex, ", $1");
214
+
215
+ // Fix strings
216
+ auto stringRegex = std::regex(R"(basic_string<char>)");
217
+ replaceAll(base, stringRegex, "string");
218
+
219
+ auto wstringRegex = std::regex(R"(basic_string<wchar_t>)");
220
+ replaceAll(base, wstringRegex, "wstring");
221
+
222
+ // Normalize Anonymous namespace
223
+ auto anonymousNamespaceGcc = std::regex(R"(\(anonymous namespace\))");
224
+ replaceAll(base, anonymousNamespaceGcc, "AnonymousNamespace");
225
+ auto anonymousNamespaceMsvc = std::regex(R"(`anonymous namespace')");
226
+ replaceAll(base, anonymousNamespaceMsvc, "AnonymousNamespace");
227
+
228
+ return base;
229
+ }
230
+
231
+
232
+ inline std::string rubyClassName(const std::string& typeInfoName)
233
+ {
234
+ std::string base = cppClassName(typeInfoName);
235
+
236
+ // Remove std:: these could be embedded in template types
109
237
  auto stdRegex = std::regex("std::");
110
238
  base = std::regex_replace(base, stdRegex, "");
111
239
 
112
- // Replace > >
113
- auto trailingAngleBracketSpaceRegex = std::regex(" >");
114
- base = std::regex_replace(base, trailingAngleBracketSpaceRegex, ">");
240
+ // Remove leading namespaces. This will not remove namespaces
241
+ // embedded in template types like std::vector<mynamespace::foo>
242
+ auto leadingNamespacesRegex = std::regex("^[^<]*::");
243
+ base = std::regex_replace(base, leadingNamespacesRegex, "");
115
244
 
116
- // Replace < and >
117
- auto angleBracketRegex = std::regex("<|>");
118
- base = std::regex_replace(base, angleBracketRegex, "__");
245
+ // Capitalize first letter
246
+ base[0] = std::toupper(base[0]);
119
247
 
120
- // Replace ,
121
- auto commaRegex = std::regex(", *");
122
- base = std::regex_replace(base, commaRegex, "_");
248
+ // Replace :: with unicode U+u02F8 (Modified Letter raised colon)
249
+ auto colonRegex = std::regex(R"(:)");
250
+ replaceAll(base, colonRegex, "\uA789");
123
251
 
124
- // Now create a vector of strings split on whitespace
125
- std::istringstream stream(base);
126
- std::vector<std::string> words{ std::istream_iterator<std::string>{stream},
127
- std::istream_iterator<std::string>{} };
252
+ // Replace _ and capitalize the next letter
253
+ std::regex namespaceRegex(R"(_(\w))");
254
+ std::smatch namespaceMatch;
255
+ while (std::regex_search(base, namespaceMatch, namespaceRegex))
256
+ {
257
+ std::string replacement = namespaceMatch[1];
258
+ std::transform(replacement.begin(), replacement.end(), replacement.begin(), ::toupper);
259
+ base.replace(namespaceMatch.position(), namespaceMatch.length(), replacement);
260
+ }
128
261
 
129
- std::string result = std::accumulate(words.begin(), words.end(), std::string(),
130
- [](const std::string& memo, const std::string& word) -> std::string
131
- {
132
- std::string capitalized = word;
133
- capitalized[0] = toupper(capitalized[0]);
134
- return memo + capitalized;
135
- });
262
+ // Replace spaces with unicode U+u00A0 (Non breaking Space)
263
+ auto spaceRegex = std::regex(R"(\s+)");
264
+ replaceAll(base, spaceRegex, "\u00A0");
265
+
266
+ // Replace < with unicode U+227A (Precedes)
267
+ auto lessThanRegex = std::regex("<");
268
+ //replaceAll(base, lessThanRegex, "≺");
269
+ replaceAll(base, lessThanRegex, "\u227A");
270
+
271
+ // Replace > with unicode U+227B (Succeeds)
272
+ auto greaterThanRegex = std::regex(">");
273
+ //replaceAll(base, greaterThanRegex, "≻");
274
+ replaceAll(base, greaterThanRegex, "\u227B");
275
+
276
+ // Replace , with Unicode Character (U+066C) - Arabic Thousands Separator
277
+ auto commaRegex = std::regex(R"(,\s*)");
278
+ replaceAll(base, commaRegex, "\u201A");
279
+
280
+ // Replace * with Unicode Character (U+2217) - Asterisk Operator
281
+ auto asteriskRegex = std::regex(R"(\*)");
282
+ replaceAll(base, asteriskRegex, "\u2217");
136
283
 
137
- return result;
284
+ return base;
138
285
  }
139
286
  }
@@ -2,12 +2,10 @@
2
2
  #define Rice__TypeRegistry__hpp_
3
3
 
4
4
  #include <optional>
5
- #include <string>
6
- #include <typeindex>
7
- #include <typeinfo>
8
5
  #include <unordered_map>
6
+ #include <set>
7
+ #include <regex>
9
8
 
10
- #include "ruby.hpp"
11
9
 
12
10
  /* The type registry keeps track of all C++ types wrapped by Rice. When a native function returns
13
11
  an instance of a class/struct we look up its type to verity that it has been registered.
@@ -31,17 +29,27 @@ namespace Rice::detail
31
29
  bool isDefined();
32
30
 
33
31
  template <typename T>
34
- bool verifyDefined();
32
+ std::pair<VALUE, rb_data_type_t*> getType();
33
+
34
+ template <typename T>
35
+ bool verify();
35
36
 
36
37
  template <typename T>
37
38
  std::pair<VALUE, rb_data_type_t*> figureType(const T& object);
38
39
 
40
+ // Validate types and throw if any types are unverified
41
+ void validateTypes();
42
+
43
+ // Clear unverified types. This is mostly for unit tests
44
+ void clearUnverifiedTypes();
45
+
39
46
  private:
40
47
  std::optional<std::pair<VALUE, rb_data_type_t*>> lookup(const std::type_info& typeInfo);
48
+ void raiseUnverifiedType(const std::string& typeName);
49
+
41
50
  std::unordered_map<std::type_index, std::pair<VALUE, rb_data_type_t*>> registry_{};
51
+ std::set<std::type_index> unverified_{};
42
52
  };
43
53
  }
44
54
 
45
- #include "TypeRegistry.ipp"
46
-
47
55
  #endif // Rice__TypeRegistry__hpp_