rice 2.1.2 → 4.0.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 (245) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/COPYING +2 -2
  5. data/Gemfile +3 -0
  6. data/README.md +45 -1028
  7. data/Rakefile +95 -12
  8. data/include/rice/rice.hpp +7766 -0
  9. data/lib/mkmf-rice.rb +127 -0
  10. data/lib/version.rb +3 -0
  11. data/rice/Address_Registration_Guard.ipp +75 -32
  12. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  13. data/rice/Arg.hpp +80 -4
  14. data/rice/Arg.ipp +51 -0
  15. data/rice/Constructor.hpp +30 -376
  16. data/rice/Data_Object.ipp +234 -107
  17. data/rice/Data_Object_defn.hpp +77 -117
  18. data/rice/Data_Type.hpp +1 -2
  19. data/rice/Data_Type.ipp +251 -295
  20. data/rice/Data_Type_defn.hpp +175 -243
  21. data/rice/Director.hpp +14 -9
  22. data/rice/Enum.hpp +54 -104
  23. data/rice/Enum.ipp +104 -230
  24. data/rice/Exception.hpp +2 -8
  25. data/rice/Exception.ipp +65 -0
  26. data/rice/Exception_defn.hpp +46 -47
  27. data/rice/Identifier.hpp +28 -28
  28. data/rice/Identifier.ipp +23 -27
  29. data/rice/Return.hpp +39 -0
  30. data/rice/Return.ipp +33 -0
  31. data/rice/detail/Exception_Handler.ipp +22 -62
  32. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  33. data/rice/detail/Iterator.hpp +18 -88
  34. data/rice/detail/Iterator.ipp +47 -0
  35. data/rice/detail/Jump_Tag.hpp +21 -0
  36. data/rice/detail/MethodInfo.hpp +44 -0
  37. data/rice/detail/MethodInfo.ipp +78 -0
  38. data/rice/detail/NativeAttribute.hpp +53 -0
  39. data/rice/detail/NativeAttribute.ipp +83 -0
  40. data/rice/detail/NativeFunction.hpp +69 -0
  41. data/rice/detail/NativeFunction.ipp +248 -0
  42. data/rice/detail/RubyFunction.hpp +39 -0
  43. data/rice/detail/RubyFunction.ipp +92 -0
  44. data/rice/detail/Type.hpp +29 -0
  45. data/rice/detail/Type.ipp +138 -0
  46. data/rice/detail/TypeRegistry.hpp +50 -0
  47. data/rice/detail/TypeRegistry.ipp +106 -0
  48. data/rice/detail/Wrapper.hpp +51 -0
  49. data/rice/detail/Wrapper.ipp +151 -0
  50. data/rice/detail/default_allocation_func.hpp +8 -19
  51. data/rice/detail/default_allocation_func.ipp +9 -8
  52. data/rice/detail/from_ruby.hpp +2 -37
  53. data/rice/detail/from_ruby.ipp +1020 -46
  54. data/rice/detail/from_ruby_defn.hpp +38 -0
  55. data/rice/detail/function_traits.hpp +124 -0
  56. data/rice/detail/method_data.hpp +23 -15
  57. data/rice/detail/method_data.ipp +53 -0
  58. data/rice/detail/rice_traits.hpp +116 -0
  59. data/rice/detail/ruby.hpp +9 -49
  60. data/rice/detail/to_ruby.hpp +3 -17
  61. data/rice/detail/to_ruby.ipp +409 -31
  62. data/rice/detail/to_ruby_defn.hpp +48 -0
  63. data/rice/forward_declares.ipp +82 -0
  64. data/rice/global_function.hpp +16 -20
  65. data/rice/global_function.ipp +8 -17
  66. data/rice/rice.hpp +59 -0
  67. data/rice/ruby_mark.hpp +5 -3
  68. data/rice/ruby_try_catch.hpp +4 -4
  69. data/rice/stl.hpp +11 -0
  70. data/sample/callbacks/extconf.rb +6 -0
  71. data/sample/callbacks/sample_callbacks.cpp +35 -0
  72. data/sample/callbacks/test.rb +28 -0
  73. data/sample/enum/extconf.rb +3 -0
  74. data/sample/enum/sample_enum.cpp +3 -17
  75. data/sample/enum/test.rb +2 -2
  76. data/sample/inheritance/animals.cpp +8 -24
  77. data/sample/inheritance/extconf.rb +3 -0
  78. data/sample/inheritance/test.rb +1 -1
  79. data/sample/map/extconf.rb +3 -0
  80. data/sample/map/map.cpp +10 -18
  81. data/sample/map/test.rb +1 -1
  82. data/test/embed_ruby.cpp +34 -0
  83. data/test/embed_ruby.hpp +4 -0
  84. data/test/ext/t1/extconf.rb +3 -0
  85. data/test/ext/t1/t1.cpp +1 -3
  86. data/test/ext/t2/extconf.rb +3 -0
  87. data/test/ext/t2/t2.cpp +1 -1
  88. data/test/extconf.rb +23 -0
  89. data/test/ruby/test_callbacks_sample.rb +28 -0
  90. data/test/ruby/test_multiple_extensions.rb +18 -0
  91. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  92. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  93. data/test/test_Address_Registration_Guard.cpp +25 -11
  94. data/test/test_Array.cpp +131 -74
  95. data/test/test_Attribute.cpp +147 -0
  96. data/test/test_Builtin_Object.cpp +36 -15
  97. data/test/test_Class.cpp +151 -276
  98. data/test/test_Constructor.cpp +10 -9
  99. data/test/test_Data_Object.cpp +135 -193
  100. data/test/test_Data_Type.cpp +323 -252
  101. data/test/test_Director.cpp +56 -42
  102. data/test/test_Enum.cpp +230 -104
  103. data/test/test_Exception.cpp +7 -7
  104. data/test/test_Hash.cpp +33 -31
  105. data/test/test_Identifier.cpp +6 -6
  106. data/test/test_Inheritance.cpp +221 -0
  107. data/test/test_Iterator.cpp +161 -0
  108. data/test/test_Jump_Tag.cpp +1 -1
  109. data/test/test_Keep_Alive.cpp +161 -0
  110. data/test/test_Memory_Management.cpp +4 -5
  111. data/test/test_Module.cpp +169 -111
  112. data/test/test_Object.cpp +51 -19
  113. data/test/test_Ownership.cpp +275 -0
  114. data/test/test_Self.cpp +205 -0
  115. data/test/test_Stl_Optional.cpp +90 -0
  116. data/test/test_Stl_Pair.cpp +144 -0
  117. data/test/test_Stl_SmartPointer.cpp +200 -0
  118. data/test/test_Stl_String.cpp +74 -0
  119. data/test/test_Stl_Vector.cpp +652 -0
  120. data/test/test_String.cpp +3 -3
  121. data/test/test_Struct.cpp +31 -40
  122. data/test/test_Symbol.cpp +3 -3
  123. data/test/test_To_From_Ruby.cpp +283 -218
  124. data/test/test_global_functions.cpp +41 -20
  125. data/test/unittest.cpp +34 -8
  126. data/test/unittest.hpp +0 -4
  127. metadata +120 -136
  128. data/Doxyfile +0 -2268
  129. data/Makefile.am +0 -26
  130. data/Makefile.in +0 -920
  131. data/README.mingw +0 -8
  132. data/aclocal.m4 +0 -1088
  133. data/bootstrap +0 -8
  134. data/check_stdcxx_11.ac +0 -142
  135. data/config.guess +0 -1421
  136. data/config.sub +0 -1807
  137. data/configure +0 -7481
  138. data/configure.ac +0 -55
  139. data/depcomp +0 -791
  140. data/doxygen.ac +0 -314
  141. data/doxygen.am +0 -186
  142. data/extconf.rb +0 -69
  143. data/install-sh +0 -501
  144. data/missing +0 -215
  145. data/post-autoconf.rb +0 -22
  146. data/post-automake.rb +0 -28
  147. data/rice/Address_Registration_Guard.cpp +0 -22
  148. data/rice/Arg_impl.hpp +0 -129
  149. data/rice/Arg_operators.cpp +0 -21
  150. data/rice/Arg_operators.hpp +0 -19
  151. data/rice/Array.hpp +0 -214
  152. data/rice/Array.ipp +0 -256
  153. data/rice/Builtin_Object.hpp +0 -8
  154. data/rice/Builtin_Object.ipp +0 -50
  155. data/rice/Builtin_Object_defn.hpp +0 -50
  156. data/rice/Class.cpp +0 -57
  157. data/rice/Class.hpp +0 -8
  158. data/rice/Class.ipp +0 -6
  159. data/rice/Class_defn.hpp +0 -83
  160. data/rice/Data_Type.cpp +0 -54
  161. data/rice/Data_Type_fwd.hpp +0 -12
  162. data/rice/Director.cpp +0 -13
  163. data/rice/Exception.cpp +0 -59
  164. data/rice/Exception_Base.hpp +0 -8
  165. data/rice/Exception_Base.ipp +0 -13
  166. data/rice/Exception_Base_defn.hpp +0 -27
  167. data/rice/Hash.hpp +0 -227
  168. data/rice/Hash.ipp +0 -329
  169. data/rice/Identifier.cpp +0 -8
  170. data/rice/Jump_Tag.hpp +0 -24
  171. data/rice/Makefile.am +0 -124
  172. data/rice/Makefile.in +0 -839
  173. data/rice/Module.cpp +0 -84
  174. data/rice/Module.hpp +0 -8
  175. data/rice/Module.ipp +0 -6
  176. data/rice/Module_defn.hpp +0 -88
  177. data/rice/Module_impl.hpp +0 -281
  178. data/rice/Module_impl.ipp +0 -345
  179. data/rice/Object.cpp +0 -169
  180. data/rice/Object.hpp +0 -8
  181. data/rice/Object.ipp +0 -19
  182. data/rice/Object_defn.hpp +0 -191
  183. data/rice/Require_Guard.hpp +0 -21
  184. data/rice/String.cpp +0 -94
  185. data/rice/String.hpp +0 -91
  186. data/rice/Struct.cpp +0 -117
  187. data/rice/Struct.hpp +0 -162
  188. data/rice/Struct.ipp +0 -26
  189. data/rice/Symbol.cpp +0 -25
  190. data/rice/Symbol.hpp +0 -66
  191. data/rice/Symbol.ipp +0 -44
  192. data/rice/config.hpp +0 -47
  193. data/rice/config.hpp.in +0 -46
  194. data/rice/detail/Arguments.hpp +0 -118
  195. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  196. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
  197. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  198. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
  199. data/rice/detail/Caster.hpp +0 -103
  200. data/rice/detail/Not_Copyable.hpp +0 -25
  201. data/rice/detail/Wrapped_Function.hpp +0 -33
  202. data/rice/detail/cfp.hpp +0 -24
  203. data/rice/detail/cfp.ipp +0 -51
  204. data/rice/detail/check_ruby_type.cpp +0 -27
  205. data/rice/detail/check_ruby_type.hpp +0 -23
  206. data/rice/detail/creation_funcs.hpp +0 -37
  207. data/rice/detail/creation_funcs.ipp +0 -36
  208. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  209. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  210. data/rice/detail/demangle.cpp +0 -56
  211. data/rice/detail/demangle.hpp +0 -19
  212. data/rice/detail/env.hpp +0 -11
  213. data/rice/detail/method_data.cpp +0 -86
  214. data/rice/detail/node.hpp +0 -13
  215. data/rice/detail/object_call.hpp +0 -69
  216. data/rice/detail/object_call.ipp +0 -131
  217. data/rice/detail/protect.cpp +0 -29
  218. data/rice/detail/protect.hpp +0 -34
  219. data/rice/detail/ruby_version_code.hpp +0 -6
  220. data/rice/detail/ruby_version_code.hpp.in +0 -6
  221. data/rice/detail/st.hpp +0 -22
  222. data/rice/detail/traits.hpp +0 -43
  223. data/rice/detail/win32.hpp +0 -16
  224. data/rice/detail/wrap_function.hpp +0 -341
  225. data/rice/detail/wrap_function.ipp +0 -514
  226. data/rice/protect.hpp +0 -92
  227. data/rice/protect.ipp +0 -1134
  228. data/rice/rubypp.rb +0 -97
  229. data/rice/to_from_ruby.hpp +0 -8
  230. data/rice/to_from_ruby.ipp +0 -294
  231. data/rice/to_from_ruby_defn.hpp +0 -70
  232. data/ruby.ac +0 -135
  233. data/ruby/Makefile.am +0 -1
  234. data/ruby/Makefile.in +0 -625
  235. data/ruby/lib/Makefile.am +0 -3
  236. data/ruby/lib/Makefile.in +0 -503
  237. data/ruby/lib/mkmf-rice.rb.in +0 -217
  238. data/ruby/lib/version.rb +0 -3
  239. data/sample/Makefile.am +0 -47
  240. data/sample/Makefile.in +0 -486
  241. data/test/Makefile.am +0 -72
  242. data/test/Makefile.in +0 -1150
  243. data/test/ext/Makefile.am +0 -41
  244. data/test/ext/Makefile.in +0 -480
  245. data/test/test_rice.rb +0 -41
@@ -0,0 +1,90 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <rice/stl.hpp>
5
+
6
+ #include <optional>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Optional);
11
+
12
+ namespace
13
+ {
14
+ class MyClass
15
+ {
16
+ public:
17
+ std::optional<std::string> optionalReturn(bool flag)
18
+ {
19
+ if (flag)
20
+ {
21
+ return std::string("Here is a value");
22
+ }
23
+ else
24
+ {
25
+ return std::nullopt;
26
+ }
27
+ }
28
+
29
+ int optionalArgument(std::optional<int32_t> data)
30
+ {
31
+ return data ? data.value() : 7;
32
+ }
33
+
34
+ std::optional<double> optional_ = std::nullopt;
35
+ };
36
+ }
37
+
38
+ Class makeOptionalClass()
39
+ {
40
+ return define_class<MyClass>("MyClass").
41
+ define_constructor(Constructor<MyClass>()).
42
+ define_method("optional_return", &MyClass::optionalReturn).
43
+ define_method("optional_argument", &MyClass::optionalArgument).
44
+ define_attr("optional_attr", &MyClass::optional_);
45
+ }
46
+
47
+ SETUP(Optional)
48
+ {
49
+ embed_ruby();
50
+ makeOptionalClass();
51
+ }
52
+
53
+ TESTCASE(OptionalReturn)
54
+ {
55
+ Module m = define_module("Testing");
56
+ Object myClass = m.instance_eval("MyClass.new");
57
+
58
+ Object result = myClass.call("optional_return", true);
59
+ ASSERT_EQUAL("Here is a value", detail::From_Ruby<std::string>().convert(result));
60
+
61
+ result = myClass.call("optional_return", false);
62
+ ASSERT_EQUAL(Qnil, result.value());
63
+ }
64
+
65
+ TESTCASE(OptionalArgument)
66
+ {
67
+ Module m = define_module("Testing");
68
+ Object myClass = m.instance_eval("MyClass.new");
69
+
70
+ Object result = myClass.call("optional_argument", 77);
71
+ ASSERT_EQUAL(77, detail::From_Ruby<int32_t>().convert(result));
72
+
73
+ result = myClass.call("optional_argument", std::nullopt);
74
+ ASSERT_EQUAL(7, detail::From_Ruby<int32_t>().convert(result));
75
+ }
76
+
77
+ TESTCASE(OptionalAttribute)
78
+ {
79
+ Module m = define_module("Testing");
80
+ Object myClass = m.instance_eval("MyClass.new");
81
+
82
+ Object result = myClass.call("optional_attr");
83
+ ASSERT_EQUAL(Qnil, result.value());
84
+
85
+ result = myClass.call("optional_attr=", 77.7);
86
+ ASSERT_EQUAL(77.7, detail::From_Ruby<double>().convert(result));
87
+
88
+ result = myClass.call("optional_attr=", std::nullopt);
89
+ ASSERT_EQUAL(Qnil, result.value());
90
+ }
@@ -0,0 +1,144 @@
1
+ #include <utility>
2
+
3
+ #include "unittest.hpp"
4
+ #include "embed_ruby.hpp"
5
+ #include <rice/rice.hpp>
6
+ #include <rice/stl.hpp>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Pair);
11
+
12
+ SETUP(Pair)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ TESTCASE(CreatePair)
18
+ {
19
+ Module m = define_module("Testing");
20
+
21
+ Class c = define_pair<std::pair<int32_t, std::optional<std::string>>>("IntStringPair");
22
+
23
+ Object pair = c.call("new", 0, nullptr);
24
+
25
+ Object result = pair.call("first");
26
+ ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
27
+
28
+ result = pair.call("second");
29
+ ASSERT_EQUAL(Qnil, result.value());
30
+
31
+ result = pair.call("first=", 77);
32
+ ASSERT_EQUAL(77, detail::From_Ruby<int32_t>().convert(result));
33
+
34
+ result = pair.call("first");
35
+ ASSERT_EQUAL(77, detail::From_Ruby<int32_t>().convert(result));
36
+
37
+ result = pair.call("second=", "A second value");
38
+ ASSERT_EQUAL("A second value", detail::From_Ruby<std::string>().convert(result));
39
+
40
+ result = pair.call("second");
41
+ ASSERT_EQUAL("A second value", detail::From_Ruby<std::string>().convert(result));
42
+ }
43
+
44
+ namespace
45
+ {
46
+ class SomeClass
47
+ {
48
+ public:
49
+ std::pair<std::string, double> pair()
50
+ {
51
+ return pair_;
52
+ }
53
+
54
+ std::pair<std::string, double> setPair(std::pair<std::string, double> value)
55
+ {
56
+ pair_ = value;
57
+ return pair_;
58
+ }
59
+
60
+ std::pair<std::string, double> pair_{ "first value", 2.0 };
61
+ };
62
+ }
63
+
64
+ // This test passes everywhere except for Ruby 2.7 on Windows
65
+ // and I don't know why. Throws a "bad any_cast" from MethodData::data
66
+ #ifndef _WIN32
67
+ TESTCASE(AutoRegister)
68
+ {
69
+ Module m = define_module("Testing");
70
+
71
+ Class c = define_class<SomeClass>("SomeClass").
72
+ define_constructor(Constructor<SomeClass>()).
73
+ define_method("pair", &SomeClass::pair).
74
+ define_method("pair=", &SomeClass::setPair);
75
+
76
+ Object someClass = c.call("new");
77
+
78
+ Object pair = someClass.call("pair");
79
+ String name = pair.class_name();
80
+ ASSERT_EQUAL("Rice::Std::Pair__basic_string__char_char_traits__char___allocator__char_____double__", detail::From_Ruby<std::string>().convert(name));
81
+
82
+ Class pairKlass1 = pair.class_of();
83
+ Class pairKlass2 = Data_Type<std::pair<std::string, double>>::klass();
84
+ ASSERT_EQUAL(pairKlass1, pairKlass2);
85
+
86
+ Object result = pair.call("first");
87
+ ASSERT_EQUAL("first value", detail::From_Ruby<std::string>().convert(result));
88
+
89
+ result = pair.call("second");
90
+ ASSERT_EQUAL(2.0, detail::From_Ruby<float>().convert(result));
91
+
92
+ Object newPair = pairKlass1.call("new", "New value", 3.2);
93
+
94
+ pair = someClass.call("pair=", newPair);
95
+
96
+ result = newPair.call("first");
97
+ ASSERT_EQUAL("New value", detail::From_Ruby<std::string>().convert(result));
98
+
99
+ result = newPair.call("second");
100
+ ASSERT_EQUAL(3.2, detail::From_Ruby<double>().convert(result));
101
+ }
102
+ #endif
103
+
104
+ namespace
105
+ {
106
+ struct SomeStruct
107
+ {
108
+ int32_t value = 5;
109
+ };
110
+ }
111
+
112
+ TESTCASE(ReferenceReturned)
113
+ {
114
+ Class structKlass = define_class<SomeStruct>("SomeStruct").
115
+ define_constructor(Constructor<SomeStruct>()).
116
+ define_attr("value", &SomeStruct::value);
117
+
118
+ define_pair<std::pair<char, SomeStruct>>("CharSomeStructPair");
119
+
120
+ std::pair<char, SomeStruct> aPair;
121
+ aPair.first = 'a';
122
+
123
+ Data_Object<std::pair<char, SomeStruct>> rubyPair(&aPair);
124
+
125
+ Object result = rubyPair.call("first");
126
+ ASSERT_EQUAL('a', detail::From_Ruby<char>().convert(result));
127
+
128
+ result = rubyPair.call("first=", 'b');
129
+ ASSERT_EQUAL('b', aPair.first);
130
+
131
+ result = rubyPair.call("first");
132
+ ASSERT_EQUAL('b', detail::From_Ruby<char>().convert(result));
133
+
134
+ Object rubyStruct = rubyPair.call("second");
135
+ result = rubyStruct.call("value");
136
+ ASSERT_EQUAL(5, detail::From_Ruby<int32_t>().convert(result));
137
+
138
+ rubyStruct.call("value=", 8);
139
+ ASSERT_EQUAL(8, aPair.second.value);
140
+
141
+ rubyStruct = rubyPair.call("second");
142
+ result = rubyStruct.call("value");
143
+ ASSERT_EQUAL(8, detail::From_Ruby<int32_t>().convert(result));
144
+ }
@@ -0,0 +1,200 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <rice/stl.hpp>
5
+
6
+ #include <memory>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(SmartPointer);
11
+
12
+ namespace
13
+ {
14
+ class MyClass
15
+ {
16
+ public:
17
+ static inline int32_t constructorCalls = 0;
18
+ static inline int32_t copyConstructorCalls = 0;
19
+ static inline int32_t moveConstructorCalls = 0;
20
+ static inline int32_t destructorCalls = 0;
21
+
22
+ static void reset()
23
+ {
24
+ constructorCalls = 0;
25
+ copyConstructorCalls = 0;
26
+ moveConstructorCalls = 0;
27
+ destructorCalls = 0;
28
+ }
29
+
30
+ public:
31
+ int flag = 0;
32
+
33
+ public:
34
+ MyClass()
35
+ {
36
+ constructorCalls++;
37
+ }
38
+
39
+ ~MyClass()
40
+ {
41
+ destructorCalls++;
42
+ }
43
+
44
+ MyClass(const MyClass& other): flag(other.flag)
45
+ {
46
+ copyConstructorCalls++;
47
+ }
48
+
49
+ MyClass(MyClass&& other) : flag(other.flag)
50
+ {
51
+ moveConstructorCalls++;
52
+ }
53
+
54
+ void setFlag(int value)
55
+ {
56
+ this->flag = value;
57
+ }
58
+ };
59
+
60
+ class Factory
61
+ {
62
+ public:
63
+ std::unique_ptr<MyClass> transfer()
64
+ {
65
+ return std::make_unique<MyClass>();
66
+ }
67
+
68
+ std::shared_ptr<MyClass> share()
69
+ {
70
+ if (!instance_)
71
+ {
72
+ instance_ = std::make_shared<MyClass>();
73
+ }
74
+ return instance_;
75
+ }
76
+
77
+ public:
78
+ static inline std::shared_ptr<MyClass> instance_;
79
+ };
80
+
81
+ int extractFlagUniquePtrRef(std::unique_ptr<MyClass>& myClass)
82
+ {
83
+ return myClass->flag;
84
+ }
85
+
86
+ int extractFlagSharedPtr(std::shared_ptr<MyClass> myClass)
87
+ {
88
+ return myClass->flag;
89
+ }
90
+
91
+ int extractFlagSharedPtrRef(std::shared_ptr<MyClass>& myClass)
92
+ {
93
+ return myClass->flag;
94
+ }
95
+ }
96
+
97
+ SETUP(SmartPointer)
98
+ {
99
+ embed_ruby();
100
+
101
+ define_class<MyClass>("MyClass").
102
+ define_method("set_flag", &MyClass::setFlag);
103
+
104
+ define_class<Factory>("Factory").
105
+ define_constructor(Constructor<Factory>()).
106
+ define_method("transfer", &Factory::transfer).
107
+ define_method("share", &Factory::share);
108
+
109
+ define_global_function("extract_flag_unique_ptr_ref", &extractFlagUniquePtrRef);
110
+ define_global_function("extract_flag_shared_ptr", &extractFlagSharedPtr);
111
+ define_global_function("extract_flag_shared_ptr_ref", &extractFlagSharedPtrRef);
112
+ }
113
+
114
+ TESTCASE(TransferOwnership)
115
+ {
116
+ MyClass::reset();
117
+
118
+ Module m = define_module("TestingModule");
119
+
120
+ std::string code = R"(factory = Factory.new
121
+ 10.times do |i|
122
+ my_class = factory.transfer
123
+ my_class.set_flag(i)
124
+ my_class = nil
125
+ end)";
126
+
127
+ m.instance_eval(code);
128
+ rb_gc_start();
129
+
130
+ ASSERT_EQUAL(10, MyClass::constructorCalls);
131
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
132
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
133
+ ASSERT_EQUAL(10, MyClass::destructorCalls);
134
+ ASSERT(!Factory::instance_);
135
+ }
136
+
137
+ TESTCASE(ShareOwnership)
138
+ {
139
+ MyClass::reset();
140
+
141
+ Module m = define_module("TestingModule");
142
+
143
+ // Create ruby objects that point to the same instance of MyClass
144
+ std::string code = R"(factory = Factory.new
145
+ 10.times do |i|
146
+ my_class = factory.share
147
+ my_class.set_flag(i)
148
+ end)";
149
+
150
+ m.instance_eval(code);
151
+ rb_gc_start();
152
+
153
+ ASSERT_EQUAL(1, MyClass::constructorCalls);
154
+ ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
155
+ ASSERT_EQUAL(0, MyClass::moveConstructorCalls);
156
+ ASSERT_EQUAL(0, MyClass::destructorCalls);
157
+ ASSERT_EQUAL(9, Factory::instance_->flag);
158
+ }
159
+
160
+ TESTCASE(UniquePtrRefParameter)
161
+ {
162
+ MyClass::reset();
163
+
164
+ Module m = define_module("TestingModule");
165
+
166
+ std::string code = R"(factory = Factory.new
167
+ my_class = factory.transfer
168
+ my_class.set_flag(7)
169
+ extract_flag_unique_ptr_ref(my_class))";
170
+
171
+ Object result = m.instance_eval(code);
172
+ }
173
+
174
+ TESTCASE(SharedPtrParameter)
175
+ {
176
+ MyClass::reset();
177
+
178
+ Module m = define_module("TestingModule");
179
+
180
+ std::string code = R"(factory = Factory.new
181
+ my_class = factory.share
182
+ my_class.set_flag(7)
183
+ extract_flag_shared_ptr(my_class))";
184
+
185
+ Object result = m.instance_eval(code);
186
+ }
187
+
188
+ TESTCASE(SharedPtrRefParameter)
189
+ {
190
+ MyClass::reset();
191
+
192
+ Module m = define_module("TestingModule");
193
+
194
+ std::string code = R"(factory = Factory.new
195
+ my_class = factory.share
196
+ my_class.set_flag(7)
197
+ extract_flag_shared_ptr_ref(my_class))";
198
+
199
+ Object result = m.instance_eval(code);
200
+ }
@@ -0,0 +1,74 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <ruby/encoding.h>
5
+ #include <rice/stl.hpp>
6
+
7
+ #include <optional>
8
+
9
+ using namespace Rice;
10
+
11
+ TESTSUITE(StlString);
12
+
13
+ SETUP(StlString)
14
+ {
15
+ embed_ruby();
16
+ }
17
+
18
+ TESTCASE(std_string_to_ruby)
19
+ {
20
+ ASSERT(rb_equal(String("").value(), detail::to_ruby(std::string(""))));
21
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby(std::string("foo"))));
22
+ }
23
+
24
+ TESTCASE(std_string_to_ruby_encoding)
25
+ {
26
+ VALUE value = detail::to_ruby(std::string("Some String"));
27
+ Object object(value);
28
+ Object encoding = object.call("encoding");
29
+ Object encodingName = encoding.call("name");
30
+ ASSERT_EQUAL("ASCII-8BIT", detail::From_Ruby<std::string>().convert(encodingName));
31
+ }
32
+
33
+ TESTCASE(std_string_to_ruby_encoding_utf8)
34
+ {
35
+ rb_encoding* defaultEncoding = rb_default_external_encoding();
36
+
37
+ VALUE utf8Encoding = rb_enc_from_encoding(rb_utf8_encoding());
38
+ rb_enc_set_default_external(utf8Encoding);
39
+
40
+ VALUE value = detail::to_ruby(std::string("Some String"));
41
+ Object object(value);
42
+ Object encoding = object.call("encoding");
43
+ Object encodingName = encoding.call("name");
44
+ ASSERT_EQUAL("UTF-8", detail::From_Ruby<std::string>().convert(encodingName));
45
+
46
+ rb_enc_set_default_external(rb_enc_from_encoding(defaultEncoding));
47
+ }
48
+
49
+ TESTCASE(std_string_from_ruby)
50
+ {
51
+ ASSERT_EQUAL(std::string(""), detail::From_Ruby<std::string>().convert(rb_str_new2("")));
52
+ ASSERT_EQUAL(std::string("foo"), detail::From_Ruby<std::string>().convert(rb_str_new2("foo")));
53
+
54
+ ASSERT_EXCEPTION_CHECK(
55
+ Exception,
56
+ detail::From_Ruby<std::string>().convert(rb_float_new(15.512)),
57
+ ASSERT_EQUAL("wrong argument type Float (expected String)", ex.what())
58
+ );
59
+ }
60
+
61
+ TESTCASE(std_string_to_ruby_with_binary)
62
+ {
63
+ Rice::String got = detail::to_ruby(std::string("\000test", 5));
64
+
65
+ ASSERT_EQUAL(String(std::string("\000test", 5)), got);
66
+ ASSERT_EQUAL(5ul, got.length());
67
+ }
68
+
69
+ TESTCASE(std_string_from_ruby_with_binary)
70
+ {
71
+ std::string got = detail::From_Ruby<std::string>().convert(rb_str_new("\000test", 5));
72
+ ASSERT_EQUAL(5ul, got.length());
73
+ ASSERT_EQUAL(std::string("\000test", 5), got);
74
+ }