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