rice 2.1.1 → 4.0.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 (246) 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 +69 -0
  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 -274
  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 +117 -137
  128. data/Doxyfile +0 -2280
  129. data/Makefile.am +0 -26
  130. data/Makefile.in +0 -920
  131. data/README +0 -1055
  132. data/README.mingw +0 -8
  133. data/aclocal.m4 +0 -1088
  134. data/bootstrap +0 -8
  135. data/check_stdcxx_11.ac +0 -142
  136. data/config.guess +0 -1421
  137. data/config.sub +0 -1807
  138. data/configure +0 -7481
  139. data/configure.ac +0 -55
  140. data/depcomp +0 -791
  141. data/doxygen.ac +0 -314
  142. data/doxygen.am +0 -186
  143. data/extconf.rb +0 -69
  144. data/install-sh +0 -501
  145. data/missing +0 -215
  146. data/post-autoconf.rb +0 -22
  147. data/post-automake.rb +0 -28
  148. data/rice/Address_Registration_Guard.cpp +0 -22
  149. data/rice/Arg_impl.hpp +0 -129
  150. data/rice/Arg_operators.cpp +0 -21
  151. data/rice/Arg_operators.hpp +0 -19
  152. data/rice/Array.hpp +0 -214
  153. data/rice/Array.ipp +0 -256
  154. data/rice/Builtin_Object.hpp +0 -8
  155. data/rice/Builtin_Object.ipp +0 -50
  156. data/rice/Builtin_Object_defn.hpp +0 -50
  157. data/rice/Class.cpp +0 -57
  158. data/rice/Class.hpp +0 -8
  159. data/rice/Class.ipp +0 -6
  160. data/rice/Class_defn.hpp +0 -83
  161. data/rice/Data_Type.cpp +0 -54
  162. data/rice/Data_Type_fwd.hpp +0 -12
  163. data/rice/Director.cpp +0 -13
  164. data/rice/Exception.cpp +0 -59
  165. data/rice/Exception_Base.hpp +0 -8
  166. data/rice/Exception_Base.ipp +0 -13
  167. data/rice/Exception_Base_defn.hpp +0 -27
  168. data/rice/Hash.hpp +0 -227
  169. data/rice/Hash.ipp +0 -329
  170. data/rice/Identifier.cpp +0 -8
  171. data/rice/Jump_Tag.hpp +0 -24
  172. data/rice/Makefile.am +0 -124
  173. data/rice/Makefile.in +0 -839
  174. data/rice/Module.cpp +0 -84
  175. data/rice/Module.hpp +0 -8
  176. data/rice/Module.ipp +0 -6
  177. data/rice/Module_defn.hpp +0 -88
  178. data/rice/Module_impl.hpp +0 -281
  179. data/rice/Module_impl.ipp +0 -345
  180. data/rice/Object.cpp +0 -169
  181. data/rice/Object.hpp +0 -8
  182. data/rice/Object.ipp +0 -19
  183. data/rice/Object_defn.hpp +0 -191
  184. data/rice/Require_Guard.hpp +0 -21
  185. data/rice/String.cpp +0 -94
  186. data/rice/String.hpp +0 -91
  187. data/rice/Struct.cpp +0 -117
  188. data/rice/Struct.hpp +0 -162
  189. data/rice/Struct.ipp +0 -26
  190. data/rice/Symbol.cpp +0 -25
  191. data/rice/Symbol.hpp +0 -66
  192. data/rice/Symbol.ipp +0 -44
  193. data/rice/config.hpp +0 -47
  194. data/rice/config.hpp.in +0 -46
  195. data/rice/detail/Arguments.hpp +0 -118
  196. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  197. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
  198. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  199. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
  200. data/rice/detail/Caster.hpp +0 -103
  201. data/rice/detail/Not_Copyable.hpp +0 -25
  202. data/rice/detail/Wrapped_Function.hpp +0 -33
  203. data/rice/detail/cfp.hpp +0 -24
  204. data/rice/detail/cfp.ipp +0 -51
  205. data/rice/detail/check_ruby_type.cpp +0 -27
  206. data/rice/detail/check_ruby_type.hpp +0 -23
  207. data/rice/detail/creation_funcs.hpp +0 -37
  208. data/rice/detail/creation_funcs.ipp +0 -36
  209. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  210. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  211. data/rice/detail/demangle.cpp +0 -56
  212. data/rice/detail/demangle.hpp +0 -19
  213. data/rice/detail/env.hpp +0 -11
  214. data/rice/detail/method_data.cpp +0 -86
  215. data/rice/detail/node.hpp +0 -13
  216. data/rice/detail/object_call.hpp +0 -69
  217. data/rice/detail/object_call.ipp +0 -131
  218. data/rice/detail/protect.cpp +0 -29
  219. data/rice/detail/protect.hpp +0 -34
  220. data/rice/detail/ruby_version_code.hpp +0 -6
  221. data/rice/detail/ruby_version_code.hpp.in +0 -6
  222. data/rice/detail/st.hpp +0 -22
  223. data/rice/detail/traits.hpp +0 -43
  224. data/rice/detail/win32.hpp +0 -16
  225. data/rice/detail/wrap_function.hpp +0 -341
  226. data/rice/detail/wrap_function.ipp +0 -514
  227. data/rice/protect.hpp +0 -92
  228. data/rice/protect.ipp +0 -1134
  229. data/rice/rubypp.rb +0 -97
  230. data/rice/to_from_ruby.hpp +0 -8
  231. data/rice/to_from_ruby.ipp +0 -294
  232. data/rice/to_from_ruby_defn.hpp +0 -70
  233. data/ruby.ac +0 -135
  234. data/ruby/Makefile.am +0 -1
  235. data/ruby/Makefile.in +0 -625
  236. data/ruby/lib/Makefile.am +0 -3
  237. data/ruby/lib/Makefile.in +0 -503
  238. data/ruby/lib/mkmf-rice.rb.in +0 -217
  239. data/ruby/lib/version.rb +0 -3
  240. data/sample/Makefile.am +0 -47
  241. data/sample/Makefile.in +0 -486
  242. data/test/Makefile.am +0 -72
  243. data/test/Makefile.in +0 -1150
  244. data/test/ext/Makefile.am +0 -41
  245. data/test/ext/Makefile.in +0 -480
  246. 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
+ }