rice 3.0.0 → 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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/Gemfile +3 -0
  5. data/README.md +44 -1025
  6. data/Rakefile +95 -12
  7. data/include/rice/rice.hpp +7766 -0
  8. data/lib/mkmf-rice.rb +127 -0
  9. data/lib/version.rb +3 -0
  10. data/rice/Address_Registration_Guard.ipp +75 -32
  11. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  12. data/rice/Arg.hpp +80 -4
  13. data/rice/Arg.ipp +51 -0
  14. data/rice/Constructor.hpp +12 -14
  15. data/rice/Data_Object.ipp +234 -107
  16. data/rice/Data_Object_defn.hpp +77 -117
  17. data/rice/Data_Type.hpp +1 -2
  18. data/rice/Data_Type.ipp +251 -295
  19. data/rice/Data_Type_defn.hpp +175 -243
  20. data/rice/Director.hpp +11 -6
  21. data/rice/Enum.hpp +54 -104
  22. data/rice/Enum.ipp +104 -230
  23. data/rice/Exception.hpp +2 -8
  24. data/rice/Exception.ipp +65 -0
  25. data/rice/Exception_defn.hpp +46 -47
  26. data/rice/Identifier.hpp +28 -28
  27. data/rice/Identifier.ipp +23 -27
  28. data/rice/Return.hpp +39 -0
  29. data/rice/Return.ipp +33 -0
  30. data/rice/detail/Exception_Handler.ipp +22 -62
  31. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  32. data/rice/detail/Iterator.hpp +18 -88
  33. data/rice/detail/Iterator.ipp +47 -0
  34. data/rice/detail/Jump_Tag.hpp +21 -0
  35. data/rice/detail/MethodInfo.hpp +44 -0
  36. data/rice/detail/MethodInfo.ipp +78 -0
  37. data/rice/detail/NativeAttribute.hpp +53 -0
  38. data/rice/detail/NativeAttribute.ipp +83 -0
  39. data/rice/detail/NativeFunction.hpp +69 -0
  40. data/rice/detail/NativeFunction.ipp +248 -0
  41. data/rice/detail/RubyFunction.hpp +39 -0
  42. data/rice/detail/RubyFunction.ipp +92 -0
  43. data/rice/detail/Type.hpp +29 -0
  44. data/rice/detail/Type.ipp +138 -0
  45. data/rice/detail/TypeRegistry.hpp +50 -0
  46. data/rice/detail/TypeRegistry.ipp +106 -0
  47. data/rice/detail/Wrapper.hpp +51 -0
  48. data/rice/detail/Wrapper.ipp +151 -0
  49. data/rice/detail/default_allocation_func.hpp +8 -19
  50. data/rice/detail/default_allocation_func.ipp +9 -8
  51. data/rice/detail/from_ruby.hpp +2 -37
  52. data/rice/detail/from_ruby.ipp +1020 -46
  53. data/rice/detail/from_ruby_defn.hpp +38 -0
  54. data/rice/detail/function_traits.hpp +124 -0
  55. data/rice/detail/method_data.hpp +23 -15
  56. data/rice/detail/method_data.ipp +53 -0
  57. data/rice/detail/rice_traits.hpp +116 -0
  58. data/rice/detail/ruby.hpp +9 -46
  59. data/rice/detail/to_ruby.hpp +3 -17
  60. data/rice/detail/to_ruby.ipp +409 -31
  61. data/rice/detail/to_ruby_defn.hpp +48 -0
  62. data/rice/forward_declares.ipp +82 -0
  63. data/rice/global_function.hpp +16 -20
  64. data/rice/global_function.ipp +8 -17
  65. data/rice/rice.hpp +59 -0
  66. data/rice/ruby_mark.hpp +5 -3
  67. data/rice/ruby_try_catch.hpp +4 -4
  68. data/rice/stl.hpp +11 -0
  69. data/sample/callbacks/extconf.rb +3 -0
  70. data/sample/callbacks/sample_callbacks.cpp +10 -13
  71. data/sample/enum/extconf.rb +3 -0
  72. data/sample/enum/sample_enum.cpp +3 -17
  73. data/sample/enum/test.rb +2 -2
  74. data/sample/inheritance/animals.cpp +8 -24
  75. data/sample/inheritance/extconf.rb +3 -0
  76. data/sample/inheritance/test.rb +1 -1
  77. data/sample/map/extconf.rb +3 -0
  78. data/sample/map/map.cpp +10 -18
  79. data/sample/map/test.rb +1 -1
  80. data/test/embed_ruby.cpp +18 -5
  81. data/test/ext/t1/extconf.rb +3 -0
  82. data/test/ext/t1/t1.cpp +1 -3
  83. data/test/ext/t2/extconf.rb +3 -0
  84. data/test/ext/t2/t2.cpp +1 -1
  85. data/test/extconf.rb +23 -0
  86. data/test/ruby/test_callbacks_sample.rb +28 -0
  87. data/test/ruby/test_multiple_extensions.rb +18 -0
  88. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  89. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  90. data/test/test_Address_Registration_Guard.cpp +23 -10
  91. data/test/test_Array.cpp +129 -73
  92. data/test/test_Attribute.cpp +147 -0
  93. data/test/test_Builtin_Object.cpp +34 -14
  94. data/test/test_Class.cpp +149 -275
  95. data/test/test_Constructor.cpp +10 -9
  96. data/test/test_Data_Object.cpp +133 -192
  97. data/test/test_Data_Type.cpp +322 -252
  98. data/test/test_Director.cpp +54 -41
  99. data/test/test_Enum.cpp +228 -103
  100. data/test/test_Exception.cpp +5 -6
  101. data/test/test_Hash.cpp +31 -30
  102. data/test/test_Identifier.cpp +4 -5
  103. data/test/test_Inheritance.cpp +221 -0
  104. data/test/test_Iterator.cpp +161 -0
  105. data/test/test_Jump_Tag.cpp +1 -1
  106. data/test/test_Keep_Alive.cpp +161 -0
  107. data/test/test_Memory_Management.cpp +2 -4
  108. data/test/test_Module.cpp +167 -110
  109. data/test/test_Object.cpp +41 -21
  110. data/test/test_Ownership.cpp +275 -0
  111. data/test/test_Self.cpp +205 -0
  112. data/test/test_Stl_Optional.cpp +90 -0
  113. data/test/test_Stl_Pair.cpp +144 -0
  114. data/test/test_Stl_SmartPointer.cpp +200 -0
  115. data/test/test_Stl_String.cpp +74 -0
  116. data/test/test_Stl_Vector.cpp +652 -0
  117. data/test/test_String.cpp +1 -2
  118. data/test/test_Struct.cpp +29 -39
  119. data/test/test_Symbol.cpp +1 -2
  120. data/test/test_To_From_Ruby.cpp +249 -285
  121. data/test/test_global_functions.cpp +39 -19
  122. data/test/unittest.hpp +0 -4
  123. metadata +63 -139
  124. data/Doxyfile +0 -2268
  125. data/Makefile.am +0 -26
  126. data/Makefile.in +0 -931
  127. data/README.mingw +0 -8
  128. data/aclocal.m4 +0 -1085
  129. data/ax_cxx_compile_stdcxx.m4 +0 -951
  130. data/bootstrap +0 -8
  131. data/config.guess +0 -1421
  132. data/config.sub +0 -1807
  133. data/configure +0 -7792
  134. data/configure.ac +0 -55
  135. data/depcomp +0 -791
  136. data/doxygen.ac +0 -314
  137. data/doxygen.am +0 -186
  138. data/extconf.rb +0 -70
  139. data/install-sh +0 -501
  140. data/missing +0 -215
  141. data/post-autoconf.rb +0 -22
  142. data/post-automake.rb +0 -28
  143. data/rice/Address_Registration_Guard.cpp +0 -22
  144. data/rice/Arg_impl.hpp +0 -129
  145. data/rice/Arg_operators.cpp +0 -21
  146. data/rice/Arg_operators.hpp +0 -19
  147. data/rice/Array.hpp +0 -214
  148. data/rice/Array.ipp +0 -256
  149. data/rice/Builtin_Object.hpp +0 -8
  150. data/rice/Builtin_Object.ipp +0 -50
  151. data/rice/Builtin_Object_defn.hpp +0 -50
  152. data/rice/Class.cpp +0 -57
  153. data/rice/Class.hpp +0 -8
  154. data/rice/Class.ipp +0 -6
  155. data/rice/Class_defn.hpp +0 -84
  156. data/rice/Data_Type.cpp +0 -54
  157. data/rice/Data_Type_fwd.hpp +0 -12
  158. data/rice/Director.cpp +0 -13
  159. data/rice/Exception.cpp +0 -54
  160. data/rice/Exception_Base.hpp +0 -8
  161. data/rice/Exception_Base.ipp +0 -13
  162. data/rice/Exception_Base_defn.hpp +0 -27
  163. data/rice/Hash.hpp +0 -230
  164. data/rice/Hash.ipp +0 -329
  165. data/rice/Identifier.cpp +0 -8
  166. data/rice/Jump_Tag.hpp +0 -24
  167. data/rice/Makefile.am +0 -121
  168. data/rice/Makefile.in +0 -884
  169. data/rice/Module.cpp +0 -84
  170. data/rice/Module.hpp +0 -8
  171. data/rice/Module.ipp +0 -6
  172. data/rice/Module_defn.hpp +0 -88
  173. data/rice/Module_impl.hpp +0 -281
  174. data/rice/Module_impl.ipp +0 -345
  175. data/rice/Object.cpp +0 -169
  176. data/rice/Object.hpp +0 -8
  177. data/rice/Object.ipp +0 -33
  178. data/rice/Object_defn.hpp +0 -214
  179. data/rice/Require_Guard.hpp +0 -21
  180. data/rice/String.cpp +0 -89
  181. data/rice/String.hpp +0 -91
  182. data/rice/Struct.cpp +0 -117
  183. data/rice/Struct.hpp +0 -162
  184. data/rice/Struct.ipp +0 -26
  185. data/rice/Symbol.cpp +0 -25
  186. data/rice/Symbol.hpp +0 -66
  187. data/rice/Symbol.ipp +0 -44
  188. data/rice/config.hpp +0 -47
  189. data/rice/config.hpp.in +0 -46
  190. data/rice/detail/Arguments.hpp +0 -118
  191. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  192. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3181
  193. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  194. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2501
  195. data/rice/detail/Caster.hpp +0 -103
  196. data/rice/detail/Not_Copyable.hpp +0 -25
  197. data/rice/detail/Wrapped_Function.hpp +0 -33
  198. data/rice/detail/cfp.hpp +0 -24
  199. data/rice/detail/cfp.ipp +0 -51
  200. data/rice/detail/check_ruby_type.cpp +0 -27
  201. data/rice/detail/check_ruby_type.hpp +0 -23
  202. data/rice/detail/creation_funcs.hpp +0 -37
  203. data/rice/detail/creation_funcs.ipp +0 -36
  204. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  205. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  206. data/rice/detail/demangle.cpp +0 -56
  207. data/rice/detail/demangle.hpp +0 -19
  208. data/rice/detail/env.hpp +0 -11
  209. data/rice/detail/method_data.cpp +0 -92
  210. data/rice/detail/node.hpp +0 -13
  211. data/rice/detail/protect.cpp +0 -29
  212. data/rice/detail/protect.hpp +0 -34
  213. data/rice/detail/ruby_version_code.hpp +0 -6
  214. data/rice/detail/ruby_version_code.hpp.in +0 -6
  215. data/rice/detail/st.hpp +0 -22
  216. data/rice/detail/win32.hpp +0 -16
  217. data/rice/detail/wrap_function.hpp +0 -66
  218. data/rice/protect.hpp +0 -38
  219. data/rice/protect.ipp +0 -1134
  220. data/rice/rubypp.rb +0 -97
  221. data/rice/to_from_ruby.hpp +0 -8
  222. data/rice/to_from_ruby.ipp +0 -418
  223. data/rice/to_from_ruby_defn.hpp +0 -70
  224. data/ruby.ac +0 -135
  225. data/ruby/Makefile.am +0 -1
  226. data/ruby/Makefile.in +0 -628
  227. data/ruby/lib/Makefile.am +0 -3
  228. data/ruby/lib/Makefile.in +0 -506
  229. data/ruby/lib/mkmf-rice.rb.in +0 -217
  230. data/ruby/lib/version.rb +0 -3
  231. data/sample/Makefile.am +0 -53
  232. data/sample/Makefile.in +0 -495
  233. data/test/Makefile.am +0 -73
  234. data/test/Makefile.in +0 -1219
  235. data/test/ext/Makefile.am +0 -41
  236. data/test/ext/Makefile.in +0 -483
  237. data/test/test_rice.rb +0 -45
@@ -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
+ }