From de905f331abdfac9aabe895b2bbbf1fbca71a002 Mon Sep 17 00:00:00 2001 From: "R. Savchenko" Date: Tue, 7 Jul 2026 11:23:51 +0200 Subject: [PATCH] smart_library correct constructors from shared_library (#114) --- include/boost/dll/smart_library.hpp | 37 ++++++++------- test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/smart_library_test.cpp | 70 +++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 test/smart_library_test.cpp diff --git a/include/boost/dll/smart_library.hpp b/include/boost/dll/smart_library.hpp index 2ad121f..cd73475 100644 --- a/include/boost/dll/smart_library.hpp +++ b/include/boost/dll/smart_library.hpp @@ -151,23 +151,26 @@ public: * * \throw Nothing. */ - explicit smart_library(const shared_library & lib) noexcept - : lib_(lib) - { - storage_.load(lib.location()); - } - /*! - * Construct from a shared_library object. - * - * \param lib A shared_library to move from. - * - * \throw Nothing. - */ - explicit smart_library(shared_library&& lib) noexcept - : lib_(std::move(lib)) - { - storage_.load(lib.location()); - } + explicit smart_library(const shared_library & lib) noexcept + : lib_(lib) { + if (lib_.is_loaded()) { + storage_.load(lib_.location()); + } + } + /*! + * Construct from a shared_library object. + * + * \param lib A shared_library to move from. + * + * \throw Nothing. + */ + explicit smart_library(shared_library&& lib) noexcept + : lib_(std::move(lib)) + { + if (lib_.is_loaded()) { + storage_.load(lib_.location()); + } + } /*! * Destroys the smart_library. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1bd2f2a..089ea65 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -116,6 +116,7 @@ boost_dll_add_test(dll_test_cpp_mangle cpp_mangle_test.cpp #[[export_symbols=]] target_link_libraries(dll_test_cpp_mangle PRIVATE Boost::variant) boost_dll_add_test(dll_test_cpp_load cpp_load_test.cpp #[[export_symbols=]] FALSE dll_cpp_plugin) target_link_libraries(dll_test_cpp_load PRIVATE Boost::variant) +boost_dll_add_test(dll_test_smart_library smart_library_test.cpp #[[export_symbols=]] FALSE dll_cpp_plugin) boost_dll_add_test(dll_test_cpp_import cpp_import_test.cpp #[[export_symbols=]] FALSE dll_cpp_plugin) target_link_libraries(dll_test_cpp_import PRIVATE Boost::variant) if(LINUX) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e743ed4..32fb69b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -105,6 +105,7 @@ project [ run cpp_mangling.cpp ] [ compile-fail cpp_mangling1_cf.cpp ] [ run cpp_load_test.cpp : : cpp_plugin ] + [ run smart_library_test.cpp : : cpp_plugin ] [ run cpp_import_test.cpp : : cpp_plugin ] [ run template_method_linux_test.cpp : : cpp_plugin ] # TODO: uncomment (fails on some MSVCs and Clang-5) diff --git a/test/smart_library_test.cpp b/test/smart_library_test.cpp new file mode 100644 index 0000000..f103c56 --- /dev/null +++ b/test/smart_library_test.cpp @@ -0,0 +1,70 @@ +// Copyright 2026 Roman Savchenko +// +// 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 +#include + +#include "../example/b2_workarounds.hpp" + +#include +#include + +#include + +#include + +// Test for smart_library construction from empty/unloaded shared_library objects. +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; + + { + shared_library empty_lib; + BOOST_TEST(!empty_lib.is_loaded()); + + // Should not access location() for an unloaded library. + smart_library sm(empty_lib); + BOOST_TEST(!sm.is_loaded()); + } + + { + shared_library lib(pt); + BOOST_TEST(lib.is_loaded()); + + shared_library moved_to = std::move(lib); + BOOST_TEST(!lib.is_loaded()); + BOOST_TEST(moved_to.is_loaded()); + + // Should not access location() for a moved-from library. + smart_library sm(std::move(lib)); + BOOST_TEST(!sm.is_loaded()); + } + + { + shared_library lib(pt); + BOOST_TEST(lib.is_loaded()); + + smart_library sm(lib); + BOOST_TEST(sm.is_loaded()); + } + + { + shared_library lib(pt); + BOOST_TEST(lib.is_loaded()); + + smart_library sm(std::move(lib)); + BOOST_TEST(sm.is_loaded()); + } + + return boost::report_errors(); +}