1 // Copyright 2016 Klemens Morgenstern
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)
7 // For more information, see http://www.boost.org
9 #include <boost/predef.h>
11 #if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
13 #include "../example/b2_workarounds.hpp"
15 #include <boost/dll/smart_library.hpp>
16 #include <boost/core/lightweight_test.hpp>
17 #include <boost/filesystem.hpp>
18 #include <boost/variant.hpp>
28 int main(int argc
, char* argv
[])
30 using namespace boost::dll
;
31 using namespace boost::dll::experimental
;
32 boost::dll::fs::path pt
= b2_workarounds::first_lib_from_argv(argc
, argv
);
34 BOOST_TEST(!pt
.empty());
35 std::cout
<< "Library: " << pt
<< std::endl
;
36 std::cerr
<< 1 << ' ';
39 auto& unscoped_var
= sm
.get_variable
<int>("unscoped_var");
40 BOOST_TEST(unscoped_var
== 42);
41 std::cerr
<< 2 << ' ';
42 auto& unscoped_c_var
= sm
.get_variable
<const double>("unscoped_c_var");
43 BOOST_TEST(unscoped_c_var
== 1.234);
45 std::cerr
<< 3 << ' ';
46 auto& sp_variable
= sm
.get_variable
<double>("some_space::variable");
47 BOOST_TEST(sp_variable
== 0.2);
49 std::cerr
<< 4 << ' ';
50 auto scoped_fun
= sm
.get_function
<const int&()>("some_space::scoped_fun");
51 BOOST_TEST(scoped_fun
!= nullptr);
52 { std::cerr
<< 5 << ' ';
53 auto &res
= scoped_fun();
54 const int expected
= 0xDEADBEEF;
55 BOOST_TEST(res
== expected
);
57 std::cerr
<< 6 << ' ';
58 auto ovl1
= sm
.get_function
<void(int)> ("overloaded");
59 auto ovl2
= sm
.get_function
<void(double)>("overloaded");
60 std::cerr
<< 7 << ' ';
61 BOOST_TEST(ovl1
!= nullptr);
62 BOOST_TEST(ovl2
!= nullptr);
63 BOOST_TEST(reinterpret_cast<void*>(ovl1
) != reinterpret_cast<void*>(ovl2
));
64 std::cerr
<< 8 << ' ';
66 BOOST_TEST(unscoped_var
== 12);
68 BOOST_TEST(sp_variable
== 5.0);
69 std::cerr
<< 9 << ' ';
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");
74 std::cerr
<< 10 << ' ';
75 BOOST_TEST(var1
!= nullptr);
76 BOOST_TEST(var2
!= nullptr);
77 BOOST_TEST(reinterpret_cast<void*>(var1
) != reinterpret_cast<void*>(var2
));
80 boost::variant
<int, double> v1
= 232.22;
81 boost::variant
<double, int> v2
= -1;
82 std::cerr
<< 11 << ' ';
86 struct : boost::static_visitor
<void>
88 void operator()(double) {BOOST_TEST(false);}
89 void operator()(int i
) {BOOST_TEST(i
== 42);}
92 struct : boost::static_visitor
<void>
94 void operator()(double d
) {BOOST_TEST(d
== 3.124);}
95 void operator()(int ) {BOOST_TEST(false);}
98 boost::apply_visitor(vis1
, v1
);
99 boost::apply_visitor(vis2
, v2
);
102 std::cerr
<< 12 << ' ';
103 /* now test the class stuff */
105 //first we import and test the global variables
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);
111 std::cerr
<< 13 << ' ';
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);
115 std::cerr
<< 14 << ' ';
117 BOOST_TEST(static_val
== 42); //alright, static method works.
120 //alright, now import the class members
121 //first add the type alias.
122 sm
.add_type_alias
<override_class
>("some_space::some_class");
123 std::cerr
<< 15 << ' ';
124 auto set
= sm
.get_mem_fn
<override_class
, void(int)>("set");
126 std::cerr
<< 16 << ' ';
128 sm
.get_mem_fn
<override_class
, int()>("get");
130 } catch(boost::dll::fs::system_error
&) {}
131 auto get
= sm
.get_mem_fn
<const override_class
, int()>("get");
132 std::cerr
<< 17 << ' ';
133 BOOST_TEST(get
!= nullptr);
134 BOOST_TEST(set
!= nullptr);
135 std::cerr
<< 18 << ' ';
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");
141 std::cerr
<< 19 << ' ';
142 BOOST_TEST(func_dd
!= nullptr);
143 BOOST_TEST(func_ii
!= nullptr);
145 std::cerr
<< 20 << ' ';
146 auto ctor_v
= sm
.get_constructor
<override_class()>();
147 auto ctor_i
= sm
.get_constructor
<override_class(int)>();
149 auto dtor
= sm
.get_destructor
<override_class
>();
150 std::cerr
<< 21 << ' ';
151 //actually never used.
152 if (ctor_v
.has_allocating())
155 auto p
= ctor_v
.call_allocating();
158 auto val
= (p
->*get
)();
159 BOOST_TEST(val
== 123);
161 dtor
.call_deleting(p
);
162 //now i cannot assert that it deletes, since it would crash.
164 //More tests to assure the correct this-ptr
165 std::cerr
<< 22 << ' ';
166 typedef override_class
* override_class_p
;
167 override_class_p
&this_dll
= sm
.shared_lib().get
<override_class_p
>("this_");
169 std::cerr
<< 23 << ' ';
170 //ok, now load the ctor/dtor
173 override_class_p this_exe
= &oc
;
175 for (auto& i
: oc
.arr
) {
178 std::cerr
<< 24 << ' ';
180 BOOST_TEST((oc
.*get
)() == 0); BOOST_TEST(this_dll
== this_exe
);
182 ctor_i
.call_standard(&oc
, 12); BOOST_TEST(this_dll
== this_exe
);
184 BOOST_TEST(static_val
== 12);
185 BOOST_TEST((oc
.*get
)() == 456); BOOST_TEST(this_dll
== this_exe
);
187 BOOST_TEST((oc
.*get
)() == 42); BOOST_TEST(this_dll
== this_exe
);
188 std::cerr
<< 25 << ' ';
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
);
194 std::cerr
<< 26 << ' ';
195 dtor
.call_standard(&oc
); BOOST_TEST(this_dll
== this_exe
);
196 BOOST_TEST(static_val
== 0);
199 #ifndef BOOST_TRAVISCI_BUILD
200 const auto& ti
= sm
.get_type_info
<override_class
>();
201 BOOST_TEST(ti
.name() != nullptr);
203 std::cerr
<< 27 << ' ';
204 //test the ovls helper.
206 namespace ex
= boost::dll::experimental
;
207 auto &var
= ex::get
<double>(sm
, "some_space::variable");
208 BOOST_TEST(&var
== &sp_variable
);
210 auto fun
= ex::get
<void(int)>(sm
, "overloaded");
211 BOOST_TEST(fun
== ovl1
);
213 auto func_ii
= sm
.get_mem_fn
<override_class
, int(int, int)> ("func");
215 auto mem_fn
= ex::get
<override_class
, int(int, int)>(sm
, "func");
217 BOOST_TEST(mem_fn
== func_ii
);
220 std::cerr
<< 28 << ' ';
221 return boost::report_errors();
225 int main() {return 0;}