Skip to content

Commit

Permalink
Switch to std::shared_ptr from boost::shared_ptr and provide a BOOST_…
Browse files Browse the repository at this point in the history
…DLL_USE_BOOST_SHARED_PTR compatibility macro to restore the old behavior
  • Loading branch information
apolukhin committed Jan 28, 2025
1 parent 841e188 commit 65a239d
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 46 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ target_link_libraries(boost_dll
Boost::core
Boost::filesystem
Boost::predef
Boost::smart_ptr
Boost::system
Boost::throw_exception
Boost::type_index
Expand Down
1 change: 0 additions & 1 deletion build.jam
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ constant boost_dependencies :
/boost/core//boost_core
/boost/filesystem//boost_filesystem
/boost/predef//boost_predef
/boost/smart_ptr//boost_smart_ptr
/boost/system//boost_system
/boost/throw_exception//boost_throw_exception
/boost/type_index//boost_type_index
Expand Down
4 changes: 2 additions & 2 deletions example/getting_started.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {

//[getting_started_imports_c_variable
// Importing pure C variable
shared_ptr<int> c_var = dll::import_symbol<int>(
std::shared_ptr<int> c_var = dll::import_symbol<int>(
path_to_shared_library, "c_variable_name"
);
//]
Expand Down Expand Up @@ -64,7 +64,7 @@ int main(int argc, char* argv[]) {

//[getting_started_imports_cpp_variable
// Importing variable.
shared_ptr<std::string> cpp_var = dll::import_symbol<std::string>(
std::shared_ptr<std::string> cpp_var = dll::import_symbol<std::string>(
path_to_shared_library, "cpp_variable_name"
);
//]
Expand Down
28 changes: 28 additions & 0 deletions include/boost/dll/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
/// Define this macro to make Boost.DLL use C++17's std::filesystem::path and std::system_error.
#define BOOST_DLL_USE_STD_FS BOOST_DLL_USE_STD_FS

/// Define this macro to make Boost.DLL use boost::shared_ptr instead of std::shared_ptr. This macro will be removed
/// after a few releases, consider migrating to std::shared_ptr.
#define BOOST_DLL_USE_BOOST_SHARED_PTR BOOST_DLL_USE_BOOST_SHARED_PTR

/// This namespace contains aliases to the Boost or C++17 classes. Aliases are configured using BOOST_DLL_USE_STD_FS macro.
namespace boost { namespace dll { namespace fs {

Expand Down Expand Up @@ -69,5 +73,29 @@ using boost::system::system_error;

#endif // BOOST_DLL_USE_STD_FS


#ifdef BOOST_DLL_USE_BOOST_SHARED_PTR

#include <boost/make_shared.hpp>

namespace boost { namespace dll { namespace detail {
template <class T>
using shared_ptr = boost::shared_ptr<T>;
using boost::make_shared;

}}}

#else // BOOST_DLL_USE_STD_FS

#include <memory>

namespace boost { namespace dll { namespace detail {
template <class T>
using shared_ptr = std::shared_ptr<T>;
using std::make_shared;
}}}

#endif // BOOST_DLL_USE_STD_FS

#endif // BOOST_DLL_DETAIL_PUSH_OPTIONS_HPP

36 changes: 19 additions & 17 deletions include/boost/dll/import.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#define BOOST_DLL_IMPORT_HPP

#include <boost/dll/config.hpp>
#include <boost/make_shared.hpp>
#include <boost/dll/shared_library.hpp>

#include <memory> // std::addressof
Expand All @@ -32,10 +31,10 @@ namespace detail {
template <class T>
class library_function {
// Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
boost::shared_ptr<T> f_;
boost::dll::detail::shared_ptr<T> f_;

public:
inline library_function(const boost::shared_ptr<shared_library>& lib, T* func_ptr) noexcept
inline library_function(const boost::dll::detail::shared_ptr<shared_library>& lib, T* func_ptr) noexcept
: f_(lib, func_ptr)
{}

Expand All @@ -55,11 +54,10 @@ namespace detail {
}
};


template <class T>
using import_type = typename std::conditional<
std::is_object<T>::value,
boost::shared_ptr<T>,
boost::dll::detail::shared_ptr<T>,
boost::dll::detail::library_function<T>
>::type;
} // namespace detail
Expand All @@ -71,7 +69,8 @@ namespace detail {


/*!
* Returns callable object or boost::shared_ptr<T> that holds the symbol imported
* Returns callable object or std::shared_ptr<T> (boost::shared_ptr<T> if
* BOOST_DLL_USE_BOOST_SHARED_PTR is defined) that holds the symbol imported
* from the loaded library. Returned value refcounts usage
* of the loaded shared library, so that it won't get unload until all copies of return value
* are not destroyed.
Expand All @@ -90,7 +89,7 @@ namespace detail {
* \endcode
*
* \code
* boost::shared_ptr<int> i = import_symbol<int>("test_lib.so", "integer_name");
* std::shared_ptr<int> i = import_symbol<int>("test_lib.so", "integer_name");
* \endcode
*
* \b Template \b parameter \b T: Type of the symbol that we are going to import. Must be explicitly specified.
Expand All @@ -99,7 +98,8 @@ namespace detail {
* \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*.
* \param mode An mode that will be used on library load.
*
* \return callable object if T is a function type, or boost::shared_ptr<T> if T is an object type.
* \return callable object if T is a function type, or std::shared_ptr<T> (boost::shared_ptr<T> if
* BOOST_DLL_USE_BOOST_SHARED_PTR is defined) if T is an object type.
*
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
Expand All @@ -110,7 +110,7 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, cons
{
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib, mode);
return type(p, std::addressof(p->get<T>(name)));
}

Expand All @@ -127,7 +127,7 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(lib);
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib);
return type(p, std::addressof(p->get<T>(name)));
}

Expand All @@ -142,7 +142,7 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(
std::move(lib)
);
return type(p, std::addressof(p->get<T>(name)));
Expand All @@ -158,7 +158,8 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::stri


/*!
* Returns callable object or boost::shared_ptr<T> that holds the symbol imported
* Returns callable object or std::shared_ptr<T> (boost::shared_ptr<T> if
* BOOST_DLL_USE_BOOST_SHARED_PTR is defined) that holds the symbol imported
* from the loaded library. Returned value refcounts usage
* of the loaded shared library, so that it won't get unload until all copies of return value
* are not destroyed.
Expand All @@ -177,7 +178,7 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::stri
* \endcode
*
* \code
* boost::shared_ptr<int> i = import_alias<int>("test_lib.so", "integer_alias_name");
* std::shared_ptr<int> i = import_alias<int>("test_lib.so", "integer_alias_name");
* \endcode
*
* \code
Expand All @@ -189,7 +190,8 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::stri
* \param name Null-terminated C or C++ mangled name of the function or variable to import. Can handle std::string, char*, const char*.
* \param mode An mode that will be used on library load.
*
* \return callable object if T is a function type, or boost::shared_ptr<T> if T is an object type.
* \return callable object if T is a function type, or std::shared_ptr<T> (boost::shared_ptr<T> if
* BOOST_DLL_USE_BOOST_SHARED_PTR is defined) if T is an object type.
*
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
Expand All @@ -200,7 +202,7 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const
{
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib, mode);
return type(p, p->get<T*>(name));
}

Expand All @@ -217,7 +219,7 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(lib);
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib);
return type(p, p->get<T*>(name));
}

Expand All @@ -232,7 +234,7 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;

auto p = boost::make_shared<boost::dll::shared_library>(
auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(
std::move(lib)
);
return type(p, p->get<T*>(name));
Expand Down
26 changes: 13 additions & 13 deletions include/boost/dll/import_mangled.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# error This file requires C++11 at least!
#endif

#include <boost/make_shared.hpp>
#include <boost/dll/config.hpp>
#include <boost/dll/smart_library.hpp>
#include <boost/dll/detail/import_mangled_helpers.hpp>

Expand All @@ -39,10 +39,10 @@ namespace detail
template <class ... Ts>
class mangled_library_function {
// Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
boost::shared_ptr<shared_library> lib_;
boost::dll::detail::shared_ptr<shared_library> lib_;
function_tuple<Ts...> f_;
public:
constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) noexcept
constexpr mangled_library_function(const boost::dll::detail::shared_ptr<shared_library>& lib, Ts*... func_ptr) noexcept
: lib_(lib)
, f_(func_ptr...)
{}
Expand Down Expand Up @@ -72,11 +72,11 @@ template <class Class, class ... Ts>
class mangled_library_mem_fn<Class, sequence<Ts...>> {
// Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
typedef mem_fn_tuple<Ts...> call_tuple_t;
boost::shared_ptr<shared_library> lib_;
boost::dll::detail::shared_ptr<shared_library> lib_;
call_tuple_t f_;

public:
constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) noexcept
constexpr mangled_library_mem_fn(const boost::dll::detail::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) noexcept
: lib_(lib)
, f_(func_ptr...)
{}
Expand Down Expand Up @@ -111,7 +111,7 @@ struct mangled_import_type<sequence<Args...>, true,false,false> //is function
const std::string& name)
{
return type(
boost::make_shared<shared_library>(p.shared_lib()),
boost::dll::detail::make_shared<shared_library>(p.shared_lib()),
std::addressof(p.get_function<Args>(name))...);
}
};
Expand All @@ -129,7 +129,7 @@ struct mangled_import_type<sequence<Class, Args...>, false, true, false> //is me
const std::string & name,
sequence<ArgsIn...> * )
{
return type(boost::make_shared<shared_library>(p.shared_lib()),
return type(boost::dll::detail::make_shared<shared_library>(p.shared_lib()),
p.get_mem_fn<typename ArgsIn::class_type, typename ArgsIn::func_type>(name)...);
}

Expand All @@ -145,14 +145,14 @@ struct mangled_import_type<sequence<Class, Args...>, false, true, false> //is me
template <class T>
struct mangled_import_type<sequence<T>, false, false, true> //is variable
{
typedef boost::shared_ptr<T> type;
typedef boost::dll::detail::shared_ptr<T> type;

static type make(
const boost::dll::experimental::smart_library& p,
const std::string& name)
{
return type(
boost::make_shared<shared_library>(p.shared_lib()),
boost::dll::detail::make_shared<shared_library>(p.shared_lib()),
std::addressof(p.get_variable<T>(name)));
}

Expand All @@ -175,7 +175,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
*/

/*!
* Returns callable object or boost::shared_ptr<T> that holds the symbol imported
* Returns callable object or boost::dll::detail::shared_ptr<T> that holds the symbol imported
* from the loaded library. Returned value refcounts usage
* of the loaded shared library, so that it won't get unload until all copies of return value
* are not destroyed.
Expand All @@ -191,7 +191,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
* \endcode
*
* \code
* boost::shared_ptr<int> i = import_mangled<int>("test_lib.so", "integer_name");
* boost::dll::detail::shared_ptr<int> i = import_mangled<int>("test_lib.so", "integer_name");
* \endcode
*
* Additionally you can also import overloaded symbols, including member-functions.
Expand All @@ -218,7 +218,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
* \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*.
* \param mode An mode that will be used on library load.
*
* \return callable object if T is a function type, or boost::shared_ptr<T> if T is an object type.
* \return callable object if T is a function type, or boost::dll::detail::shared_ptr<T> if T is an object type.
*
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
Expand Down Expand Up @@ -280,7 +280,7 @@ template <class ...Args>
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;

boost::shared_ptr<boost::dll::experimental::smart_library> p = boost::make_shared<boost::dll::experimental::smart_library>(lib);
boost::dll::detail::shared_ptr<boost::dll::experimental::smart_library> p = boost::dll::detail::make_shared<boost::dll::experimental::smart_library>(lib);
return type::boostmake(p, name);
}

Expand Down
2 changes: 2 additions & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ project
<local-visibility>hidden
<library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system
<library>/boost/smart_ptr//boost_smart_ptr
<threading>multi
<define>BOOST_SYSTEM_NO_DEPRECATED
;
Expand Down Expand Up @@ -80,6 +81,7 @@ project
[ run empty_library_info_test.cpp : : empty_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/tutorial1/tutorial1.cpp : : my_plugin_sum : <link>shared <define>BOOST_DLL_USE_BOOST_SHARED_PTR : tutorial1_boost_shared_ptr ]
[ 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
Expand Down
Loading

0 comments on commit 65a239d

Please sign in to comment.