]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright 2016 Klemens Morgenstern |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt | |
5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | // For more information, see http://www.boost.org | |
8 | ||
9 | #include <boost/predef.h> | |
10 | ||
11 | #if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0)) | |
12 | ||
13 | #include "../example/b2_workarounds.hpp" | |
14 | ||
15 | #include <boost/dll/smart_library.hpp> | |
16 | #include <boost/core/lightweight_test.hpp> | |
17 | #include <boost/filesystem.hpp> | |
18 | #include <boost/variant.hpp> | |
19 | ||
20 | #include <iostream> | |
21 | ||
22 | struct override_class | |
23 | { | |
24 | int arr[32]; | |
25 | }; | |
26 | ||
27 | ||
28 | int main(int argc, char* argv[]) | |
29 | { | |
30 | using namespace boost::dll; | |
31 | using namespace boost::dll::experimental; | |
92f5a8d4 | 32 | boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv); |
7c673cae FG |
33 | |
34 | BOOST_TEST(!pt.empty()); | |
35 | std::cout << "Library: " << pt << std::endl; | |
92f5a8d4 | 36 | std::cerr << 1 << ' '; |
7c673cae FG |
37 | smart_library sm(pt); |
38 | ||
39 | auto& unscoped_var = sm.get_variable<int>("unscoped_var"); | |
40 | BOOST_TEST(unscoped_var == 42); | |
92f5a8d4 | 41 | std::cerr << 2 << ' '; |
7c673cae FG |
42 | auto& unscoped_c_var = sm.get_variable<const double>("unscoped_c_var"); |
43 | BOOST_TEST(unscoped_c_var == 1.234); | |
44 | ||
92f5a8d4 | 45 | std::cerr << 3 << ' '; |
7c673cae FG |
46 | auto& sp_variable = sm.get_variable<double>("some_space::variable"); |
47 | BOOST_TEST(sp_variable == 0.2); | |
48 | ||
92f5a8d4 | 49 | std::cerr << 4 << ' '; |
7c673cae FG |
50 | auto scoped_fun = sm.get_function<const int&()>("some_space::scoped_fun"); |
51 | BOOST_TEST(scoped_fun != nullptr); | |
92f5a8d4 | 52 | { std::cerr << 5 << ' '; |
7c673cae FG |
53 | auto &res = scoped_fun(); |
54 | const int expected = 0xDEADBEEF; | |
55 | BOOST_TEST(res == expected); | |
56 | } | |
92f5a8d4 | 57 | std::cerr << 6 << ' '; |
7c673cae FG |
58 | auto ovl1 = sm.get_function<void(int)> ("overloaded"); |
59 | auto ovl2 = sm.get_function<void(double)>("overloaded"); | |
92f5a8d4 | 60 | std::cerr << 7 << ' '; |
7c673cae FG |
61 | BOOST_TEST(ovl1 != nullptr); |
62 | BOOST_TEST(ovl2 != nullptr); | |
63 | BOOST_TEST(reinterpret_cast<void*>(ovl1) != reinterpret_cast<void*>(ovl2)); | |
92f5a8d4 | 64 | std::cerr << 8 << ' '; |
7c673cae FG |
65 | ovl1(12); |
66 | BOOST_TEST(unscoped_var == 12); | |
67 | ovl2(5.0); | |
68 | BOOST_TEST(sp_variable == 5.0); | |
92f5a8d4 | 69 | std::cerr << 9 << ' '; |
7c673cae FG |
70 | |
71 | ||
72 | auto var1 = sm.get_function<void(boost::variant<int, double> &)>("use_variant"); | |
73 | auto var2 = sm.get_function<void(boost::variant<double, int> &)>("use_variant"); | |
92f5a8d4 | 74 | std::cerr << 10 << ' '; |
7c673cae FG |
75 | BOOST_TEST(var1 != nullptr); |
76 | BOOST_TEST(var2 != nullptr); | |
77 | BOOST_TEST(reinterpret_cast<void*>(var1) != reinterpret_cast<void*>(var2)); | |
78 | ||
79 | { | |
80 | boost::variant<int, double> v1 = 232.22; | |
81 | boost::variant<double, int> v2 = -1; | |
92f5a8d4 | 82 | std::cerr << 11 << ' '; |
7c673cae FG |
83 | var1(v1); |
84 | var2(v2); | |
85 | ||
86 | struct : boost::static_visitor<void> | |
87 | { | |
88 | void operator()(double) {BOOST_TEST(false);} | |
89 | void operator()(int i) {BOOST_TEST(i == 42);} | |
90 | } vis1; | |
91 | ||
92 | struct : boost::static_visitor<void> | |
93 | { | |
94 | void operator()(double d) {BOOST_TEST(d == 3.124);} | |
95 | void operator()(int ) {BOOST_TEST(false);} | |
96 | } vis2; | |
97 | ||
98 | boost::apply_visitor(vis1, v1); | |
99 | boost::apply_visitor(vis2, v2); | |
100 | ||
101 | } | |
92f5a8d4 | 102 | std::cerr << 12 << ' '; |
7c673cae FG |
103 | /* now test the class stuff */ |
104 | ||
105 | //first we import and test the global variables | |
106 | ||
107 | auto& father_val = sm.get_variable<int>("some_space::father_value"); | |
108 | auto& static_val = sm.get_variable<int>("some_space::some_class::value"); | |
109 | BOOST_TEST(father_val == 12); | |
110 | BOOST_TEST(static_val == -1); | |
92f5a8d4 | 111 | std::cerr << 13 << ' '; |
7c673cae FG |
112 | //now get the static function. |
113 | auto set_value = sm.get_function<void(const int &)>("some_space::some_class::set_value"); | |
114 | BOOST_TEST(set_value != nullptr); | |
92f5a8d4 | 115 | std::cerr << 14 << ' '; |
7c673cae FG |
116 | set_value(42); |
117 | BOOST_TEST(static_val == 42); //alright, static method works. | |
118 | ||
119 | ||
120 | //alright, now import the class members | |
121 | //first add the type alias. | |
122 | sm.add_type_alias<override_class>("some_space::some_class"); | |
92f5a8d4 | 123 | std::cerr << 15 << ' '; |
7c673cae FG |
124 | auto set = sm.get_mem_fn<override_class, void(int)>("set"); |
125 | ||
92f5a8d4 | 126 | std::cerr << 16 << ' '; |
7c673cae FG |
127 | try { |
128 | sm.get_mem_fn<override_class, int()>("get"); | |
129 | BOOST_TEST(false); | |
92f5a8d4 | 130 | } catch(boost::dll::fs::system_error &) {} |
7c673cae | 131 | auto get = sm.get_mem_fn<const override_class, int()>("get"); |
92f5a8d4 | 132 | std::cerr << 17 << ' '; |
7c673cae FG |
133 | BOOST_TEST(get != nullptr); |
134 | BOOST_TEST(set != nullptr); | |
92f5a8d4 | 135 | std::cerr << 18 << ' '; |
7c673cae FG |
136 | auto func_dd = sm.get_mem_fn<override_class, double(double, double)>("func"); |
137 | auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func"); | |
138 | auto func_iiv = sm.get_mem_fn<volatile override_class, int(int, int)> ("func"); | |
139 | auto func_ddc = sm.get_mem_fn<const volatile override_class, double(double, double)>("func"); | |
140 | ||
92f5a8d4 | 141 | std::cerr << 19 << ' '; |
7c673cae FG |
142 | BOOST_TEST(func_dd != nullptr); |
143 | BOOST_TEST(func_ii != nullptr); | |
144 | ||
92f5a8d4 | 145 | std::cerr << 20 << ' '; |
7c673cae FG |
146 | auto ctor_v = sm.get_constructor<override_class()>(); |
147 | auto ctor_i = sm.get_constructor<override_class(int)>(); | |
148 | ||
149 | auto dtor = sm.get_destructor<override_class>(); | |
92f5a8d4 | 150 | std::cerr << 21 << ' '; |
7c673cae FG |
151 | //actually never used. |
152 | if (ctor_v.has_allocating()) | |
153 | { | |
154 | //allocate | |
155 | auto p = ctor_v.call_allocating(); | |
156 | ||
157 | //assert it works | |
158 | auto val = (p->*get)(); | |
159 | BOOST_TEST(val == 123); | |
160 | //deallocate | |
161 | dtor.call_deleting(p); | |
162 | //now i cannot assert that it deletes, since it would crash. | |
163 | } | |
164 | //More tests to assure the correct this-ptr | |
92f5a8d4 | 165 | std::cerr << 22 << ' '; |
7c673cae FG |
166 | typedef override_class * override_class_p; |
167 | override_class_p &this_dll = sm.shared_lib().get<override_class_p>("this_"); | |
168 | ||
92f5a8d4 | 169 | std::cerr << 23 << ' '; |
7c673cae FG |
170 | //ok, now load the ctor/dtor |
171 | override_class oc; | |
172 | ||
173 | override_class_p this_exe = &oc; | |
174 | ||
b32b8144 | 175 | for (auto& i : oc.arr) { |
7c673cae | 176 | i = 0; |
b32b8144 | 177 | } |
92f5a8d4 | 178 | std::cerr << 24 << ' '; |
7c673cae FG |
179 | |
180 | BOOST_TEST((oc.*get)() == 0); BOOST_TEST(this_dll == this_exe); | |
181 | ||
182 | ctor_i.call_standard(&oc, 12); BOOST_TEST(this_dll == this_exe); | |
183 | ||
184 | BOOST_TEST(static_val == 12); | |
185 | BOOST_TEST((oc.*get)() == 456); BOOST_TEST(this_dll == this_exe); | |
186 | (oc.*set)(42); | |
187 | BOOST_TEST((oc.*get)() == 42); BOOST_TEST(this_dll == this_exe); | |
92f5a8d4 | 188 | std::cerr << 25 << ' '; |
7c673cae FG |
189 | |
190 | BOOST_TEST((oc.*func_dd)(3,2) == 6); BOOST_TEST(this_dll == this_exe); | |
191 | BOOST_TEST((oc.*func_ii)(1,2) == 3); BOOST_TEST(this_dll == this_exe); | |
192 | BOOST_TEST((oc.*func_ddc)(10,2) == 5); BOOST_TEST(this_dll == this_exe); | |
193 | BOOST_TEST((oc.*func_iiv)(9,2) == 7); BOOST_TEST(this_dll == this_exe); | |
92f5a8d4 | 194 | std::cerr << 26 << ' '; |
7c673cae FG |
195 | dtor.call_standard(&oc); BOOST_TEST(this_dll == this_exe); |
196 | BOOST_TEST(static_val == 0); | |
197 | ||
92f5a8d4 TL |
198 | // TODO: FIX! |
199 | #ifndef BOOST_TRAVISCI_BUILD | |
b32b8144 FG |
200 | const auto& ti = sm.get_type_info<override_class>(); |
201 | BOOST_TEST(ti.name() != nullptr); | |
92f5a8d4 TL |
202 | #endif |
203 | std::cerr << 27 << ' '; | |
7c673cae FG |
204 | //test the ovls helper. |
205 | { | |
206 | namespace ex = boost::dll::experimental; | |
207 | auto &var = ex::get<double>(sm, "some_space::variable"); | |
208 | BOOST_TEST(&var == &sp_variable); | |
209 | ||
210 | auto fun = ex::get<void(int)>(sm, "overloaded"); | |
211 | BOOST_TEST(fun == ovl1); | |
212 | ||
213 | auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func"); | |
214 | ||
215 | auto mem_fn = ex::get<override_class, int(int, int)>(sm, "func"); | |
216 | ||
217 | BOOST_TEST(mem_fn == func_ii); | |
218 | } | |
219 | ||
92f5a8d4 | 220 | std::cerr << 28 << ' '; |
7c673cae FG |
221 | return boost::report_errors(); |
222 | } | |
223 | ||
224 | #else | |
225 | int main() {return 0;} | |
226 | #endif |