summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/dll/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/dll/test')
-rw-r--r--src/boost/libs/dll/test/Jamfile.v295
-rw-r--r--src/boost/libs/dll/test/cpp_import_class_test.cpp115
-rw-r--r--src/boost/libs/dll/test/cpp_import_test.cpp81
-rw-r--r--src/boost/libs/dll/test/cpp_load_test.cpp228
-rw-r--r--src/boost/libs/dll/test/cpp_mangle_test.cpp133
-rw-r--r--src/boost/libs/dll/test/cpp_test_library.cpp203
-rw-r--r--src/boost/libs/dll/test/library_info_test.cpp65
-rw-r--r--src/boost/libs/dll/test/link.hpp21
-rw-r--r--src/boost/libs/dll/test/link1.cpp10
-rw-r--r--src/boost/libs/dll/test/link2.cpp12
-rw-r--r--src/boost/libs/dll/test/section_name_too_big.cpp17
-rw-r--r--src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp82
-rw-r--r--src/boost/libs/dll/test/shared_library_errors.cpp100
-rw-r--r--src/boost/libs/dll/test/shared_library_get_symbol_test.cpp193
-rw-r--r--src/boost/libs/dll/test/shared_library_load_test.cpp528
-rw-r--r--src/boost/libs/dll/test/shared_library_search_symbol_test.cpp49
-rw-r--r--src/boost/libs/dll/test/structures_tests.cpp345
-rw-r--r--src/boost/libs/dll/test/symbol_runtime_info_test.cpp231
-rw-r--r--src/boost/libs/dll/test/template_method_linux_test.cpp67
-rw-r--r--src/boost/libs/dll/test/test_library.cpp115
20 files changed, 2690 insertions, 0 deletions
diff --git a/src/boost/libs/dll/test/Jamfile.v2 b/src/boost/libs/dll/test/Jamfile.v2
new file mode 100644
index 000000000..b7ea3909d
--- /dev/null
+++ b/src/boost/libs/dll/test/Jamfile.v2
@@ -0,0 +1,95 @@
+#
+# Copyright Renato Tegon Forti, Antony Polukhin 2011 - 2019.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+# For more information, see http://www.boost.org
+
+# bring in rules for testing
+import testing ;
+import path ;
+
+local RDYNAMIC = <target-os>freebsd:<linkflags>"-rdynamic" <target-os>solaris:<linkflags>"-Bdynamic" <target-os>aix:<linkflags>"-rdynamic"
+ <target-os>qnxnto,<toolset>qcc:<linkflags>"-Bdynamic" <target-os>qnxnto,<toolset>gcc:<linkflags>"-rdynamic"
+ <target-os>android:<linkflags>"-rdynamic" <target-os>linux:<linkflags>"-rdynamic" <target-os>darwin,<toolset>gcc:<linkflags>"-dynamic"
+ <target-os>darwin,<toolset>clang:<linkflags>"-rdynamic" <target-os>iphone:<linkflags>"-rdynamic" ;
+
+
+# Static library that is not linked with any of the boost libs
+lib static_plugin : ../example/tutorial4/static_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED $(RDYNAMIC) ;
+lib static_refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>static <define>BOOST_SYSTEM_NO_DEPRECATED <variant>release $(RDYNAMIC) ;
+
+
+project
+ : source-location .
+ : requirements
+
+ # linux
+ <target-os>linux:<linkflags>"-ldl"
+ <toolset>gcc:<cxxflags>"-Wall -Wextra -pedantic -Wno-long-long"
+
+ # others
+ <local-visibility>hidden
+ <library>/boost/filesystem//boost_filesystem
+ <library>/boost/system//boost_system
+ <threading>multi
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ ;
+{
+
+ # our test lib for shared library tests
+ lib test_library : test_library.cpp : <link>shared ;
+ lib getting_started_library : ../example/getting_started_library.cpp : <link>shared ;
+ lib my_plugin_sum : ../example/tutorial1/my_plugin_sum.cpp : <link>shared ;
+ lib my_plugin_aggregator : ../example/tutorial2/my_plugin_aggregator.cpp : <link>shared ;
+ lib on_unload_lib : ../example/tutorial6/on_unload_lib.cpp : <link>shared ;
+ lib library1 : ../example/tutorial7/library1.cpp : <link>shared ;
+ lib library2 : ../example/tutorial7/library2.cpp : <link>shared ;
+ lib refcounting_plugin : ../example/tutorial8/refcounting_plugin.cpp : <link>shared ;
+ lib cpp_plugin : cpp_test_library.cpp : <link>shared ;
+
+ test-suite boostdll
+ :
+ [ run link1.cpp link2.cpp : : : : validate_link ]
+ [ run shared_library_load_test.cpp : : library1 test_library : <link>shared ]
+ [ run shared_library_search_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_get_symbol_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_get_symbol_test.cpp
+ :
+ : test_library
+ : $(RDYNAMIC) <target-os>windows:<define>BOOST_USE_WINDOWS_H <link>shared
+ : get_symbol_windows_h_forced
+ ]
+ [ run symbol_runtime_info_test.cpp : : test_library : $(RDYNAMIC) <link>shared ]
+ [ run shared_library_errors.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
+ [ run structures_tests.cpp ]
+ [ run library_info_test.cpp ../example/tutorial4/static_plugin.cpp : : test_library : <test-info>always_show_run_output <link>shared ]
+ [ run ../example/getting_started.cpp : : getting_started_library : <link>shared ]
+ [ run ../example/tutorial1/tutorial1.cpp : : my_plugin_sum : <link>shared ]
+ [ run ../example/tutorial2/tutorial2.cpp : : my_plugin_aggregator : <link>shared ]
+ [ run ../example/tutorial3/tutorial3.cpp : : my_plugin_aggregator my_plugin_sum : <link>shared ]
+ [ run ../example/tutorial4/load_self.cpp ../example/tutorial4/static_plugin.cpp
+ : : : <variant>release $(RDYNAMIC)
+ ]
+ [ run ../example/tutorial5/load_all.cpp ../example/tutorial4/static_plugin.cpp
+ : : getting_started_library my_plugin_aggregator my_plugin_sum : $(RDYNAMIC) <link>shared
+ ]
+ [ run ../example/tutorial6/tutorial6.cpp : : on_unload_lib : <link>shared ]
+ [ run ../example/tutorial7/tutorial7.cpp : : library1 library2 : <link>shared ]
+ [ run ../example/tutorial8/tutorial8.cpp : : refcounting_plugin : <link>shared ]
+ [ run ../example/tutorial8/tutorial8_static.cpp : : : <link>static <variant>release $(RDYNAMIC) <test-info>always_show_run_output <library>static_refcounting_plugin
+ # Known problem: unsupported __dllexport__ with weak symbols + GNU linker features (no non-weak unresolved symbols in executable => no need to link libraries)
+ <target-os>windows,<toolset>gcc:<build>no
+ ]
+ [ run ../example/tutorial9/tutorial9.cpp ]
+ # test for shared libraries
+ [ compile-fail section_name_too_big.cpp ]
+ [ run shared_library_concurrent_load_test.cpp /boost/thread//boost_thread : : library1 library2 my_plugin_aggregator refcounting_plugin : <link>shared ]
+ [ run cpp_mangle_test.cpp : : cpp_plugin ]
+ [ run cpp_load_test.cpp : : cpp_plugin ]
+ [ run cpp_import_test.cpp : : cpp_plugin ]
+ [ run template_method_linux_test.cpp : : cpp_plugin ]
+ ;
+}
diff --git a/src/boost/libs/dll/test/cpp_import_class_test.cpp b/src/boost/libs/dll/test/cpp_import_class_test.cpp
new file mode 100644
index 000000000..60e0adc0b
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_import_class_test.cpp
@@ -0,0 +1,115 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <iostream>
+
+using namespace std;
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+#include <boost/function.hpp>
+
+#define L cout << __LINE__ << endl;
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+
+ smart_library sm(pt);
+
+ auto static_val = import_mangled<int>(sm, "some_space::some_class::value");
+
+ std::cout << "--------------------- Entry Points ------------------------\n" << std::endl;
+ for (auto &s : sm.symbol_storage().get_storage())
+ std::cout << s.demangled << std::endl;
+
+ std::cout << "-----------------------------------------------------------\n\n" << std::endl;
+
+
+ auto sp_variable = import_mangled<double>(sm, "some_space::variable");
+
+ auto unscoped_var = import_mangled<int>(sm, "unscoped_var");
+
+ std::size_t type_size = *import_mangled<std::size_t>(sm, "some_space::size_of_some_class");
+ {
+
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ class override_class{};
+ auto cl = import_class<override_class, int>(sm, "some_space::some_class", type_size, 42);
+#else
+ auto cl = import_class<class override_class, int>(sm, "some_space::some_class", type_size, 42);
+#endif
+ BOOST_TEST(!cl.is_copy_assignable());
+ BOOST_TEST(!cl.is_copy_constructible());
+
+ BOOST_TEST( cl.is_move_assignable());
+ BOOST_TEST( cl.is_move_constructible());
+
+ BOOST_TEST(*static_val == 42);
+
+ auto i = cl.call<const override_class, int()>("get")();
+ BOOST_TEST(i == 456);
+ cl.call<void(int)>("set")(42);
+ i = 0;
+ i = cl.call<const override_class, int()>("get")();
+ BOOST_TEST(i == 42);
+
+ auto func = import_mangled<
+ override_class, double(double, double), int(int, int),
+ volatile override_class, int(int, int),
+ const volatile override_class, double(double, double)>(sm, "func");
+
+
+
+ BOOST_TEST((cl->*func)(3.,2.) == 6.);
+ BOOST_TEST((cl->*func)(1 ,2 ) == 3 );
+
+ auto fun2 = cl.import<double(double, double), int(int, int)>("func");
+
+ BOOST_TEST((cl->*fun2)(3.,2.) == 6.);
+ BOOST_TEST((cl->*fun2)(5 ,2 ) == 7 );
+
+ //test if it binds.
+ boost::function<int(override_class* const, int, int)> mem_fn_obj = func;
+
+
+ const std::type_info & ti = cl.get_type_info();
+ std::string imp_name = boost::core::demangle(ti.name());
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ std::string exp_name = "struct some_space::some_class";
+#else
+ std::string exp_name = "some_space::some_class";
+#endif
+ BOOST_TEST(imp_name == exp_name);
+ }
+
+ BOOST_TEST(*static_val == 0);
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_import_test.cpp b/src/boost/libs/dll/test/cpp_import_test.cpp
new file mode 100644
index 000000000..b6005d058
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_import_test.cpp
@@ -0,0 +1,81 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+#include <boost/function.hpp>
+
+#include <iostream>
+
+struct override_class
+{
+ int arr[32];
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+
+ smart_library sm(pt);
+
+ auto sp_variable = import_mangled<double>(sm, "some_space::variable");
+
+ auto unscoped_var = import_mangled<int>(sm, "unscoped_var");
+
+
+ auto ovl = import_mangled<void(int), void(double)>(sm, "overloaded");
+
+ ovl(12);
+ BOOST_TEST(*unscoped_var == 12);
+ ovl(5.0);
+ BOOST_TEST(*sp_variable == 5.0);
+
+ boost::function<void(int)> f_test = ovl;//test if it binds
+ f_test(-2);
+ BOOST_TEST(*unscoped_var == -2);
+
+ sm.add_type_alias<override_class>("some_space::some_class");
+
+ auto func = import_mangled<
+ override_class, double(double, double), int(int, int),
+ volatile override_class, int(int, int),
+ const volatile override_class, double(double, double)>(sm, "func");
+
+ override_class override_class_varible{};
+
+ override_class *ov = &override_class_varible;
+ volatile override_class *ovv = ov;
+ const volatile override_class *ovcv = ov;
+
+ BOOST_TEST(func(ov, 3.,2.) == 6.);
+ BOOST_TEST(func(ov, 1,2 ) == 3 );
+ BOOST_TEST(func(ovv, 10,2) == 8 );
+ BOOST_TEST(func(ovcv, 9,2) == 4.5 );
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_load_test.cpp b/src/boost/libs/dll/test/cpp_load_test.cpp
new file mode 100644
index 000000000..a95a9afdc
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_load_test.cpp
@@ -0,0 +1,228 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+
+#include <iostream>
+
+struct override_class
+{
+ int arr[32];
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using namespace boost::dll::experimental;
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ BOOST_TEST(!pt.empty());
+ std::cout << "Library: " << pt << std::endl;
+ std::cerr << 1 << ' ';
+ smart_library sm(pt);
+
+ auto& unscoped_var = sm.get_variable<int>("unscoped_var");
+ BOOST_TEST(unscoped_var == 42);
+ std::cerr << 2 << ' ';
+ auto& unscoped_c_var = sm.get_variable<const double>("unscoped_c_var");
+ BOOST_TEST(unscoped_c_var == 1.234);
+
+ std::cerr << 3 << ' ';
+ auto& sp_variable = sm.get_variable<double>("some_space::variable");
+ BOOST_TEST(sp_variable == 0.2);
+
+ std::cerr << 4 << ' ';
+ auto scoped_fun = sm.get_function<const int&()>("some_space::scoped_fun");
+ BOOST_TEST(scoped_fun != nullptr);
+ { std::cerr << 5 << ' ';
+ auto &res = scoped_fun();
+ const int expected = 0xDEADBEEF;
+ BOOST_TEST(res == expected);
+ }
+ std::cerr << 6 << ' ';
+ auto ovl1 = sm.get_function<void(int)> ("overloaded");
+ auto ovl2 = sm.get_function<void(double)>("overloaded");
+ std::cerr << 7 << ' ';
+ BOOST_TEST(ovl1 != nullptr);
+ BOOST_TEST(ovl2 != nullptr);
+ BOOST_TEST(reinterpret_cast<void*>(ovl1) != reinterpret_cast<void*>(ovl2));
+ std::cerr << 8 << ' ';
+ ovl1(12);
+ BOOST_TEST(unscoped_var == 12);
+ ovl2(5.0);
+ BOOST_TEST(sp_variable == 5.0);
+ std::cerr << 9 << ' ';
+
+
+// TODO: ms.get_name on Clang has space after comma `boost::variant<double, int>`
+#if !(defined(BOOST_TRAVISCI_BUILD) && defined(_MSC_VER) && defined(BOOST_CLANG))
+ auto var1 = sm.get_function<void(boost::variant<int, double> &)>("use_variant");
+ auto var2 = sm.get_function<void(boost::variant<double, int> &)>("use_variant");
+ std::cerr << 10 << ' ';
+ BOOST_TEST(var1 != nullptr);
+ BOOST_TEST(var2 != nullptr);
+ BOOST_TEST(reinterpret_cast<void*>(var1) != reinterpret_cast<void*>(var2));
+
+ {
+ boost::variant<int, double> v1 = 232.22;
+ boost::variant<double, int> v2 = -1;
+ std::cerr << 11 << ' ';
+ var1(v1);
+ var2(v2);
+
+ struct : boost::static_visitor<void>
+ {
+ void operator()(double) {BOOST_TEST(false);}
+ void operator()(int i) {BOOST_TEST(i == 42);}
+ } vis1;
+
+ struct : boost::static_visitor<void>
+ {
+ void operator()(double d) {BOOST_TEST(d == 3.124);}
+ void operator()(int ) {BOOST_TEST(false);}
+ } vis2;
+
+ boost::apply_visitor(vis1, v1);
+ boost::apply_visitor(vis2, v2);
+
+ }
+#endif
+ std::cerr << 12 << ' ';
+ /* now test the class stuff */
+
+ //first we import and test the global variables
+
+ auto& father_val = sm.get_variable<int>("some_space::father_value");
+ auto& static_val = sm.get_variable<int>("some_space::some_class::value");
+ BOOST_TEST(father_val == 12);
+ BOOST_TEST(static_val == -1);
+ std::cerr << 13 << ' ';
+ //now get the static function.
+ auto set_value = sm.get_function<void(const int &)>("some_space::some_class::set_value");
+ BOOST_TEST(set_value != nullptr);
+ std::cerr << 14 << ' ';
+ set_value(42);
+ BOOST_TEST(static_val == 42); //alright, static method works.
+
+
+ //alright, now import the class members
+ //first add the type alias.
+ sm.add_type_alias<override_class>("some_space::some_class");
+ std::cerr << 15 << ' ';
+ auto set = sm.get_mem_fn<override_class, void(int)>("set");
+
+ std::cerr << 16 << ' ';
+ try {
+ sm.get_mem_fn<override_class, int()>("get");
+ BOOST_TEST(false);
+ } catch(boost::dll::fs::system_error &) {}
+ auto get = sm.get_mem_fn<const override_class, int()>("get");
+ std::cerr << 17 << ' ';
+ BOOST_TEST(get != nullptr);
+ BOOST_TEST(set != nullptr);
+ std::cerr << 18 << ' ';
+ auto func_dd = sm.get_mem_fn<override_class, double(double, double)>("func");
+ auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func");
+ auto func_iiv = sm.get_mem_fn<volatile override_class, int(int, int)> ("func");
+ auto func_ddc = sm.get_mem_fn<const volatile override_class, double(double, double)>("func");
+
+ std::cerr << 19 << ' ';
+ BOOST_TEST(func_dd != nullptr);
+ BOOST_TEST(func_ii != nullptr);
+
+ std::cerr << 20 << ' ';
+ auto ctor_v = sm.get_constructor<override_class()>();
+ auto ctor_i = sm.get_constructor<override_class(int)>();
+
+ auto dtor = sm.get_destructor<override_class>();
+ std::cerr << 21 << ' ';
+ //actually never used.
+ if (ctor_v.has_allocating())
+ {
+ //allocate
+ auto p = ctor_v.call_allocating();
+
+ //assert it works
+ auto val = (p->*get)();
+ BOOST_TEST(val == 123);
+ //deallocate
+ dtor.call_deleting(p);
+ //now i cannot assert that it deletes, since it would crash.
+ }
+ //More tests to assure the correct this-ptr
+ std::cerr << 22 << ' ';
+ typedef override_class * override_class_p;
+ override_class_p &this_dll = sm.shared_lib().get<override_class_p>("this_");
+
+ std::cerr << 23 << ' ';
+ //ok, now load the ctor/dtor
+ override_class oc;
+
+ override_class_p this_exe = &oc;
+
+ for (auto& i : oc.arr) {
+ i = 0;
+ }
+ std::cerr << 24 << ' ';
+
+ BOOST_TEST((oc.*get)() == 0); BOOST_TEST(this_dll == this_exe);
+
+ ctor_i.call_standard(&oc, 12); BOOST_TEST(this_dll == this_exe);
+
+ BOOST_TEST(static_val == 12);
+ BOOST_TEST((oc.*get)() == 456); BOOST_TEST(this_dll == this_exe);
+ (oc.*set)(42);
+ BOOST_TEST((oc.*get)() == 42); BOOST_TEST(this_dll == this_exe);
+ std::cerr << 25 << ' ';
+
+ BOOST_TEST((oc.*func_dd)(3,2) == 6); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_ii)(1,2) == 3); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_ddc)(10,2) == 5); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST((oc.*func_iiv)(9,2) == 7); BOOST_TEST(this_dll == this_exe);
+ std::cerr << 26 << ' ';
+ dtor.call_standard(&oc); BOOST_TEST(this_dll == this_exe);
+ BOOST_TEST(static_val == 0);
+
+#ifndef BOOST_NO_RTTI
+ const auto& ti = sm.get_type_info<override_class>();
+ BOOST_TEST(ti.name() != nullptr);
+#endif
+ std::cerr << 27 << ' ';
+ //test the ovls helper.
+ {
+ namespace ex = boost::dll::experimental;
+ auto &var = ex::get<double>(sm, "some_space::variable");
+ BOOST_TEST(&var == &sp_variable);
+
+ auto fun = ex::get<void(int)>(sm, "overloaded");
+ BOOST_TEST(fun == ovl1);
+
+ auto func_ii = sm.get_mem_fn<override_class, int(int, int)> ("func");
+
+ auto mem_fn = ex::get<override_class, int(int, int)>(sm, "func");
+
+ BOOST_TEST(mem_fn == func_ii);
+ }
+
+ std::cerr << 28 << ' ';
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_mangle_test.cpp b/src/boost/libs/dll/test/cpp_mangle_test.cpp
new file mode 100644
index 000000000..1b235877b
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_mangle_test.cpp
@@ -0,0 +1,133 @@
+// Copyright 2016 Klemens Morgenstern
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/variant.hpp>
+
+#include <iostream>
+
+
+struct override_class {};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+ using mangled_storage = detail::mangled_storage_impl;
+
+ boost::dll::fs::path pt = b2_workarounds::first_lib_from_argv(argc, argv);
+
+ std::cout << "Library: " << pt << std::endl;
+ library_info lib{pt};
+
+ mangled_storage ms(lib);
+
+ std::cout << "Symbols: " << std::endl;
+
+ for (auto &s : ms.get_storage())
+ {
+ std::cout << s.demangled << std::endl;
+ }
+
+ std::string v;
+ v = ms.get_variable<double>("some_space::variable");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+ BOOST_TEST(v != "some_space::variable"); //demangle is different
+
+ v = ms.get_variable<double>("some_space::variable_typo");
+ BOOST_TEST(v.empty());
+
+
+ v = ms.get_variable<const double>("unscoped_c_var");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+
+ v = ms.get_variable<int>("unscoped_var");
+
+ BOOST_TEST(!v.empty()); //check if a symbols was found.
+
+
+ v = ms.get_function<const int &()>("some_space::scoped_fun");
+
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::scoped_fun");
+
+
+ auto v1 = ms.get_function<void(const double)>("overloaded");
+ auto v2 = ms.get_function<void(const volatile int)>("overloaded");
+ BOOST_TEST(!v1.empty());
+ BOOST_TEST(!v2.empty());
+ BOOST_TEST(v1 != v2);
+
+ v = ms.get_variable<int>("some_space::some_class::value");
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::some_class::value");
+
+ v = ms.get_function<void(const int &)>("some_space::some_class::set_value");
+
+ BOOST_TEST(!v.empty());
+ BOOST_TEST(v != "some_space::some_class::set_value");
+
+
+
+ ms.add_alias<override_class>("some_space::some_class");
+
+ auto ctor1 = ms.get_constructor<override_class()>();
+ BOOST_TEST(!ctor1.empty());
+
+ auto ctor2 = ms.get_constructor<override_class(int)>();
+ BOOST_TEST(!ctor2.empty());
+
+
+ v = ms.get_mem_fn<override_class, double(double, double)>("func");
+ BOOST_TEST(!v.empty());
+
+ v = ms.get_mem_fn<override_class, int(int, int)>("func");
+ BOOST_TEST(!v.empty());
+
+
+ auto dtor = ms.get_destructor<override_class>();
+
+ BOOST_TEST(!dtor.empty());
+
+// TODO: ms.get_name on Clang has space after comma `boost::variant<double, int>`
+#if !(defined(BOOST_TRAVISCI_BUILD) && defined(_MSC_VER) && defined(BOOST_CLANG))
+ auto var1 = ms.get_function<void(boost::variant<int, double> &)>("use_variant");
+ auto var2 = ms.get_function<void(boost::variant<double, int> &)>("use_variant");
+
+ BOOST_TEST(!var1.empty());
+ BOOST_TEST(!var2.empty());
+#endif
+
+#ifndef BOOST_NO_RTTI
+
+#if defined(_MSC_VER) // MSVC, Clang-cl, and ICC on Windows
+ auto vtable = ms.get_vtable<override_class>();
+ BOOST_TEST(!vtable.empty());
+#else
+ auto ti = ms.get_type_info<override_class>();
+ BOOST_TEST(!ti.empty());
+#endif
+
+#endif // #ifndef BOOST_NO_RTTI
+
+ return boost::report_errors();
+}
+
+#else
+int main() {return 0;}
+#endif
diff --git a/src/boost/libs/dll/test/cpp_test_library.cpp b/src/boost/libs/dll/test/cpp_test_library.cpp
new file mode 100644
index 000000000..f32a3376a
--- /dev/null
+++ b/src/boost/libs/dll/test/cpp_test_library.cpp
@@ -0,0 +1,203 @@
+// Copyright 2016 Klemens Morgenstern
+// Copyright 2017-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/config.hpp>
+#include <boost/variant.hpp>
+
+BOOST_SYMBOL_EXPORT extern int unscoped_var;
+int unscoped_var = 42;
+
+BOOST_SYMBOL_EXPORT extern const double unscoped_c_var;
+const double unscoped_c_var = 1.234;
+
+
+namespace some_space {
+
+BOOST_SYMBOL_EXPORT extern double variable;
+double variable = 0.2;
+BOOST_SYMBOL_EXPORT const int & scoped_fun()
+{
+ static int x = 0xDEADBEEF;
+ return x;
+}
+
+}
+
+
+BOOST_SYMBOL_EXPORT void overloaded(const volatile int i)
+{
+ unscoped_var = i;
+}
+
+BOOST_SYMBOL_EXPORT void overloaded(const double d)
+{
+ some_space::variable = d;
+}
+
+BOOST_SYMBOL_EXPORT void use_variant(boost::variant<int, double> & v)
+{
+ v = 42;
+}
+
+BOOST_SYMBOL_EXPORT void use_variant(boost::variant<double, int> & v)
+{
+ v = 3.124;
+}
+
+
+
+namespace some_space
+{
+
+BOOST_SYMBOL_EXPORT extern int father_value;
+int father_value = 12;
+
+struct BOOST_SYMBOL_EXPORT some_father
+{
+ some_father() { father_value = 24; };
+ ~some_father() { father_value = 112; };
+};
+
+
+
+struct BOOST_SYMBOL_EXPORT some_class : some_father
+{
+ static int value ;
+ static void set_value(const int &i);
+
+ // static some_class* dummy();
+
+ virtual double func(double i, double j);
+ virtual int func(int i, int j);
+ int func(int i, int j) volatile;
+ double func(double i, double j) const volatile;
+
+ int mem_val;
+ int get() const ;
+ void set(int i) ;
+
+ some_class();
+ some_class(some_class &&);
+ some_class(int i);
+
+ some_class& operator=(some_class &&);
+
+
+ virtual ~some_class();
+};
+
+some_class::some_class(some_class &&){}
+
+
+some_class& some_class::operator=(some_class &&ref) {return ref;}
+
+
+BOOST_SYMBOL_EXPORT extern std::size_t size_of_some_class;
+std::size_t size_of_some_class = sizeof(some_space::some_class);
+
+
+extern "C" BOOST_SYMBOL_EXPORT const volatile some_class* this_;
+const volatile some_class * this_ = nullptr;
+
+int some_class::value = -1;
+
+void some_class::set_value(const int &i) {value = i;}
+
+
+//some_class* some_class::dummy() {return new some_class();}//so it implements an allocating ctor.
+
+double some_class::func(double i, double j) {this_ = this; return i*j;}
+int some_class::func(int i, int j) {this_ = this; return i+j;}
+int some_class::func(int i, int j) volatile {this_ = this; return i-j;;}
+double some_class::func(double i, double j) const volatile {this_ = this; return i/j;}
+
+int some_class::get() const {this_ = this; return mem_val;}
+void some_class::set(int i) {this_ = this; mem_val = i;}
+
+some_class::some_class() { this_ = this; value = 23; mem_val = 123;}
+some_class::some_class(int i) : mem_val(456) {this_ = this; value = i;}
+
+some_class::~some_class()
+{
+ value = 0;
+ this_ = this;
+}
+
+}
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin;
+}
+
+namespace testing { namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func() const;
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func2();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int AFunc();
+ };
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() const { return 30; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() { return 32; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func2() { return 33; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::AFunc() { return 31; }
+
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
+}}
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func() const;
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int Func2();
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int AFunc();
+ };
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() const { return 40; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func() { return 42; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::Func2() { return 43; }
+
+ template<typename Arg>
+ BOOST_SYMBOL_EXPORT int my_plugin::AFunc() { return 41; }
+
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
+ template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
+}
+
+
+#endif
diff --git a/src/boost/libs/dll/test/library_info_test.cpp b/src/boost/libs/dll/test/library_info_test.cpp
new file mode 100644
index 000000000..e7808e961
--- /dev/null
+++ b/src/boost/libs/dll/test/library_info_test.cpp
@@ -0,0 +1,65 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2015-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+#include "../example/b2_workarounds.hpp"
+
+#include <boost/dll/library_info.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/tutorial4/static_plugin.hpp"
+
+// Unit Tests
+
+#include <iterator>
+
+int main(int argc, char* argv[])
+{
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+
+ boost::dll::library_info lib_info(shared_library_path);
+ std::vector<std::string> sec = lib_info.sections();
+ std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", "));
+ BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end());
+
+
+ std::cout << "\n\n\n";
+ std::vector<std::string> symb = lib_info.symbols();
+ std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g") != symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") != symb.end());
+
+ symb = lib_info.symbols("boostdll");
+ std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g_alias") != symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "foo_variable") != symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "const_integer_g") == symb.end());
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") == symb.end());
+ BOOST_TEST(lib_info.symbols(std::string("boostdll")) == symb);
+
+ std::vector<std::string> empty = lib_info.symbols("empty");
+ BOOST_TEST(empty.empty() == true);
+
+ BOOST_TEST(lib_info.symbols("section_that_does_not_exist").empty());
+
+ // Self testing
+ std::cout << "Self: " << argv[0];
+ boost::dll::library_info self_info(argv[0]);
+
+ sec = self_info.sections();
+ //std::copy(sec.begin(), sec.end(), std::ostream_iterator<std::string>(std::cout, ", "));
+ BOOST_TEST(std::find(sec.begin(), sec.end(), "boostdll") != sec.end());
+
+ symb = self_info.symbols("boostdll");
+ std::copy(symb.begin(), symb.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
+ BOOST_TEST(std::find(symb.begin(), symb.end(), "create_plugin") != symb.end());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/dll/test/link.hpp b/src/boost/libs/dll/test/link.hpp
new file mode 100644
index 000000000..f84d8bd34
--- /dev/null
+++ b/src/boost/libs/dll/test/link.hpp
@@ -0,0 +1,21 @@
+// Copyright 2018-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org
+
+
+#include <boost/predef.h>
+
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#endif
+
+
+#include <boost/dll.hpp>
diff --git a/src/boost/libs/dll/test/link1.cpp b/src/boost/libs/dll/test/link1.cpp
new file mode 100644
index 000000000..639e827cf
--- /dev/null
+++ b/src/boost/libs/dll/test/link1.cpp
@@ -0,0 +1,10 @@
+// Copyright 2018-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org
+
+
+#include "link.hpp"
diff --git a/src/boost/libs/dll/test/link2.cpp b/src/boost/libs/dll/test/link2.cpp
new file mode 100644
index 000000000..670d39069
--- /dev/null
+++ b/src/boost/libs/dll/test/link2.cpp
@@ -0,0 +1,12 @@
+// Copyright 2018-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org
+
+
+#include "link.hpp"
+
+int main() {}
diff --git a/src/boost/libs/dll/test/section_name_too_big.cpp b/src/boost/libs/dll/test/section_name_too_big.cpp
new file mode 100644
index 000000000..03db48f5c
--- /dev/null
+++ b/src/boost/libs/dll/test/section_name_too_big.cpp
@@ -0,0 +1,17 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+#include <boost/dll/config.hpp>
+#include <boost/dll/alias.hpp>
+
+int integer_g = 100;
+BOOST_DLL_ALIAS_SECTIONED(integer_g, integer_g_aliased, "long_section_name")
+
diff --git a/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp
new file mode 100644
index 000000000..e97926b7e
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_concurrent_load_test.cpp
@@ -0,0 +1,82 @@
+// Copyright 2015-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifdef BOOST_TRAVISCI_BUILD
+
+int main() {
+ return 0;
+}
+
+#else // #ifdef BOOST_TRAVISCI_BUILD
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/bind.hpp>
+#include <cctype>
+#include <vector>
+
+typedef std::vector<boost::dll::fs::path> paths_t;
+const std::size_t thread_count = 4;
+boost::barrier b(thread_count);
+
+
+// Disgusting workarounds for b2 on Windows platform
+inline paths_t generate_paths(int argc, char* argv[]) {
+ paths_t ret;
+ ret.reserve(argc - 1);
+
+ for (int i = 1; i < argc; ++i) {
+ boost::dll::fs::path p = argv[i];
+ if (b2_workarounds::is_shared_library(p)) {
+ ret.push_back(p);
+ }
+ }
+
+ return ret;
+}
+
+inline void load_unload(const paths_t& paths, std::size_t count) {
+ for (std::size_t j = 0; j < count; j += 2) {
+ for (std::size_t i = 0; i < paths.size(); ++i) {
+ boost::dll::shared_library lib(paths[i]);
+ BOOST_TEST(lib);
+ }
+ for (std::size_t i = 0; i < paths.size(); ++i) {
+ boost::dll::shared_library lib(paths[i]);
+ BOOST_TEST(lib.location() != "");
+ }
+
+ // Waiting for all threads to unload shared libraries
+ b.wait();
+ }
+}
+
+
+int main(int argc, char* argv[]) {
+ BOOST_TEST(argc >= 3);
+ paths_t paths = generate_paths(argc, argv);
+ BOOST_TEST(!paths.empty());
+
+ std::cout << "Libraries:\n\t";
+ std::copy(paths.begin(), paths.end(), std::ostream_iterator<boost::dll::fs::path>(std::cout, ", "));
+ std::cout << std::endl;
+
+ boost::thread_group threads;
+ for (std::size_t i = 0; i < thread_count; ++i) {
+ threads.create_thread(boost::bind(load_unload, paths, 1000));
+ }
+ threads.join_all();
+
+ return boost::report_errors();
+}
+
+#endif // #ifdef BOOST_TRAVISCI_BUILD
diff --git a/src/boost/libs/dll/test/shared_library_errors.cpp b/src/boost/libs/dll/test/shared_library_errors.cpp
new file mode 100644
index 000000000..2f186fe1b
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_errors.cpp
@@ -0,0 +1,100 @@
+// Copyright 2011-2012 Renato Tegon Forti.
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll/shared_library.hpp>
+#include <boost/dll/library_info.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/function.hpp>
+
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+ boost::dll::fs::path bad_path = shared_library_path / "directory_that_does_not_exist";
+
+ try {
+ shared_library lib(bad_path);
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.get<int>("variable_or_function_that_does_not_exist");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib("");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib("\0\0");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.location();
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ shared_library lib;
+ lib.load("\0\0", load_mode::rtld_global);
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ shared_library sl(shared_library_path);
+ try {
+ sl.get<int>("variable_or_function_that_does_not_exist");
+ BOOST_TEST(false);
+ } catch (const boost::dll::fs::system_error& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ library_info lib("\0");
+ BOOST_TEST(false);
+ } catch (const std::exception& e) {
+ std::cout << e.what() << '\n';
+ }
+
+ try {
+ std::string not_a_binary(argv[1]);
+ not_a_binary += "/not_a_binary";
+ std::ofstream ofs(not_a_binary.c_str());
+ ofs << "This is not a binary file, so library_info must report 'Unsupported binary format'";
+ ofs.close();
+ library_info lib(not_a_binary);
+ BOOST_TEST(false);
+ } catch (const std::exception& e) {
+ std::cout << e.what() << '\n';
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp
new file mode 100644
index 000000000..82e524d3d
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_get_symbol_test.cpp
@@ -0,0 +1,193 @@
+// Copyright 2011-2012 Renato Tegon Forti.
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/function.hpp>
+#include <boost/fusion/container.hpp>
+// lib functions
+
+typedef float (lib_version_func)();
+typedef void (say_hello_func) ();
+typedef int (increment) (int);
+
+typedef boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* > do_share_res_t;
+typedef boost::shared_ptr<do_share_res_t> (do_share_t)(
+ std::vector<int> v1,
+ std::vector<int>& v2,
+ const std::vector<int>& v3,
+ const std::vector<int>* v4,
+ std::vector<int>* v5
+ );
+
+void refcountable_test(boost::dll::fs::path shared_library_path) {
+ using namespace boost::dll;
+ using namespace boost::fusion;
+
+ std::vector<int> v(1000);
+
+ {
+ boost::function<say_hello_func> sz2
+ = import<say_hello_func>(shared_library_path, "say_hello");
+
+ sz2();
+ sz2();
+ sz2();
+ }
+
+ {
+ boost::function<std::size_t(const std::vector<int>&)> sz
+ = import_alias<std::size_t(const std::vector<int>&)>(shared_library_path, "foo_bar");
+ BOOST_TEST(sz(v) == 1000);
+ }
+
+
+ {
+ boost::function<do_share_t> f;
+
+ {
+ boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
+ f = f2;
+ }
+
+ std::vector<int> v1(1, 1), v2(2, 2), v3(3, 3), v4(4, 4), v5(1000, 5);
+ boost::shared_ptr<do_share_res_t> res = f(v1, v2, v3, &v4, &v5);
+
+ BOOST_TEST(at_c<0>(*res).size() == 1); BOOST_TEST(at_c<0>(*res).front() == 1);
+ BOOST_TEST(at_c<1>(*res).size() == 2); BOOST_TEST(at_c<1>(*res).front() == 2);
+ BOOST_TEST(at_c<2>(*res).size() == 3); BOOST_TEST(at_c<2>(*res).front() == 3);
+ BOOST_TEST(at_c<3>(*res)->size() == 4); BOOST_TEST(at_c<3>(*res)->front() == 4);
+ BOOST_TEST(at_c<4>(*res)->size() == 1000); BOOST_TEST(at_c<4>(*res)->front() == 5);
+
+ BOOST_TEST(at_c<3>(*res) == &v4);
+ BOOST_TEST(at_c<4>(*res) == &v5);
+ BOOST_TEST(at_c<1>(*res).back() == 777);
+ BOOST_TEST(v5.back() == 9990);
+ }
+
+ {
+ boost::shared_ptr<int> i = import<int>(shared_library_path, "integer_g");
+ BOOST_TEST(*i == 100);
+
+ boost::shared_ptr<int> i2;
+ i.swap(i2);
+ BOOST_TEST(*i2 == 100);
+ }
+
+ {
+ boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
+ BOOST_TEST(f() == 0);
+
+ f() = 10;
+ BOOST_TEST(f() == 10);
+
+ boost::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
+ BOOST_TEST(f1() == 10);
+
+ f1() += 10;
+ BOOST_TEST(f() == 20);
+ }
+
+ {
+ boost::shared_ptr<const int> i = import<const int>(shared_library_path, "const_integer_g");
+ BOOST_TEST(*i == 777);
+
+ boost::shared_ptr<const int> i2 = i;
+ i.reset();
+ BOOST_TEST(*i2 == 777);
+ }
+
+ {
+ boost::shared_ptr<std::string> s = import_alias<std::string>(shared_library_path, "info");
+ BOOST_TEST(*s == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+
+ boost::shared_ptr<std::string> s2;
+ s.swap(s2);
+ BOOST_TEST(*s2 == "I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+ }
+}
+
+// exe function
+extern "C" int BOOST_SYMBOL_EXPORT exef() {
+ return 15;
+}
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+
+ refcountable_test(shared_library_path);
+
+ shared_library sl(shared_library_path);
+
+ BOOST_TEST(sl.get<int>("integer_g") == 100);
+
+ sl.get<int>("integer_g") = 10;
+ BOOST_TEST(sl.get<int>("integer_g") == 10);
+ BOOST_TEST(sl.get<int>(std::string("integer_g")) == 10);
+
+ BOOST_TEST(sl.get<say_hello_func>("say_hello"));
+ sl.get<say_hello_func>("say_hello")();
+
+ float ver = sl.get<lib_version_func>("lib_version")();
+ BOOST_TEST(ver == 1.0);
+
+ int n = sl.get<increment>("increment")(1);
+ BOOST_TEST(n == 2);
+
+ BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
+
+ boost::function<int(int)> inc = sl.get<int(int)>("increment");
+ BOOST_TEST(inc(1) == 2);
+ BOOST_TEST(inc(2) == 3);
+ BOOST_TEST(inc(3) == 4);
+
+ // Checking that symbols are still available, after another load+unload of the library
+ { shared_library sl2(shared_library_path); }
+
+ BOOST_TEST(inc(1) == 2);
+ BOOST_TEST(sl.get<int>("integer_g") == 10);
+
+
+ // Checking aliases
+ boost::function<std::size_t(const std::vector<int>&)> sz
+ = sl.get_alias<std::size_t(const std::vector<int>&)>("foo_bar");
+
+ std::vector<int> v(10);
+ BOOST_TEST(sz(v) == 10);
+ BOOST_TEST(sl.get_alias<std::size_t>("foo_variable") == 42);
+
+
+ sz = sl.get<std::size_t(*)(const std::vector<int>&)>("foo_bar");
+ BOOST_TEST(sz(v) == 10);
+ BOOST_TEST(*sl.get<std::size_t*>("foo_variable") == 42);
+
+ { // self
+ shared_library sl(program_location());
+ int val = sl.get<int(void)>("exef")();
+ BOOST_TEST(val == 15);
+ }
+
+ int& reference_to_internal_integer = sl.get<int&>("reference_to_internal_integer");
+ BOOST_TEST(reference_to_internal_integer == 0xFF0000);
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ int&& rvalue_reference_to_internal_integer = sl.get<int&&>("rvalue_reference_to_internal_integer");
+ BOOST_TEST(rvalue_reference_to_internal_integer == 0xFF0000);
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/shared_library_load_test.cpp b/src/boost/libs/dll/test/shared_library_load_test.cpp
new file mode 100644
index 000000000..de7e619ee
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_load_test.cpp
@@ -0,0 +1,528 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2015-2019 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+// Unit Tests
+
+namespace boost { namespace dll { namespace fs {
+
+#ifdef BOOST_DLL_USE_STD_FS
+using std::filesystem::remove;
+using std::filesystem::copy;
+#else
+using boost::filesystem::remove;
+using boost::filesystem::copy;
+#endif
+
+}}}
+
+inline boost::dll::fs::path drop_version(const boost::dll::fs::path& lhs) {
+ boost::dll::fs::path ext = lhs.filename().extension();
+ if (ext.native().size() > 1 && std::isdigit(ext.string()[1])) {
+ ext = lhs;
+ ext.replace_extension().replace_extension().replace_extension();
+ return ext;
+ }
+
+ return lhs;
+}
+
+inline bool lib_path_equal(const boost::dll::fs::path& lhs, const boost::dll::fs::path& rhs) {
+ const bool res = (drop_version(lhs).filename() == drop_version(rhs).filename());
+ if (!res) {
+ std::cerr << "lhs != rhs: " << lhs << " != " << rhs << '\n';
+ }
+ return res;
+}
+
+struct fs_copy_guard {
+ const boost::dll::fs::path actual_path_;
+ const bool same_;
+
+ inline explicit fs_copy_guard(const boost::dll::fs::path& shared_library_path)
+ : actual_path_( drop_version(shared_library_path) )
+ , same_(actual_path_ == shared_library_path)
+ {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ boost::dll::fs::copy(shared_library_path, actual_path_, ignore);
+ }
+ }
+
+ inline ~fs_copy_guard() {
+ if (!same_) {
+ boost::dll::fs::error_code ignore;
+ boost::dll::fs::remove(actual_path_, ignore);
+ }
+ }
+};
+
+// Disgusting workarounds for b2 on Windows platform
+inline boost::dll::fs::path do_find_correct_libs_path(int argc, char* argv[], const char* lib_name) {
+ boost::dll::fs::path ret;
+
+ for (int i = 1; i < argc; ++i) {
+ ret = argv[i];
+ if (ret.string().find(lib_name) != std::string::npos && b2_workarounds::is_shared_library(ret)) {
+ return ret;
+ }
+ }
+
+ return lib_name;
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+
+ BOOST_TEST(argc >= 3);
+ boost::dll::fs::path shared_library_path = do_find_correct_libs_path(argc, argv, "test_library");
+ std::cout << "Library: " << shared_library_path;
+
+ {
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2;
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+
+ swap(sl, sl2);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl.assign(sl2);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ sl2.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ // Assigning an empty shared library
+ sl2.assign(shared_library());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+ boost::dll::fs::error_code ec;
+ BOOST_TEST(sl2.location(ec) != sl.location());
+ BOOST_TEST(ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+
+ // Checking self assignment #1
+ sl.assign(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+
+ // Checking self assignment #2
+ sl.assign(sl, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ BOOST_TEST(!sl.is_loaded());
+
+ sl.assign(sl);
+ BOOST_TEST(!sl);
+
+ shared_library sl2(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+
+ sl2.assign(sl);
+ BOOST_TEST(!sl);
+ BOOST_TEST(!sl2);
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::search_system_folders, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ BOOST_TEST(lib_path_equal(sl.location(ec), shared_library_path));
+ BOOST_TEST(!ec);
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm.dll");
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("libdl.so");
+#endif
+ BOOST_TEST(false);
+ } catch (...) {}
+ }
+
+ {
+ try {
+#if BOOST_OS_WINDOWS
+ boost::dll::shared_library("winmm", load_mode::search_system_folders | load_mode::append_decorations);
+#elif BOOST_OS_LINUX
+ boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders | load_mode::append_decorations);
+#endif
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::load_with_altered_search_path, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_local);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ fs_copy_guard guard(shared_library_path);
+
+ boost::dll::fs::path platform_independent_path = guard.actual_path_;
+ platform_independent_path.replace_extension();
+ if (platform_independent_path.filename().wstring().find(L"lib") == 0) {
+ platform_independent_path
+ = platform_independent_path.parent_path() / platform_independent_path.filename().wstring().substr(3);
+ }
+ std::cerr << "platform_independent_path: " << platform_independent_path << '\n';
+
+ shared_library sl(platform_independent_path, load_mode::append_decorations);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+ {
+ shared_library sl(shared_library_path, load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+ {
+ shared_library sl;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ }
+
+
+ { // Non-default flags with assignment
+ shared_library sl(shared_library_path,
+ load_mode::rtld_now | load_mode::rtld_global | load_mode::load_with_altered_search_path
+
+// `load_mode::rtld_deepbind` is incompatible with sanitizers:
+// You are trying to dlopen a libtest_library.so shared library with RTLD_DEEPBIND flag which is incompatibe with sanitizer runtime
+// (see https://github.com/google/sanitizers/issues/611 for details).
+#ifndef BOOST_TRAVISCI_BUILD
+ | load_mode::rtld_deepbind
+#endif
+
+ );
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+
+ shared_library sl4;
+ sl4.assign(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl4.is_loaded());
+ BOOST_TEST(sl4);
+ }
+
+ { // Non-default flags with assignment and error_code
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ shared_library sl2(sl, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST(sl2);
+ BOOST_TEST(sl2.location() == sl.location());
+
+ shared_library sl3(sl);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+ BOOST_TEST(sl3.location() == sl.location());
+ }
+
+ { // self_load
+ shared_library sl(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ std::cout << "\nProgram location: " << program_location();
+ std::cout << "\nLibrary location: " << sl.location();
+ BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
+
+ boost::dll::fs::error_code ec;
+ shared_library sl2(program_location());
+ BOOST_TEST(sl2.is_loaded());
+ BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
+ BOOST_TEST(sl2);
+ BOOST_TEST(!ec);
+
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ sl.load(shared_library_path);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl.unload();
+ BOOST_TEST(!sl);
+ BOOST_TEST(sl != sl2);
+ BOOST_TEST(sl < sl2 || sl2 <sl);
+ BOOST_TEST(!(sl == sl2));
+
+ sl2.unload();
+ BOOST_TEST(!sl2);
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(!(sl < sl2 || sl2 <sl));
+ BOOST_TEST(!(sl != sl2));
+
+ // assigning self
+ sl.load(program_location());
+ sl2 = sl;
+ BOOST_TEST(sl == sl2);
+ BOOST_TEST(sl.location() == sl2.location());
+ }
+
+ {
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(shared_library_path, load_mode::rtld_lazy | load_mode::rtld_global, ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // self_load
+ shared_library sl;
+ boost::dll::fs::error_code ec;
+ sl.load(program_location());
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(!ec);
+ }
+
+ { // unload
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+ BOOST_TEST(lib_path_equal(sl.location(), shared_library_path));
+ sl.unload();
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+
+ { // error_code load calls test
+ boost::dll::fs::error_code ec;
+ shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+
+ boost::dll::fs::path bad_path(shared_library_path);
+ bad_path += ".1.1.1.1.1.1";
+ sl.load(bad_path, ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+
+ sl.load(shared_library_path, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl.is_loaded());
+ BOOST_TEST(sl);
+
+ shared_library sl2(bad_path, ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl2.is_loaded());
+ BOOST_TEST(!sl2);
+
+ shared_library sl3(shared_library_path, ec);
+ BOOST_TEST(!ec);
+ BOOST_TEST(sl3.is_loaded());
+ BOOST_TEST(sl3);
+
+ sl.load("", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(!sl.is_loaded());
+ BOOST_TEST(!sl);
+ }
+
+
+ shared_library_path = do_find_correct_libs_path(argc, argv, "library1");
+ fs_copy_guard guard(shared_library_path);
+ shared_library starts_with_lib(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ starts_with_lib.load(
+ boost::dll::fs::path(guard.actual_path_).replace_extension(),
+ load_mode::append_decorations
+ );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp
new file mode 100644
index 000000000..cf1dc66fc
--- /dev/null
+++ b/src/boost/libs/dll/test/shared_library_search_symbol_test.cpp
@@ -0,0 +1,49 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+// Unit Tests
+
+extern "C" void BOOST_SYMBOL_EXPORT exef() {
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+ BOOST_TEST(b2_workarounds::is_shared_library(shared_library_path));
+ std::cout << "Library: " << shared_library_path;
+
+ {
+ shared_library sl(shared_library_path);
+ BOOST_TEST(sl.has("say_hello"));
+ BOOST_TEST(sl.has("lib_version"));
+ BOOST_TEST(sl.has("integer_g"));
+ BOOST_TEST(sl.has(std::string("integer_g")));
+ BOOST_TEST(!sl.has("i_do_not_exist"));
+ BOOST_TEST(!sl.has(std::string("i_do_not_exist")));
+ }
+
+ {
+ shared_library sl(program_location());
+ BOOST_TEST(sl.has("exef"));
+ BOOST_TEST(!sl.has("i_do_not_exist"));
+ }
+
+
+ exef(); // Make sure that this function still callable in traditional way
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/structures_tests.cpp b/src/boost/libs/dll/test/structures_tests.cpp
new file mode 100644
index 000000000..1598dc735
--- /dev/null
+++ b/src/boost/libs/dll/test/structures_tests.cpp
@@ -0,0 +1,345 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/dll/detail/elf_info.hpp>
+#include <boost/dll/detail/pe_info.hpp>
+#include <boost/dll/detail/macho_info.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <boost/predef/os.h>
+
+#if BOOST_OS_WINDOWS
+# include <windows.h>
+#elif BOOST_OS_MACOS || BOOST_OS_IOS
+# include <mach-o/loader.h>
+# include <mach-o/nlist.h>
+#elif BOOST_OS_QNX
+// QNX's copy of <elf.h> and <link.h> reside in sys folder
+# include <sys/elf.h>
+#else
+ #include <elf.h>
+#endif
+
+namespace dd = boost::dll::detail;
+
+template <class T1, class T2>
+inline std::size_t get_offset(const T1& v1, const T2& v2) {
+ const unsigned char* p1 = reinterpret_cast<const unsigned char*>(&v1);
+ const unsigned char* p2 = reinterpret_cast<const unsigned char*>(&v2);
+
+ if (p1 < p2) {
+ return static_cast<std::size_t>(p2 - p1);
+ }
+
+ return static_cast<std::size_t>(p1 - p2);
+}
+
+#define CHECK_FIELD(Field) \
+ BOOST_STATIC_ASSERT(sizeof(v1.Field) == sizeof(v2.Field)); \
+ BOOST_TEST(get_offset(v1, v1.Field) == get_offset(v2, v2.Field)) \
+ /**/
+
+
+// ELF structures
+template <class T1, class T2>
+void elf_header_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(e_ident);
+ CHECK_FIELD(e_type);
+ CHECK_FIELD(e_machine);
+ CHECK_FIELD(e_version);
+ CHECK_FIELD(e_entry);
+ CHECK_FIELD(e_phoff);
+ CHECK_FIELD(e_shoff);
+ CHECK_FIELD(e_flags);
+ CHECK_FIELD(e_ehsize);
+ CHECK_FIELD(e_phentsize);
+ CHECK_FIELD(e_phnum);
+ CHECK_FIELD(e_shentsize);
+ CHECK_FIELD(e_shnum);
+ CHECK_FIELD(e_shstrndx);
+}
+
+template <class T1, class T2>
+void elf_sheader_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(sh_name);
+ CHECK_FIELD(sh_type);
+ CHECK_FIELD(sh_flags);
+ CHECK_FIELD(sh_addr);
+ CHECK_FIELD(sh_offset);
+ CHECK_FIELD(sh_size);
+ CHECK_FIELD(sh_link);
+ CHECK_FIELD(sh_info);
+ CHECK_FIELD(sh_addralign);
+ CHECK_FIELD(sh_entsize);
+}
+
+template <class T1, class T2>
+void elf_sym_header_checks(const T1& v1, const T2& v2) {
+ BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
+
+ CHECK_FIELD(st_name);
+ CHECK_FIELD(st_value);
+ CHECK_FIELD(st_size);
+ CHECK_FIELD(st_info);
+ CHECK_FIELD(st_other);
+ CHECK_FIELD(st_shndx);
+}
+
+
+// PE structures
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_DOS_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(e_magic);
+ CHECK_FIELD(e_cblp);
+ CHECK_FIELD(e_cp);
+ CHECK_FIELD(e_crlc);
+ CHECK_FIELD(e_cparhdr);
+ CHECK_FIELD(e_minalloc);
+ CHECK_FIELD(e_maxalloc);
+ CHECK_FIELD(e_ss);
+ CHECK_FIELD(e_sp);
+ CHECK_FIELD(e_csum);
+ CHECK_FIELD(e_ip);
+ CHECK_FIELD(e_cs);
+ CHECK_FIELD(e_lfarlc);
+ CHECK_FIELD(e_ovno);
+ CHECK_FIELD(e_res);
+ CHECK_FIELD(e_oemid);
+ CHECK_FIELD(e_oeminfo);
+ CHECK_FIELD(e_res2);
+ CHECK_FIELD(e_lfanew);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_FILE_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Machine);
+ CHECK_FIELD(NumberOfSections);
+ CHECK_FIELD(TimeDateStamp);
+ CHECK_FIELD(PointerToSymbolTable);
+ CHECK_FIELD(NumberOfSymbols);
+ CHECK_FIELD(SizeOfOptionalHeader);
+ CHECK_FIELD(Characteristics);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_DATA_DIRECTORY_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(VirtualAddress);
+ CHECK_FIELD(Size);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_EXPORT_DIRECTORY_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Characteristics);
+ CHECK_FIELD(TimeDateStamp);
+ CHECK_FIELD(MajorVersion);
+ CHECK_FIELD(MinorVersion);
+ CHECK_FIELD(Name);
+ CHECK_FIELD(Base);
+ CHECK_FIELD(NumberOfFunctions);
+ CHECK_FIELD(NumberOfNames);
+ CHECK_FIELD(AddressOfFunctions);
+ CHECK_FIELD(AddressOfNames);
+ CHECK_FIELD(AddressOfNameOrdinals);
+}
+
+
+template <class T>
+void generic_header_check(const T& v1, const dd::IMAGE_SECTION_HEADER_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Name);
+ CHECK_FIELD(VirtualAddress);
+ CHECK_FIELD(SizeOfRawData);
+ CHECK_FIELD(PointerToRawData);
+ CHECK_FIELD(PointerToRelocations);
+ CHECK_FIELD(PointerToLinenumbers);
+ CHECK_FIELD(NumberOfRelocations);
+ CHECK_FIELD(NumberOfLinenumbers);
+ CHECK_FIELD(Characteristics);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::IMAGE_OPTIONAL_HEADER_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Magic);
+ CHECK_FIELD(MajorLinkerVersion);
+ CHECK_FIELD(MinorLinkerVersion);
+ CHECK_FIELD(SizeOfCode);
+ CHECK_FIELD(SizeOfInitializedData);
+ CHECK_FIELD(SizeOfUninitializedData);
+ CHECK_FIELD(AddressOfEntryPoint);
+ CHECK_FIELD(ImageBase);
+ CHECK_FIELD(SectionAlignment);
+ CHECK_FIELD(FileAlignment);
+ CHECK_FIELD(MajorOperatingSystemVersion);
+ CHECK_FIELD(MinorOperatingSystemVersion);
+ CHECK_FIELD(MajorImageVersion);
+ CHECK_FIELD(MinorImageVersion);
+ CHECK_FIELD(MajorSubsystemVersion);
+ CHECK_FIELD(MinorSubsystemVersion);
+ CHECK_FIELD(Win32VersionValue);
+ CHECK_FIELD(SizeOfImage);
+ CHECK_FIELD(SizeOfHeaders);
+ CHECK_FIELD(CheckSum);
+ CHECK_FIELD(Subsystem);
+ CHECK_FIELD(DllCharacteristics);
+ CHECK_FIELD(SizeOfStackReserve);
+ CHECK_FIELD(SizeOfStackCommit);
+ CHECK_FIELD(SizeOfHeapReserve);
+ CHECK_FIELD(SizeOfHeapCommit);
+ CHECK_FIELD(LoaderFlags);
+ CHECK_FIELD(NumberOfRvaAndSizes);
+ CHECK_FIELD(DataDirectory);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::IMAGE_NT_HEADERS_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(Signature);
+ CHECK_FIELD(FileHeader);
+ CHECK_FIELD(OptionalHeader);
+}
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::mach_header_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(magic);
+ CHECK_FIELD(cputype);
+ CHECK_FIELD(cpusubtype);
+ CHECK_FIELD(filetype);
+ CHECK_FIELD(ncmds);
+ CHECK_FIELD(sizeofcmds);
+ //CHECK_FIELD(flags);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::segment_command_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+ CHECK_FIELD(segname);
+ CHECK_FIELD(vmaddr);
+ CHECK_FIELD(vmsize);
+ CHECK_FIELD(fileoff);
+ CHECK_FIELD(filesize);
+ CHECK_FIELD(maxprot);
+ CHECK_FIELD(initprot);
+ CHECK_FIELD(nsects);
+ CHECK_FIELD(flags);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::section_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(sectname);
+ CHECK_FIELD(segname);
+ CHECK_FIELD(addr);
+ CHECK_FIELD(size);
+ CHECK_FIELD(offset);
+ CHECK_FIELD(align);
+ CHECK_FIELD(reloff);
+ CHECK_FIELD(nreloc);
+ CHECK_FIELD(flags);
+ //CHECK_FIELD(reserved vs reserveed1&reserved2);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::symtab_command_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+ CHECK_FIELD(symoff);
+ CHECK_FIELD(nsyms);
+ CHECK_FIELD(stroff);
+ CHECK_FIELD(strsize);
+}
+
+template <class T, class AddrT>
+void generic_header_check(const T& v1, const dd::nlist_template<AddrT>& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ //CHECK_FIELD(n_strx);
+ CHECK_FIELD(n_type);
+ CHECK_FIELD(n_sect);
+ CHECK_FIELD(n_desc);
+ CHECK_FIELD(n_value);
+}
+
+template <class T>
+void generic_header_check(const T& v1, const dd::load_command_& v2) {
+ BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
+
+ CHECK_FIELD(cmd);
+ CHECK_FIELD(cmdsize);
+}
+
+
+
+// Unit Tests
+int main(int /*argc*/, char* /*argv*/[]) {
+
+#if BOOST_OS_WINDOWS
+ generic_header_check(::IMAGE_DOS_HEADER(), dd::IMAGE_DOS_HEADER_());
+ generic_header_check(::IMAGE_FILE_HEADER(), dd::IMAGE_FILE_HEADER_());
+ generic_header_check(::IMAGE_DATA_DIRECTORY(), dd::IMAGE_DATA_DIRECTORY_());
+ generic_header_check(::IMAGE_EXPORT_DIRECTORY(), dd::IMAGE_EXPORT_DIRECTORY_());
+ generic_header_check(::IMAGE_SECTION_HEADER(), dd::IMAGE_SECTION_HEADER_());
+ generic_header_check(::IMAGE_OPTIONAL_HEADER32(), dd::IMAGE_OPTIONAL_HEADER32_());
+ generic_header_check(::IMAGE_OPTIONAL_HEADER64(), dd::IMAGE_OPTIONAL_HEADER64_());
+ generic_header_check(::IMAGE_NT_HEADERS32(), dd::IMAGE_NT_HEADERS32_());
+ generic_header_check(::IMAGE_NT_HEADERS64(), dd::IMAGE_NT_HEADERS64_());
+#elif BOOST_OS_MACOS || BOOST_OS_IOS
+ generic_header_check(::mach_header(), dd::mach_header_32_());
+ generic_header_check(::mach_header_64(), dd::mach_header_64_());
+
+ generic_header_check(::segment_command(), dd::segment_command_32_());
+ generic_header_check(::segment_command_64(), dd::segment_command_64_());
+
+ generic_header_check(::section(), dd::section_32_());
+ generic_header_check(::section_64(), dd::section_64_());
+
+ generic_header_check(::load_command(), dd::load_command_());
+ generic_header_check(::symtab_command(), dd::symtab_command_());
+
+ struct ::nlist nl32_var;
+ generic_header_check(nl32_var, dd::nlist_32_());
+ struct ::nlist_64 nl64_var;
+ generic_header_check(nl64_var, dd::nlist_64_());
+
+#else
+ elf_header_checks(::Elf32_Ehdr(), dd::Elf32_Ehdr_());
+ elf_header_checks(::Elf64_Ehdr(), dd::Elf64_Ehdr_());
+
+ elf_sheader_checks(::Elf32_Shdr(), dd::Elf32_Shdr_());
+ elf_sheader_checks(::Elf64_Shdr(), dd::Elf64_Shdr_());
+
+ elf_sym_header_checks(::Elf32_Sym(), dd::Elf32_Sym_());
+ elf_sym_header_checks(::Elf64_Sym(), dd::Elf64_Sym_());
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/symbol_runtime_info_test.cpp b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp
new file mode 100644
index 000000000..bfeb69bf6
--- /dev/null
+++ b/src/boost/libs/dll/test/symbol_runtime_info_test.cpp
@@ -0,0 +1,231 @@
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/dll.hpp>
+#include <boost/dll/runtime_symbol_info.hpp>
+#include <boost/filesystem/operations.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <boost/predef/os.h>
+
+
+#include <cmath>
+#include <exception> // std::set_terminate
+#include <signal.h> // ::signal
+
+// Makes global error variables dirty. Useful for preventing issues like https://github.com/boostorg/dll/issues/16
+void make_error_code_dirty() {
+ using namespace std;
+ (void)log(-1.0);
+
+#if BOOST_OS_WINDOWS
+ boost::winapi::WCHAR_ path_hldr[10];
+ int some_invalid_value_for_handle = 0xFF004242;
+ boost::winapi::HMODULE_ some_invalid_handle;
+ memcpy(&some_invalid_handle, &some_invalid_value_for_handle, sizeof(some_invalid_value_for_handle));
+ boost::winapi::GetModuleFileNameW(some_invalid_handle, path_hldr, 10);
+#endif
+}
+
+
+
+// lib functions
+
+typedef float (lib_version_func)();
+typedef void (say_hello_func) ();
+typedef int (increment) (int);
+
+// exe function
+extern "C" int BOOST_SYMBOL_EXPORT exef() {
+ return 15;
+}
+
+
+extern "C" void BOOST_SYMBOL_EXPORT my_terminate_handler() {
+ std::abort();
+}
+
+extern "C" void BOOST_SYMBOL_EXPORT my_signal_handler(int) {
+ std::abort();
+}
+
+void internal_function() {}
+int internal_variable = 1;
+
+// Unit Tests
+int main(int argc, char* argv[]) {
+ using namespace boost::dll;
+
+ boost::dll::fs::path shared_library_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ BOOST_TEST(shared_library_path.string().find("test_library") != std::string::npos);
+
+ make_error_code_dirty();
+
+ shared_library lib(shared_library_path);
+
+ std::cout << std::endl;
+ std::cout << "shared_library: " << shared_library_path << std::endl;
+ std::cout << "symbol_location: " << symbol_location(lib.get<int>("integer_g")) << std::endl;
+ std::cout << "lib.location(): " << lib.location() << std::endl;
+ BOOST_TEST(
+ symbol_location(lib.get<int>("integer_g")) == lib.location()
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ symbol_location(lib.get<say_hello_func>("say_hello")) == lib.location()
+ );
+
+ BOOST_TEST(
+ symbol_location(lib.get<lib_version_func>("lib_version")) == lib.location()
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ symbol_location(lib.get<const int>("const_integer_g")) == lib.location()
+ );
+
+ // Checking that symbols are still available, after another load+unload of the library
+ { shared_library sl2(shared_library_path); }
+
+ BOOST_TEST(
+ symbol_location(lib.get<int>("integer_g")) == lib.location()
+ );
+
+
+ make_error_code_dirty();
+
+ // Checking aliases
+ BOOST_TEST(
+ symbol_location(lib.get<std::size_t(*)(const std::vector<int>&)>("foo_bar")) == lib.location()
+ );
+ BOOST_TEST(
+ symbol_location(lib.get_alias<std::size_t(const std::vector<int>&)>("foo_bar")) == lib.location()
+ );
+
+
+ BOOST_TEST(
+ symbol_location(lib.get<std::size_t*>("foo_variable")) == lib.location()
+ );
+ BOOST_TEST(
+ symbol_location(lib.get_alias<std::size_t>("foo_variable")) == lib.location()
+ );
+
+ { // self
+
+ make_error_code_dirty();
+
+ shared_library sl(program_location());
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef")), argv[0]))
+ );
+ }
+
+ { // self with error_code
+ boost::dll::fs::error_code ec;
+ shared_library sl(program_location(ec));
+ BOOST_TEST(!ec);
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(sl.get<int(void)>("exef"), ec), argv[0]))
+ );
+ BOOST_TEST(!ec);
+
+ symbol_location(&sl.get<int(void)>("exef"), ec);
+ BOOST_TEST(ec);
+ }
+
+ std::cout << "\ninternal_function: " << symbol_location(internal_function);
+ std::cout << "\nargv[0] : " << boost::filesystem::absolute(argv[0]);
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(internal_function), argv[0]))
+ );
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(symbol_location(internal_variable), argv[0]))
+ );
+
+ make_error_code_dirty();
+
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(this_line_location(), argv[0]))
+ );
+
+ { // this_line_location with error_code
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ BOOST_TEST(
+ (boost::dll::fs::equivalent(this_line_location(ec), argv[0]))
+ );
+ BOOST_TEST(!ec);
+ }
+
+ BOOST_TEST(
+ lib.get_alias<boost::dll::fs::path()>("module_location_from_itself")() == lib.location()
+ );
+
+ // Checking docs content
+ std::cout << "\nsymbol_location(std::cerr); // " << symbol_location(std::cerr);
+ std::cout << "\nsymbol_location(std::puts); // " << symbol_location(std::puts);
+
+ std::set_terminate(&my_terminate_handler);
+ BOOST_TEST((boost::dll::fs::equivalent(
+ symbol_location_ptr(std::set_terminate(0)),
+ argv[0]
+ )));
+
+ {
+ boost::dll::fs::error_code ec;
+ boost::dll::fs::path p = symbol_location_ptr(std::set_terminate(0), ec);
+ BOOST_TEST(ec || !p.empty());
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ symbol_location(std::set_terminate(0), ec),
+ BOOST_TEST(ec);
+ }
+
+ {
+ std::set_terminate(&my_terminate_handler);
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ symbol_location(std::set_terminate(0), ec),
+ BOOST_TEST(ec);
+ }
+
+ {
+ boost::dll::fs::error_code ec;
+ ::signal(SIGSEGV, &my_signal_handler);
+ boost::dll::fs::path p = symbol_location_ptr(::signal(SIGSEGV, SIG_DFL), ec);
+ BOOST_TEST((boost::dll::fs::equivalent(
+ p,
+ argv[0]
+ )) || ec);
+ }
+
+ {
+ ::signal(SIGSEGV, &my_signal_handler);
+ boost::dll::fs::error_code ec;
+ make_error_code_dirty();
+ symbol_location(::signal(SIGSEGV, SIG_DFL), ec);
+ BOOST_TEST(ec);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/dll/test/template_method_linux_test.cpp b/src/boost/libs/dll/test/template_method_linux_test.cpp
new file mode 100644
index 000000000..cb4969609
--- /dev/null
+++ b/src/boost/libs/dll/test/template_method_linux_test.cpp
@@ -0,0 +1,67 @@
+// Copyright 2019 Ramil Gauss.
+// Copyright 2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/predef.h>
+#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
+
+#include <boost/dll/smart_library.hpp>
+#include <boost/dll/import_mangled.hpp>
+#include <boost/dll/import_class.hpp>
+
+#include <iostream>
+#include <string>
+
+#include "../example/b2_workarounds.hpp"
+#include <boost/core/lightweight_test.hpp>
+
+
+namespace space {
+ class BOOST_SYMBOL_EXPORT my_plugin {
+ public:
+ template <typename Arg>
+ BOOST_SYMBOL_EXPORT int Func(); // defined in cpp_test_library.cpp
+ };
+}
+
+int main(int argc, char** argv) {
+ unsigned matches_found = 0;
+ boost::dll::fs::path lib_path = b2_workarounds::first_lib_from_argv(argc, argv);
+ boost::dll::experimental::smart_library lib(lib_path);
+
+ auto storage = lib.symbol_storage().get_storage();
+ for (auto& s : storage) {
+ auto& demangled = s.demangled;
+ BOOST_TEST(demangled.data());
+
+ auto beginFound = demangled.find("Func<");
+ if (beginFound == std::string::npos)
+ continue;
+
+ auto endFound = demangled.find("(");
+ if (endFound == std::string::npos)
+ continue;
+
+ // Usually "Func<space::my_plugin>" on Linux, "Func<class space::my_plugin>" on Windows.
+ auto funcName = demangled.substr(beginFound, endFound - beginFound);
+ std::cout << "Function name: " << funcName.data() << std::endl;
+ auto typeIndexFunc = boost::dll::experimental::import_mangled<space::my_plugin, int()>(lib, funcName);
+
+ space::my_plugin cl;
+ BOOST_TEST_EQ(typeIndexFunc(&cl), 42);
+
+ ++matches_found;
+ break;
+ }
+ BOOST_TEST_EQ(matches_found, 1);
+
+ return boost::report_errors();
+}
+
+
+#else
+int main() {}
+#endif
diff --git a/src/boost/libs/dll/test/test_library.cpp b/src/boost/libs/dll/test/test_library.cpp
new file mode 100644
index 000000000..fee07c629
--- /dev/null
+++ b/src/boost/libs/dll/test/test_library.cpp
@@ -0,0 +1,115 @@
+// Copyright 2011-2012 Renato Tegon Forti
+// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
+// Copyright 2015-2019 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// MinGW related workaround
+#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
+
+#include <boost/dll/config.hpp>
+#include <boost/dll/alias.hpp>
+#include <iostream>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/fusion/container.hpp>
+
+#define LIBRARY_API BOOST_SYMBOL_EXPORT
+
+extern "C" void LIBRARY_API say_hello(void);
+extern "C" float LIBRARY_API lib_version(void);
+extern "C" int LIBRARY_API increment(int);
+
+extern "C" int LIBRARY_API integer_g;
+extern "C" const int LIBRARY_API const_integer_g = 777;
+
+namespace foo {
+ std::size_t bar(const std::vector<int>& v) {
+ return v.size();
+ }
+
+ std::size_t variable = 42;
+}
+
+
+
+// Make sure that aliases have no problems with memory allocations and different types of input parameters
+namespace namespace1 { namespace namespace2 { namespace namespace3 {
+ typedef
+ boost::fusion::vector<std::vector<int>, std::vector<int>, std::vector<int>, const std::vector<int>*, std::vector<int>* >
+ do_share_res_t;
+
+ boost::shared_ptr<do_share_res_t> do_share(
+ std::vector<int> v1,
+ std::vector<int>& v2,
+ const std::vector<int>& v3,
+ const std::vector<int>* v4,
+ std::vector<int>* v5
+ )
+ {
+ v2.back() = 777;
+ v5->back() = 9990;
+ return boost::make_shared<do_share_res_t>(v1, v2, v3, v4, v5);
+ }
+
+ std::string info("I am a std::string from the test_library (Think of me as of 'Hello world'. Long 'Hello world').");
+
+ int& ref_returning_function() {
+ static int i = 0;
+ return i;
+ }
+}}}
+
+
+
+BOOST_DLL_ALIAS(foo::bar, foo_bar)
+BOOST_DLL_ALIAS(foo::variable, foo_variable)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::do_share, do_share)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::info, info)
+BOOST_DLL_ALIAS(const_integer_g, const_integer_g_alias)
+BOOST_DLL_ALIAS(namespace1::namespace2::namespace3::ref_returning_function, ref_returning_function)
+
+
+
+int integer_g = 100;
+
+void say_hello(void)
+{
+ std::cout << "Hello, Boost.Application!" << std::endl;
+}
+
+float lib_version(void)
+{
+ return 1.0;
+}
+
+int increment(int n)
+{
+ return ++n;
+}
+
+#include <boost/dll/runtime_symbol_info.hpp>
+
+boost::dll::fs::path this_module_location_from_itself() {
+ return boost::dll::this_line_location();
+}
+
+BOOST_DLL_ALIAS(this_module_location_from_itself, module_location_from_itself)
+
+
+
+int internal_integer_i = 0xFF0000;
+extern "C" LIBRARY_API int& reference_to_internal_integer;
+int& reference_to_internal_integer = internal_integer_i;
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+extern "C" LIBRARY_API int&& rvalue_reference_to_internal_integer;
+int&& rvalue_reference_to_internal_integer = static_cast<int&&>(internal_integer_i);
+#endif
+