2
0
mirror of https://github.com/boostorg/dll.git synced 2026-01-19 04:12:08 +00:00

Merge branch 'develop' of github.com:boostorg/dll into HEAD

This commit is contained in:
Antony Polukhin
2024-12-20 16:53:55 +03:00
53 changed files with 935 additions and 875 deletions

View File

@@ -18,15 +18,11 @@ target_link_libraries(boost_dll
Boost::config
Boost::core
Boost::filesystem
Boost::function
Boost::move
Boost::predef
Boost::smart_ptr
Boost::spirit
Boost::system
Boost::throw_exception
Boost::type_index
Boost::type_traits
Boost::winapi
)

View File

@@ -10,15 +10,11 @@ constant boost_dependencies :
/boost/config//boost_config
/boost/core//boost_core
/boost/filesystem//boost_filesystem
/boost/function//boost_function
/boost/move//boost_move
/boost/predef//boost_predef
/boost/smart_ptr//boost_smart_ptr
/boost/spirit//boost_spirit
/boost/system//boost_system
/boost/throw_exception//boost_throw_exception
/boost/type_index//boost_type_index
/boost/type_traits//boost_type_traits
/boost/winapi//boost_winapi ;
project /boost/dll

View File

@@ -35,15 +35,8 @@ local doxygen_params =
\"forcedlinkfs{1}=\\xmlonly<link linkend='boost.dll.fs.\\1'>boost::dll::fs::\\1</link>\\endxmlonly\" \\
\"forcedmacrolink{1}=\\xmlonly<link linkend='\\1'>\\1</link>\\endxmlonly\" "
<doxygen:param>"PREDEFINED= \\
\"BOOST_RV_REF(T)=T&&\" \\
\"BOOST_RV_REF(shared_library)=shared_library&&\" \\
\"BOOST_COPY_ASSIGN_REF(shared_library)=const shared_library&\" \\
\"BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library)= \\
shared_library(const shared_library&) = delete; \\
shared_library& operator=(const shared_library&) = delete; \" \\
\"BOOST_DLL_IMPORT_RESULT_TYPE=result_type\" \\
\"BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE=result_type\" \\
\"BOOST_EXPLICIT_OPERATOR_BOOL()=explicit operator bool() const noexcept;\" \\
\"BOOST_DLL_DOXYGEN\" "
;

View File

@@ -10,12 +10,11 @@
The Boost.DLL is a header only library, but it depends on the following libraries
and they must be available in order to compile programs that use Boost.DLL:
* Boost.System for the boost::system::error_code and boost::system::system_error classes.
* Boost.System for the boost::system::system_error class.
* Boost.Filesystem for directory manipulation.
Refcountable part of Boost.DLL also depends on:
* Boost.Function for creation of a callback system.
* Boost.SharedPtr for reference counting.
[endsect]

View File

@@ -17,7 +17,7 @@ boost::dll::shared_library lib("/test/boost/application/libtest_library.so");
Now you can easily import symbols from that library using the `get` and `get_alias` member functions:
```
int plugin_constant = lib.get<const int>("integer_variable");
boost::function<int()> f = lib.get<int()>("function_returning_int");
auto function_ptr = lib.get<int()>("function_returning_int");
int& i = lib.get_alias<int>("alias_to_int_variable");
```
In case of `boost::dll::shared_library` it is safe to use imported symbols only until `boost::dll::shared_library`

View File

@@ -19,10 +19,9 @@ int main(int argc, char* argv[]) {
/*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
boost::dll::fs::path shared_library_path(argv[1]); // argv[1] contains path to directory with our plugin library
shared_library_path /= "my_plugin_aggregator";
typedef boost::shared_ptr<my_plugin_api> (pluginapi_create_t)();
boost::function<pluginapi_create_t> creator;
creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
auto creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
shared_library_path, // path to library
"create_plugin", // symbol to import
dll::load_mode::append_decorations // do append extensions and prefixes

View File

@@ -27,9 +27,10 @@ std::size_t search_for_symbols(const std::vector<boost::dll::fs::path>& plugins)
}
// library has symbol, importing...
typedef boost::shared_ptr<my_plugin_api> (pluginapi_create_t)();
boost::function<pluginapi_create_t> creator
= dll::import_alias<pluginapi_create_t>(boost::move(lib), "create_plugin");
using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
auto creator = dll::import_alias<pluginapi_create_t>(
std::move(lib), "create_plugin"
);
std::cout << "Matching plugin name: " << creator()->name() << std::endl;
++ plugins_found;

View File

@@ -21,8 +21,7 @@ int main() {
dll::shared_library self(dll::program_location());
std::cout << "Call function" << std::endl;
boost::function<boost::shared_ptr<my_plugin_api>()> creator
= self.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin");
auto creator = self.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin");
std::cout << "Computed Value: " << creator()->calculate(2, 2) << std::endl;
//<-

View File

@@ -22,7 +22,7 @@ namespace dll = boost::dll;
class plugins_collector {
// Name => plugin
typedef boost::container::map<std::string, dll::shared_library> plugins_t;
using plugins_t = boost::container::map<std::string, dll::shared_library>;
boost::dll::fs::path plugins_directory_;
plugins_t plugins_;
@@ -32,7 +32,7 @@ class plugins_collector {
// Gets `my_plugin_api` instance using "create_plugin" or "plugin" imports,
// stores plugin with its name in the `plugins_` map.
void insert_plugin(BOOST_RV_REF(dll::shared_library) lib);
void insert_plugin(dll::shared_library&& lib);
public:
plugins_collector(const boost::dll::fs::path& plugins_directory)
@@ -52,8 +52,7 @@ public:
//[plugcpp_plugins_collector_load_all
void plugins_collector::load_all() {
namespace fs = ::boost::dll::fs;
typedef fs::path::string_type string_type;
const string_type extension = dll::shared_library::suffix().native();
const auto extension = dll::shared_library::suffix().native();
// Searching a folder for files with '.so' or '.dll' extension
fs::recursive_directory_iterator endit;
@@ -67,7 +66,7 @@ void plugins_collector::load_all() {
}
/*->*/
// We found a file. Trying to load it
boost::dll::fs::error_code error;
std::error_code error;
dll::shared_library plugin(it->path(), error);
if (error) {
continue;
@@ -75,17 +74,17 @@ void plugins_collector::load_all() {
std::cout << "Loaded (" << plugin.native() << "):" << it->path() << '\n';
// Gets plugin using "create_plugin" or "plugin" function
insert_plugin(boost::move(plugin));
insert_plugin(std::move(plugin));
}
dll::shared_library plugin(dll::program_location());
std::cout << "Loaded self\n";
insert_plugin(boost::move(plugin));
insert_plugin(std::move(plugin));
}
//]
//[plugcpp_plugins_collector_insert_plugin
void plugins_collector::insert_plugin(BOOST_RV_REF(dll::shared_library) lib) {
void plugins_collector::insert_plugin(dll::shared_library&& lib) {
std::string plugin_name;
if (lib.has("create_plugin")) {
plugin_name = lib.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin")()->name();
@@ -96,7 +95,7 @@ void plugins_collector::insert_plugin(BOOST_RV_REF(dll::shared_library) lib) {
}
if (plugins_.find(plugin_name) == plugins_.cend()) {
plugins_[plugin_name] = boost::move(lib);
plugins_[plugin_name] = std::move(lib);
}
}
//]

View File

@@ -10,14 +10,14 @@
//[plugcpp_on_unload
#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
#include <boost/function.hpp>
#include <functional>
#include <vector>
namespace my_namespace {
struct on_unload {
typedef boost::function<void()> callback_t;
typedef on_unload this_type;
using callback_t = std::function<void()> ;
using this_type = on_unload;
~on_unload() {
for (std::size_t i = 0; i < callbacks_.size(); ++i) {

View File

@@ -9,10 +9,10 @@
//[callplugcpp_tutorial6
#include <boost/dll/import.hpp>
#include <boost/function.hpp>
#include <functional>
#include <iostream>
typedef boost::function<void()> callback_t;
using callback_t = std::function<void()> ;
void print_unloaded() {
std::cout << "unloaded" << std::endl;
@@ -23,16 +23,15 @@ int main(int argc, char* argv[]) {
boost::dll::fs::path shared_library_path = /*<-*/ b2_workarounds::first_lib_from_argv(argc, argv); /*->*/ //=argv[1];
// loading library and getting a function from it
boost::function<void(const callback_t&)> on_unload
= boost::dll::import_alias<void(const callback_t&)>(
shared_library_path, "on_unload"
);
std::function<void(const callback_t&)> on_unload = boost::dll::import_alias<void(const callback_t&)>(
shared_library_path, "on_unload"
);
on_unload(&print_unloaded); // adding a callback
std::cout << "Before library unload." << std::endl;
// Releasing last reference to the library, so that it gets unloaded
on_unload.clear();
on_unload = {};
std::cout << "After library unload." << std::endl;
}
//]

View File

@@ -54,8 +54,8 @@ inline boost::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) {
inline boost::shared_ptr<my_refcounting_api> get_plugin(
boost::dll::fs::path path, const char* func_name)
{
typedef my_refcounting_api*(func_t)();
boost::function<func_t> creator = boost::dll::import_alias<func_t>(
using func_t = my_refcounting_api*();
auto creator = boost::dll::import_alias<func_t>(
path,
func_name,
boost::dll::load_mode::append_decorations // will be ignored for executable

View File

@@ -10,7 +10,7 @@
//[callplugcpp_tutorial9
#include <boost/dll/import.hpp> // for dll::import
#include <boost/dll/shared_library.hpp> // for dll::shared_library
#include <boost/function.hpp>
#include <functional>
#include <iostream>
#include <windows.h>
@@ -29,15 +29,14 @@ int main() {
);
std::cout << "0.0 GetStdHandle() returned " << get_std_handle(STD_OUTPUT_HANDLE) << std::endl;
// You may put the `get_std_handle` into boost::function<>. But boost::function<Signature> can not compile with
// You may put the `get_std_handle` into std::function<>. But std::function<Signature> may not compile with
// Signature template parameter that contains calling conventions, so you'll have to remove the calling convention.
boost::function<HANDLE(DWORD)> get_std_handle2 = get_std_handle;
std::function<HANDLE(DWORD)> get_std_handle2 = get_std_handle;
std::cout << "0.1 GetStdHandle() returned " << get_std_handle2(STD_OUTPUT_HANDLE) << std::endl;
/*<-*/
#endif /*->*/
// OPTION #1, does not require C++11. But without C++11 dll::import<> can not handle calling conventions,
// so you'll need to hand write the import.
// OPTION #1, hand write the import.
dll::shared_library lib("Kernel32.dll", dll::load_mode::search_system_folders);
GetStdHandle_t& func = lib.get<GetStdHandle_t>("GetStdHandle");

View File

@@ -44,7 +44,7 @@ namespace boost { namespace dll {
#define BOOST_DLL_SELECTANY __declspec(selectany)
#define BOOST_DLL_SECTION(SectionName, Permissions) \
static_assert( \
static_assert( \
sizeof(#SectionName) < 10, \
"Some platforms require section names to be at most 8 bytes" \
); \
@@ -83,7 +83,7 @@ namespace boost { namespace dll {
* \param Permissions Can be "read" or "write" (without quotes!).
*/
#define BOOST_DLL_SECTION(SectionName, Permissions) \
static_assert( \
static_assert( \
sizeof(#SectionName) < 10, \
"Some platforms require section names to be at most 8 bytes" \
); \
@@ -92,7 +92,7 @@ namespace boost { namespace dll {
#else // #if !BOOST_OS_MACOS && !BOOST_OS_IOS
#define BOOST_DLL_SECTION(SectionName, Permissions) \
static_assert( \
static_assert( \
sizeof(#SectionName) < 10, \
"Some platforms require section names to be at most 8 bytes" \
); \
@@ -184,7 +184,7 @@ namespace boost { namespace dll {
#else
// Note: we can not use `aggressive_ptr_cast` here, because in that case GCC applies
// different permissions to the section and it causes Segmentation fault.
// Note: we can not use `boost::addressof()` here, because in that case GCC
// Note: we can not use `std::addressof()` here, because in that case GCC
// may optimize away the FunctionOrVar instance and we'll get a pointer to unexisting symbol.
/*!
* \brief Same as \forcedmacrolink{BOOST_DLL_ALIAS} but puts alias name into the user specified section.

View File

@@ -16,7 +16,7 @@
#endif
#ifdef BOOST_DLL_DOXYGEN
/// Define this macro to make Boost.DLL use C++17's std::filesystem::path, std::system_error and std::error_code.
/// 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
/// This namespace contains aliases to the Boost or C++17 classes. Aliases are configured using BOOST_DLL_USE_STD_FS macro.
@@ -38,19 +38,17 @@ using system_error = std::conditional_t<BOOST_DLL_USE_STD_FS, std::system_error,
#endif
#ifdef BOOST_DLL_USE_STD_FS
#include <filesystem>
#include <system_error>
namespace boost { namespace dll { namespace fs {
using namespace std::filesystem;
using std::error_code;
using std::system_error;
using std::make_error_code;
using std::errc;
using std::system_category;
}}}
@@ -58,18 +56,14 @@ using std::system_category;
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/system/error_code.hpp>
namespace boost { namespace dll { namespace fs {
using namespace boost::filesystem;
using boost::system::error_code;
using boost::system::system_error;
using boost::system::errc::make_error_code;
namespace errc = boost::system::errc;
using boost::system::system_category;
}}}

View File

@@ -13,15 +13,9 @@
# pragma once
#endif
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <cstring> // std::memcpy
#include <memory>
#include <type_traits>
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
# pragma GCC system_header
@@ -32,17 +26,17 @@ namespace boost { namespace dll { namespace detail {
// GCC warns when reinterpret_cast between function pointer and object pointer occur.
// This method suppress the warnings and ensures that such casts are safe.
template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && !std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<To>::value && boost::is_pointer<From>::value,
std::is_pointer<To>::value && std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);
static_assert(
boost::is_void< typename boost::remove_pointer<To>::type >::value
|| boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<To>::type >::value
|| std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);
@@ -60,25 +54,25 @@ BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::val
#endif
template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value || boost::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
BOOST_FORCEINLINE typename std::enable_if<std::is_reference<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<From>::value,
std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);
static_assert(
boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);
static_assert(
sizeof(v) == sizeof(typename boost::remove_reference<To>::type*),
sizeof(v) == sizeof(typename std::remove_reference<To>::type*),
"Pointer to function and pointer to object differ in size on your platform."
);
return static_cast<To>(
**reinterpret_cast<typename boost::remove_reference<To>::type**>(
**reinterpret_cast<typename std::remove_reference<To>::type**>(
v
)
);
@@ -89,16 +83,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_reference<To>::value |
#endif
template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::value || boost::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) BOOST_NOEXCEPT
BOOST_FORCEINLINE typename std::enable_if<std::is_member_pointer<To>::value && !std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From v) noexcept
{
static_assert(
boost::is_pointer<From>::value,
std::is_pointer<From>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);
static_assert(
boost::is_void< typename boost::remove_pointer<From>::type >::value,
std::is_void< typename std::remove_pointer<From>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);
@@ -108,16 +102,16 @@ BOOST_FORCEINLINE typename boost::disable_if_c<!boost::is_member_pointer<To>::va
}
template <class To, class From>
BOOST_FORCEINLINE typename boost::disable_if_c<boost::is_member_pointer<To>::value || !boost::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From /* v */) BOOST_NOEXCEPT
BOOST_FORCEINLINE typename std::enable_if<!std::is_member_pointer<To>::value && std::is_member_pointer<From>::value, To>::type
aggressive_ptr_cast(From /* v */) noexcept
{
static_assert(
boost::is_pointer<To>::value,
std::is_pointer<To>::value,
"`agressive_ptr_cast` function must be used only for pointer casting."
);
static_assert(
boost::is_void< typename boost::remove_pointer<To>::type >::value,
std::is_void< typename std::remove_pointer<To>::type >::value,
"`agressive_ptr_cast` function must be used only for casting to or from void pointers."
);

View File

@@ -130,7 +130,7 @@ template<typename Class, typename Lib>
destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt) {
typedef typename destructor<Class>::standard_t standard_t;
//@apolukhin That does NOT work this way with MSVC-14 x32 via memcpy. The x64 is different.
//standard_t dtor = &lib.template get< typename boost::remove_pointer<standard_t>::type >(dt);
//standard_t dtor = &lib.template get< typename std::remove_pointer<standard_t>::type >(dt);
void * buf = &lib.template get<unsigned char>(dt);
standard_t dtor;
std::memcpy(&dtor, &buf, sizeof(dtor));
@@ -175,11 +175,11 @@ destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt
//see here for the abi http://mentorembedded.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor
if (!dt.D1.empty()) {
s = &lib.template get< typename boost::remove_pointer<stand>::type >(dt.D1);
s = &lib.template get< typename std::remove_pointer<stand>::type >(dt.D1);
}
if (!dt.D0.empty()) {
d = &lib.template get< typename boost::remove_pointer<delet>::type >(dt.D0);
d = &lib.template get< typename std::remove_pointer<delet>::type >(dt.D0);
}
return destructor<Class>(s,d);

View File

@@ -8,19 +8,15 @@
#define BOOST_DLL_DETAIL_DEMANGLING_ITANIUM_HPP_
#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
#include <iterator>
#include <algorithm>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <iterator>
#include <type_traits>
namespace boost { namespace dll { namespace detail {
class mangled_storage_impl : public mangled_storage_base
{
template<typename T>
@@ -185,22 +181,22 @@ namespace parser
}
};
inline std::string const_rule_impl(true_type ) {return " const";}
inline std::string const_rule_impl(false_type) {return "";}
inline std::string const_rule_impl(std::true_type ) {return " const";}
inline std::string const_rule_impl(std::false_type) {return "";}
template<typename T>
std::string const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
std::string const_rule() {using t = std::is_const<typename std::remove_reference<T>::type>; return const_rule_impl(t());}
inline std::string volatile_rule_impl(true_type ) {return " volatile";}
inline std::string volatile_rule_impl(false_type) {return "";}
inline std::string volatile_rule_impl(std::true_type ) {return " volatile";}
inline std::string volatile_rule_impl(std::false_type) {return "";}
template<typename T>
std::string volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
std::string volatile_rule() {using t = std::is_volatile<typename std::remove_reference<T>::type>; return volatile_rule_impl(t());}
inline std::string reference_rule_impl(false_type, false_type) {return "";}
inline std::string reference_rule_impl(true_type, false_type) {return "&" ;}
inline std::string reference_rule_impl(false_type, true_type ) {return "&&";}
inline std::string reference_rule_impl(std::false_type, std::false_type) {return "";}
inline std::string reference_rule_impl(std::true_type, std::false_type) {return "&" ;}
inline std::string reference_rule_impl(std::false_type, std::true_type ) {return "&&";}
template<typename T>
std::string reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
std::string reference_rule() {using t_l = std::is_lvalue_reference<T>; using t_r = std::is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
//it takes a string, because it may be overloaded.
template<typename Return, typename Arg>

View File

@@ -10,10 +10,12 @@
#include <vector>
#include <string>
#include <map>
#include <type_traits>
#include <boost/dll/detail/demangling/demangle_symbol.hpp>
#include <boost/dll/library_info.hpp>
#include <boost/type_index/ctti_type_index.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace dll { namespace detail {

View File

@@ -8,16 +8,12 @@
#define BOOST_DLL_DETAIL_DEMANGLING_MSVC_HPP_
#include <boost/dll/detail/demangling/mangled_storage_base.hpp>
#include <boost/core/detail/string_view.hpp>
#include <iterator>
#include <algorithm>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/spirit/home/x3.hpp>
#include <type_traits>
namespace boost { namespace dll { namespace detail {
@@ -26,11 +22,6 @@ class mangled_storage_impl : public mangled_storage_base
template<typename T>
struct dummy {};
template<typename Return, typename ...Args>
std::vector<std::string> get_func_params(dummy<Return(Args...)>) const
{
return {get_name<Args>()...};
}
template<typename Return, typename ...Args>
std::string get_return_type(dummy<Return(Args...)>) const
{
@@ -93,134 +84,247 @@ void mangled_storage_impl::trim_typename(std::string & val)
}
}
namespace parser {
namespace parser
{
namespace x3 = spirit::x3;
inline auto ptr_rule_impl(std::integral_constant<std::size_t, 32>)
{
return -((-x3::space) >> "__ptr32");
}
inline auto ptr_rule_impl(std::integral_constant<std::size_t, 64>)
{
return -((-x3::space) >> "__ptr64");
inline bool try_consume_prefix(boost::core::string_view& s, boost::core::string_view prefix) {
const bool result = s.starts_with(prefix);
if (result) {
s.remove_prefix(prefix.size());
}
return result;
}
inline auto ptr_rule() {
return ptr_rule_impl(std::integral_constant<std::size_t, sizeof(std::size_t)*8>());
inline bool ignore_prefix(boost::core::string_view& s, boost::core::string_view prefix) {
parser::try_consume_prefix(s, prefix);
return true;
}
inline void consume_ptrs(boost::core::string_view& s) {
do {
while (parser::try_consume_prefix(s, " ")) {}
} while (parser::try_consume_prefix(s, "__ptr32") || parser::try_consume_prefix(s, "__ptr64"));
}
auto const visibility = ("public:" | x3::lit("protected:") | "private:");
auto const virtual_ = x3::space >> "virtual";
auto const static_ = x3::space >> x3::lit("static") ;
inline auto const_rule_impl(true_type ) {return x3::space >> "const";};
inline auto const_rule_impl(false_type) {return x3::eps;};
template<typename T>
auto const_rule() {using t = is_const<typename remove_reference<T>::type>; return const_rule_impl(t());}
inline auto volatile_rule_impl(true_type ) {return x3::space >> "volatile";};
inline auto volatile_rule_impl(false_type) {return x3::eps;};
template<typename T>
auto volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return volatile_rule_impl(t());}
inline auto inv_const_rule_impl(true_type ) {return "const" >> x3::space ;};
inline auto inv_const_rule_impl(false_type) {return x3::eps;};
template<typename T>
auto inv_const_rule() {using t = is_const<typename remove_reference<T>::type>; return inv_const_rule_impl(t());}
inline auto inv_volatile_rule_impl(true_type ) {return "volatile" >> x3::space;};
inline auto inv_volatile_rule_impl(false_type) {return x3::eps;};
template<typename T>
auto inv_volatile_rule() {using t = is_volatile<typename remove_reference<T>::type>; return inv_volatile_rule_impl(t());}
inline auto reference_rule_impl(false_type, false_type) {return x3::eps;}
inline auto reference_rule_impl(true_type, false_type) {return x3::space >>"&" ;}
inline auto reference_rule_impl(false_type, true_type ) {return x3::space >>"&&" ;}
template<typename T>
auto reference_rule() {using t_l = is_lvalue_reference<T>; using t_r = is_rvalue_reference<T>; return reference_rule_impl(t_l(), t_r());}
auto const class_ = ("class" | x3::lit("struct"));
//it takes a string, because it may be overloaded.
template<typename T>
auto type_rule(const std::string & type_name)
{
using namespace std;
return -(class_ >> x3::space)>> x3::string(type_name) >>
const_rule<T>() >>
volatile_rule<T>() >>
reference_rule<T>() >>
ptr_rule();
inline bool ignore_ptrs(boost::core::string_view& s) {
parser::consume_ptrs(s);
return true;
}
template<>
inline auto type_rule<void>(const std::string &) { return x3::string("void"); };
auto const cdecl_ = "__cdecl" >> x3::space;
auto const stdcall = "__stdcall" >> x3::space;
#if defined(_WIN64)//seems to be necessary by msvc 14-x64
auto const thiscall = "__cdecl" >> x3::space;
#else
auto const thiscall = "__thiscall" >> x3::space;
#endif
inline bool try_consume_visibility(boost::core::string_view& s) {
return parser::try_consume_prefix(s, "public:")
|| parser::try_consume_prefix(s, "protected:")
|| parser::try_consume_prefix(s, "private:");
}
template<typename T>
bool try_consume_type(boost::core::string_view& s, const mangled_storage_impl& ms) {
if (std::is_void<T>::value) {
return parser::try_consume_prefix(s, "void");
}
parser::ignore_prefix(s, "class ");
parser::ignore_prefix(s, "struct ");
const auto& mangled_name = ms.get_name<T>();
if (!parser::try_consume_prefix(s, mangled_name)) {
return false;
}
if (std::is_const<typename std::remove_reference<T>::type>::value) {
if (!parser::try_consume_prefix(s, " const")) {
return false;
}
}
if (std::is_volatile<typename std::remove_reference<T>::type>::value) {
if (!parser::try_consume_prefix(s, " volatile")) {
return false;
}
}
if (std::is_rvalue_reference<T>::value) {
if (!parser::try_consume_prefix(s, " &&")) {
return false;
}
}
if (std::is_lvalue_reference<T>::value) {
if (!parser::try_consume_prefix(s, " &")) {
return false;
}
}
return parser::ignore_ptrs(s);
}
inline bool try_consume_thiscall(boost::core::string_view& s) {
parser::try_consume_prefix(s, " ");
return parser::try_consume_prefix(s, "__cdecl ") // Win 64bit
|| parser::try_consume_prefix(s, "__thiscall "); // Win 32bit
}
template<typename Return, typename Arg>
auto arg_list(const mangled_storage_impl & ms, Return (*)(Arg))
{
using namespace std;
return type_rule<Arg>(ms.get_name<Arg>());
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)(Arg)) {
return parser::try_consume_type<Arg>(s, ms);
}
template<typename Return, typename First, typename Second, typename ...Args>
auto arg_list(const mangled_storage_impl & ms, Return (*)(First, Second, Args...))
{
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)(First, Second, Args...)) {
using next_type = Return (*)(Second, Args...);
return type_rule<First>(ms.get_name<First>()) >> x3::char_(',') >> arg_list(ms, next_type());
return parser::try_consume_type<First>(s, ms)
&& parser::try_consume_prefix(s, ",")
&& parser::try_consume_arg_list(s, ms, next_type());
}
template<typename Return>
auto arg_list(const mangled_storage_impl& /*ms*/, Return (*)())
{
return x3::string("void");
bool try_consume_arg_list(boost::core::string_view& s, const mangled_storage_impl& ms, Return (*)()) {
return parser::try_consume_type<void>(s, ms);
}
}
class is_destructor_with_name {
const std::string& dtor_name_;
template<typename T> std::string mangled_storage_impl::get_variable(const std::string &name) const
{
using namespace std;
using namespace boost;
public:
explicit is_destructor_with_name(const std::string& dtor_name)
: dtor_name_(dtor_name) {}
namespace x3 = spirit::x3;
using namespace parser;
inline bool operator()(boost::core::string_view s) const {
return parser::try_consume_visibility(s)
&& parser::ignore_prefix(s, " virtual")
&& parser::try_consume_thiscall(s)
&& parser::try_consume_prefix(s, dtor_name_)
&& parser::ignore_ptrs(s)
&& s.empty();
}
auto type_name = get_name<T>();
inline bool operator()(const mangled_storage_base::entry& e) const {
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
}
};
auto matcher =
-(visibility >> static_ >> x3::space) >> //it may be a static class-member
parser::type_rule<T>(type_name) >> x3::space >>
name;
template<typename T>
class is_variable_with_name {
const std::string& variable_name_;
const mangled_storage_impl& ms_;
auto predicate = [&](const mangled_storage_base::entry & e)
{
if (e.demangled == name)//maybe not mangled,
return true;
public:
is_variable_with_name(const std::string& variable_name, const mangled_storage_impl& ms)
: variable_name_(variable_name), ms_(ms) {}
auto itr = e.demangled.begin();
auto end = e.demangled.end();
auto res = x3::parse(itr, end, matcher);
return res && (itr == end);
};
inline bool operator()(boost::core::string_view s) const {
if (parser::try_consume_visibility(s) && !parser::try_consume_prefix(s, " static ")) {
return false;
}
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
return parser::try_consume_type<T>(s, ms_)
&& parser::try_consume_prefix(s, variable_name_)
&& s.empty();
}
inline bool operator()(const mangled_storage_base::entry& e) const {
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
}
};
template <class Signature>
class is_constructor_with_name {
const std::string& ctor_name_;
const mangled_storage_impl& ms_;
public:
is_constructor_with_name(const std::string& ctor_name, const mangled_storage_impl& ms)
: ctor_name_(ctor_name), ms_(ms) {}
inline bool operator()(boost::core::string_view s) const {
return parser::try_consume_visibility(s)
&& parser::try_consume_thiscall(s)
&& parser::try_consume_prefix(s, ctor_name_)
&& parser::try_consume_prefix(s, "(")
&& parser::try_consume_arg_list(s, ms_, Signature())
&& parser::try_consume_prefix(s, ")")
&& parser::ignore_ptrs(s)
&& s.empty();
}
inline bool operator()(const mangled_storage_base::entry& e) const {
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
}
};
template <class Signature>
class is_function_with_name;
template <class Result, class... Args>
class is_function_with_name<Result(*)(Args...)> {
const std::string& function_name_;
const mangled_storage_impl& ms_;
public:
is_function_with_name(const std::string& function_name, const mangled_storage_impl& ms)
: function_name_(function_name), ms_(ms) {}
inline bool operator()(boost::core::string_view s) const {
if (parser::try_consume_visibility(s) && !parser::try_consume_prefix(s, " static ")) {
return false;
}
using Signature = Result(*)(Args...);
return parser::try_consume_type<Result>(s, ms_)
&& parser::ignore_prefix(s, " ")
&& parser::try_consume_prefix(s, "__cdecl ")
&& parser::try_consume_prefix(s, function_name_)
&& parser::try_consume_prefix(s, "(")
&& parser::try_consume_arg_list(s, ms_, Signature())
&& parser::try_consume_prefix(s, ")")
&& parser::ignore_ptrs(s)
&& s.empty();
}
inline bool operator()(const mangled_storage_base::entry& e) const {
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
}
};
template <typename Class, typename Func>
class is_mem_fn_with_name;
template <typename Class, class Result, class... Args>
class is_mem_fn_with_name<Class, Result(*)(Args...)> {
const std::string& function_name_;
const mangled_storage_impl& ms_;
public:
is_mem_fn_with_name(const std::string& function_name, const mangled_storage_impl& ms)
: function_name_(function_name), ms_(ms) {}
inline bool operator()(boost::core::string_view s) const {
using Signature = Result(*)(Args...);
return parser::try_consume_visibility(s)
&& parser::ignore_prefix(s, " virtual")
&& parser::try_consume_prefix(s, " ")
&& parser::try_consume_type<Result>(s, ms_)
&& parser::try_consume_thiscall(s)
&& parser::try_consume_type<typename std::remove_cv<Class>::type>(s, ms_)
&& parser::try_consume_prefix(s, "::")
&& parser::try_consume_prefix(s, function_name_)
&& parser::try_consume_prefix(s, "(")
&& parser::try_consume_arg_list(s, ms_, Signature())
&& parser::try_consume_prefix(s, ")")
&& (!std::is_const<Class>::value || parser::try_consume_prefix(s, "const "))
&& (!std::is_volatile<Class>::value || parser::try_consume_prefix(s, "volatile "))
&& parser::ignore_ptrs(s)
&& s.empty();
}
inline bool operator()(const mangled_storage_base::entry& e) const {
return (*this)(boost::core::string_view(e.demangled.data(), e.demangled.size()));
}
};
} // namespace parser
template<typename T>
std::string mangled_storage_impl::get_variable(const std::string &name) const {
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_variable_with_name<T>(name, *this));
if (found != storage_.end())
return found->mangled;
@@ -228,73 +332,19 @@ template<typename T> std::string mangled_storage_impl::get_variable(const std::s
return "";
}
template<typename Func> std::string mangled_storage_impl::get_function(const std::string &name) const
{
namespace x3 = spirit::x3;
using namespace parser;
using func_type = Func*;
using return_type = typename function_traits<Func>::result_type;
std::string return_type_name = get_name<return_type>();
auto matcher =
-(visibility >> static_ >> x3::space) >> //it may be a static class-member, which does however not have the static attribute.
parser::type_rule<return_type>(return_type_name) >> x3::space >>
cdecl_ >> //cdecl declaration for methods. stdcall cannot be
name >> x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
auto predicate = [&](const mangled_storage_base::entry & e)
{
if (e.demangled == name)//maybe not mangled,
return true;
auto itr = e.demangled.begin();
auto end = e.demangled.end();
auto res = x3::parse(itr, end, matcher);
return res && (itr == end);
};
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
template<typename Func>
std::string mangled_storage_impl::get_function(const std::string &name) const {
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_function_with_name<Func*>(name, *this));
if (found != storage_.end())
return found->mangled;
else
return "";
}
template<typename Class, typename Func>
std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
{
namespace x3 = spirit::x3;
using namespace parser;
using func_type = Func*;
using return_type = typename function_traits<Func>::result_type;
auto return_type_name = get_name<return_type>();
auto cname = get_name<Class>();
auto matcher =
visibility >> -virtual_ >> x3::space >>
parser::type_rule<return_type>(return_type_name) >> x3::space >>
thiscall >> //cdecl declaration for methods. stdcall cannot be
cname >> "::" >> name >>
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >>
inv_const_rule<Class>() >> inv_volatile_rule<Class>() >> parser::ptr_rule();
auto predicate = [&](const mangled_storage_base::entry & e)
{
auto itr = e.demangled.begin();
auto end = e.demangled.end();
auto res = x3::parse(itr, end, matcher);
return res && (itr == end);
};
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
std::string mangled_storage_impl::get_mem_fn(const std::string &name) const {
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_mem_fn_with_name<Class, Func*>(name, *this));
if (found != storage_.end())
return found->mangled;
@@ -304,14 +354,7 @@ std::string mangled_storage_impl::get_mem_fn(const std::string &name) const
template<typename Signature>
auto mangled_storage_impl::get_constructor() const -> ctor_sym
{
namespace x3 = spirit::x3;
using namespace parser;
using func_type = Signature*;
auto mangled_storage_impl::get_constructor() const -> ctor_sym {
std::string ctor_name; // = class_name + "::" + name;
std::string unscoped_cname; //the unscoped class-name
{
@@ -329,23 +372,7 @@ auto mangled_storage_impl::get_constructor() const -> ctor_sym
}
}
auto matcher =
visibility >> x3::space >>
thiscall >> //cdecl declaration for methods. stdcall cannot be
ctor_name >>
x3::lit('(') >> parser::arg_list(*this, func_type()) >> x3::lit(')') >> parser::ptr_rule();
auto predicate = [&](const mangled_storage_base::entry & e)
{
auto itr = e.demangled.begin();
auto end = e.demangled.end();
auto res = x3::parse(itr, end, matcher);
return res && (itr == end);
};
auto f = std::find_if(storage_.begin(), storage_.end(), predicate);
const auto f = std::find_if(storage_.begin(), storage_.end(), parser::is_constructor_with_name<Signature*>(ctor_name, *this));
if (f != storage_.end())
return f->mangled;
@@ -354,10 +381,7 @@ auto mangled_storage_impl::get_constructor() const -> ctor_sym
}
template<typename Class>
auto mangled_storage_impl::get_destructor() const -> dtor_sym
{
namespace x3 = spirit::x3;
using namespace parser;
auto mangled_storage_impl::get_destructor() const -> dtor_sym {
std::string dtor_name; // = class_name + "::" + name;
std::string unscoped_cname; //the unscoped class-name
{
@@ -375,23 +399,7 @@ auto mangled_storage_impl::get_destructor() const -> dtor_sym
}
}
auto matcher =
visibility >> -virtual_ >> x3::space >>
thiscall >> //cdecl declaration for methods. stdcall cannot be
dtor_name >> parser::ptr_rule();
auto predicate = [&](const mangled_storage_base::entry & e)
{
auto itr = e.demangled.begin();
auto end = e.demangled.end();
auto res = x3::parse(itr, end, matcher);
return res && (itr == end);
};
auto found = std::find_if(storage_.begin(), storage_.end(), predicate);
const auto found = std::find_if(storage_.begin(), storage_.end(), parser::is_destructor_with_name(dtor_name));
if (found != storage_.end())
return found->mangled;
@@ -400,8 +408,7 @@ auto mangled_storage_impl::get_destructor() const -> dtor_sym
}
template<typename T>
std::string mangled_storage_impl::get_vtable() const
{
std::string mangled_storage_impl::get_vtable() const {
std::string id = "const " + get_name<T>() + "::`vftable'";
auto predicate = [&](const mangled_storage_base::entry & e)
@@ -419,8 +426,7 @@ std::string mangled_storage_impl::get_vtable() const
}
template<typename T>
std::vector<std::string> mangled_storage_impl::get_related() const
{
std::vector<std::string> mangled_storage_impl::get_related() const {
std::vector<std::string> ret;
auto name = get_name<T>();
@@ -433,9 +439,6 @@ std::vector<std::string> mangled_storage_impl::get_related() const
return ret;
}
}}}
#endif /* BOOST_DLL_DETAIL_DEMANGLING_MSVC_HPP_ */

View File

@@ -259,7 +259,7 @@ private:
read_raw(fs, symbols[0], static_cast<std::size_t>(symtab_size - (symtab_size % sizeof(symbol_t))) );
}
static bool is_visible(const symbol_t& sym) BOOST_NOEXCEPT {
static bool is_visible(const symbol_t& sym) noexcept {
const unsigned char visibility = (sym.st_other & 0x03);
// `(sym.st_info >> 4) != STB_LOCAL_ && !!sym.st_size` check also workarounds the
// GCC's issue https://sourceware.org/bugzilla/show_bug.cgi?id=13621

View File

@@ -8,11 +8,7 @@
#define BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <type_traits>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -34,9 +30,9 @@ struct push_front<Value, sequence<Args...>>
template<class Lhs, class Rhs>
struct unqalified_is_same :
boost::is_same<
typename boost::remove_cv<Lhs>::type,
typename boost::remove_cv<Rhs>::type
std::is_same<
typename std::remove_cv<Lhs>::type,
typename std::remove_cv<Rhs>::type
>
{
};
@@ -48,19 +44,19 @@ template<class T> struct is_function_seq;
//type-trait for function overloads
template<class Class, class...Args> struct is_function_seq<sequence<Class, Args...>>
: boost::conditional<
boost::is_function<Class>::value,
: std::conditional<
std::is_function<Class>::value,
is_function_seq<sequence<Args...>>,
boost::false_type>::type
std::false_type>::type
{};
template<class Class>
struct is_function_seq<sequence<Class>> : boost::is_function<Class>
struct is_function_seq<sequence<Class>> : std::is_function<Class>
{
};
template<>
struct is_function_seq<sequence<>> : boost::false_type
struct is_function_seq<sequence<>> : std::false_type
{
};
@@ -151,11 +147,11 @@ struct make_mem_fn_seq<T0, T1, T2, Args...>
* Class, const Class, void(int)//--> ovl class.
*
*/
static_assert(boost::is_object<T0>::value, "");
static_assert(std::is_object<T0>::value, "");
typedef typename make_mem_fn_seq_getter<
unqalified_is_same<T0, T1>::value, T0, T1, T2>::type mem_fn_type;
typedef typename boost::conditional<
typedef typename std::conditional<
unqalified_is_same<T0, T1>::value,
make_mem_fn_seq<T1, Args...>,
make_mem_fn_seq<T0, T2, Args...>> ::type next;
@@ -203,46 +199,46 @@ struct make_mem_fn_seq<T0, T1, T2, Args...>
template<class T, class U, class ...Args>
struct is_mem_fn_seq_impl
{
typedef typename boost::conditional<
boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
typedef typename std::conditional<
std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
typename is_mem_fn_seq_impl<T, Args...>::type,
boost::false_type>::type type;
std::false_type>::type type;
};
template<class T, class U>
struct is_mem_fn_seq_impl<T, U>
{
typedef typename boost::conditional<
boost::is_function<U>::value && boost::is_object<T>::value,
boost::true_type, boost::false_type>::type type;
typedef typename std::conditional<
std::is_function<U>::value && std::is_object<T>::value,
std::true_type, std::false_type>::type type;
};
template<class T, class U, class Last>
struct is_mem_fn_seq_impl<T, U, Last>
{
typedef typename boost::conditional<
(boost::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
&& boost::is_function<Last>::value,
boost::true_type, boost::false_type>::type type;
typedef typename std::conditional<
(std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
&& std::is_function<Last>::value,
std::true_type, std::false_type>::type type;
};
template<class T> struct is_mem_fn_seq : boost::false_type {};
template<class T> struct is_mem_fn_seq : std::false_type {};
//If only two arguments are provided at all.
template<class T, class U>
struct is_mem_fn_seq<sequence<T, U>> : boost::conditional<
boost::is_object<T>::value && boost::is_function<U>::value,
boost::true_type, boost::false_type>::type
struct is_mem_fn_seq<sequence<T, U>> : std::conditional<
std::is_object<T>::value && std::is_function<U>::value,
std::true_type, std::false_type>::type
{
};
template<class T, class Func, class ...Args>
struct is_mem_fn_seq<sequence<T, Func, Args...>> :
boost::conditional<
boost::is_class<T>::value && boost::is_function<Func>::value,
std::conditional<
std::is_class<T>::value && std::is_function<Func>::value,
typename is_mem_fn_seq_impl<T, Args...>::type,
boost::false_type>::type {};
std::false_type>::type {};
/* ********************************** mem fn sequence tuple ******************************/

View File

@@ -350,6 +350,9 @@ public:
// getting ordinal
fs.seekg(fixed_ordinals_addr + i * sizeof(ordinal));
read_raw(fs, ordinal);
if (ordinal >= exported_symbols) { // required for clang-win created PE
continue;
}
// getting function addr
fs.seekg(fixed_functions_addr + ordinal * sizeof(ptr));
@@ -380,7 +383,7 @@ public:
MSVCR110D.dll
*/
/*
static std::vector<std::string> depend_of(boost::dll::fs::error_code &ec) BOOST_NOEXCEPT {
static std::vector<std::string> depend_of(boost::dll::fs::error_code &ec) noexcept {
std::vector<std::string> ret;
IMAGE_DOS_HEADER* image_dos_header = (IMAGE_DOS_HEADER*)native();

View File

@@ -24,13 +24,13 @@
# include <cstddef> // for std::ptrdiff_t
namespace boost { namespace dll { namespace detail {
inline void* strip_handle(void* handle) BOOST_NOEXCEPT {
inline void* strip_handle(void* handle) noexcept {
return reinterpret_cast<void*>(
(reinterpret_cast<std::ptrdiff_t>(handle) >> 2) << 2
);
}
inline boost::dll::fs::path path_from_handle(void* handle, boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path path_from_handle(void* handle, std::error_code &ec) {
handle = strip_handle(handle);
// Iterate through all images currently in memory
@@ -53,8 +53,8 @@ namespace boost { namespace dll { namespace detail {
}
boost::dll::detail::reset_dlerror();
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
return boost::dll::fs::path();
@@ -78,7 +78,7 @@ namespace boost { namespace dll { namespace detail {
// ... // Ignoring remaning parts of the structure
};
inline boost::dll::fs::path path_from_handle(const void* handle, boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path path_from_handle(const void* handle, std::error_code &ec) {
static const std::size_t work_around_b_24465209__offset = 128;
const struct soinfo* si = reinterpret_cast<const struct soinfo*>(
static_cast<const char*>(handle) + work_around_b_24465209__offset
@@ -119,7 +119,7 @@ namespace boost { namespace dll { namespace detail {
};
#endif // #if BOOST_OS_QNX
inline boost::dll::fs::path path_from_handle(void* handle, boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path path_from_handle(void* handle, std::error_code &ec) {
// RTLD_DI_LINKMAP (RTLD_DI_ORIGIN returns only folder and is not suitable for this case)
// Obtain the Link_map for the handle that is specified.
// The p argument points to a Link_map pointer (Link_map
@@ -144,8 +144,8 @@ namespace boost { namespace dll { namespace detail {
#endif
if (!link_map) {
boost::dll::detail::reset_dlerror();
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
return boost::dll::fs::path();

View File

@@ -21,7 +21,7 @@
#include <mach-o/dyld.h>
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
ec.clear();
char path[1024];
@@ -31,8 +31,8 @@ namespace boost { namespace dll { namespace detail {
char *p = new char[size];
if (_NSGetExecutablePath(p, &size) != 0) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
}
@@ -46,7 +46,7 @@ namespace boost { namespace dll { namespace detail {
#include <stdlib.h>
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
ec.clear();
return boost::dll::fs::path(getexecname());
@@ -60,7 +60,7 @@ namespace boost { namespace dll { namespace detail {
#include <stdlib.h>
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
ec.clear();
int mib[4];
@@ -81,7 +81,7 @@ namespace boost { namespace dll { namespace detail {
#elif BOOST_OS_BSD_NET
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
return boost::dll::fs::read_symlink("/proc/curproc/exe", ec);
}
}}} // namespace boost::dll::detail
@@ -90,7 +90,7 @@ namespace boost { namespace dll { namespace detail {
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
return boost::dll::fs::read_symlink("/proc/curproc/file", ec);
}
}}} // namespace boost::dll::detail
@@ -100,7 +100,7 @@ namespace boost { namespace dll { namespace detail {
#include <fstream>
#include <string> // for std::getline
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
ec.clear();
std::string s;
@@ -108,8 +108,8 @@ namespace boost { namespace dll { namespace detail {
std::getline(ifs, s);
if (ifs.fail() || s.empty()) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
}
@@ -120,12 +120,15 @@ namespace boost { namespace dll { namespace detail {
#else // BOOST_OS_LINUX || BOOST_OS_UNIX || BOOST_OS_HPUX || BOOST_OS_ANDROID
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path program_location_impl(std::error_code &ec) {
// We can not use
// boost::dll::detail::path_from_handle(dlopen(NULL, RTLD_LAZY | RTLD_LOCAL), ignore);
// because such code returns empty path.
return boost::dll::fs::read_symlink("/proc/self/exe", ec); // Linux specific
boost::dll::fs::error_code fs_errc;
auto result = boost::dll::fs::read_symlink("/proc/self/exe", fs_errc); // Linux specific
ec = fs_errc;
return result;
}
}}} // namespace boost::dll::detail

View File

@@ -13,10 +13,11 @@
#include <boost/dll/detail/posix/path_from_handle.hpp>
#include <boost/dll/detail/posix/program_location_impl.hpp>
#include <boost/move/utility.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/predef/os.h>
#include <utility> // std::move
#include <dlfcn.h>
#include <cstring> // strncmp
#if !BOOST_OS_MACOS && !BOOST_OS_IOS && !BOOST_OS_QNX
@@ -33,31 +34,28 @@
namespace boost { namespace dll { namespace detail {
class shared_library_impl {
BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl)
public:
typedef void* native_handle_t;
shared_library_impl() BOOST_NOEXCEPT
: handle_(NULL)
shared_library_impl() noexcept
: handle_(nullptr)
{}
~shared_library_impl() BOOST_NOEXCEPT {
~shared_library_impl() noexcept {
unload();
}
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
shared_library_impl(shared_library_impl&& sl) noexcept
: handle_(sl.handle_)
{
sl.handle_ = NULL;
sl.handle_ = nullptr;
}
shared_library_impl(native_handle_t handle)
explicit shared_library_impl(native_handle_t handle) noexcept
: handle_(handle)
{}
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
shared_library_impl & operator=(shared_library_impl&& sl) noexcept {
swap(sl);
return *this;
}
@@ -73,7 +71,7 @@ public:
return actual_path;
}
void load(boost::dll::fs::path sl, load_mode::type portable_mode, boost::dll::fs::error_code &ec) {
void load(boost::dll::fs::path sl, load_mode::type portable_mode, std::error_code &ec) {
typedef int native_mode_t;
native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
unload();
@@ -81,8 +79,8 @@ public:
// Do not allow opening NULL paths. User must use program_location() instead
if (sl.empty()) {
boost::dll::detail::reset_dlerror();
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
return;
@@ -128,8 +126,8 @@ public:
boost::dll::fs::path loc = boost::dll::detail::program_location_impl(prog_loc_err);
if (boost::dll::fs::exists(actual_path) && !boost::dll::fs::equivalent(sl, loc, prog_loc_err)) {
// decorated path exists : current error is not a bad file descriptor and we are not trying to load the executable itself
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::executable_format_error
ec = std::make_error_code(
std::errc::executable_format_error
);
return;
}
@@ -142,8 +140,8 @@ public:
return;
}
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
// Maybe user wanted to load the executable itself? Checking...
@@ -158,20 +156,20 @@ public:
// returned handle is for the main program.
ec.clear();
boost::dll::detail::reset_dlerror();
handle_ = dlopen(NULL, native_mode);
handle_ = dlopen(nullptr, native_mode);
if (!handle_) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
}
}
}
bool is_loaded() const BOOST_NOEXCEPT {
bool is_loaded() const noexcept {
return (handle_ != 0);
}
void unload() BOOST_NOEXCEPT {
void unload() noexcept {
if (!is_loaded()) {
return;
}
@@ -180,11 +178,11 @@ public:
handle_ = 0;
}
void swap(shared_library_impl& rhs) BOOST_NOEXCEPT {
void swap(shared_library_impl& rhs) noexcept {
boost::core::invoke_swap(handle_, rhs.handle_);
}
boost::dll::fs::path full_module_path(boost::dll::fs::error_code &ec) const {
boost::dll::fs::path full_module_path(std::error_code &ec) const {
return boost::dll::detail::path_from_handle(handle_, ec);
}
@@ -197,12 +195,12 @@ public:
#endif
}
void* symbol_addr(const char* sb, boost::dll::fs::error_code &ec) const BOOST_NOEXCEPT {
void* symbol_addr(const char* sb, std::error_code &ec) const noexcept {
// dlsym - obtain the address of a symbol from a dlopen object
void* const symbol = dlsym(handle_, sb);
if (symbol == NULL) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::invalid_seek
if (symbol == nullptr) {
ec = std::make_error_code(
std::errc::invalid_seek
);
}
@@ -214,7 +212,7 @@ public:
return symbol;
}
native_handle_t native() const BOOST_NOEXCEPT {
native_handle_t native() const noexcept {
return handle_;
}

View File

@@ -22,14 +22,14 @@
namespace boost { namespace dll { namespace detail {
inline void reset_dlerror() BOOST_NOEXCEPT {
inline void reset_dlerror() noexcept {
#if !BOOST_OS_WINDOWS
const char* const error_txt = dlerror();
(void)error_txt;
#endif
}
inline void report_error(const boost::dll::fs::error_code& ec, const char* message) {
inline void report_error(const std::error_code& ec, const char* message) {
#if !BOOST_OS_WINDOWS
const char* const error_txt = dlerror();
if (error_txt) {

View File

@@ -19,15 +19,15 @@
namespace boost { namespace dll { namespace detail {
inline boost::dll::fs::error_code last_error_code() BOOST_NOEXCEPT {
inline std::error_code last_error_code() noexcept {
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
return boost::dll::fs::error_code(
return std::error_code(
static_cast<int>(err),
boost::dll::fs::system_category()
std::system_category()
);
}
inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, boost::dll::fs::error_code &ec) {
inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, std::error_code &ec) {
BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A);
BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260);

View File

@@ -14,11 +14,12 @@
#include <boost/dll/detail/system_error.hpp>
#include <boost/dll/detail/windows/path_from_handle.hpp>
#include <boost/move/utility.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/winapi/dll.hpp>
#include <utility> // std::move
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
@@ -26,30 +27,28 @@
namespace boost { namespace dll { namespace detail {
class shared_library_impl {
BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl)
public:
typedef boost::winapi::HMODULE_ native_handle_t;
shared_library_impl() BOOST_NOEXCEPT
: handle_(NULL)
shared_library_impl() noexcept
: shared_library_impl(nullptr)
{}
~shared_library_impl() BOOST_NOEXCEPT {
~shared_library_impl() noexcept {
unload();
}
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
shared_library_impl(shared_library_impl&& sl) noexcept
: handle_(sl.handle_)
{
sl.handle_ = NULL;
sl.handle_ = nullptr;
}
shared_library_impl(native_handle_t handle)
explicit shared_library_impl(native_handle_t handle) noexcept
: handle_(handle)
{}
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
shared_library_impl & operator=(shared_library_impl&& sl) noexcept {
swap(sl);
return *this;
}
@@ -60,7 +59,7 @@ public:
return actual_path;
}
void load(boost::dll::fs::path sl, load_mode::type portable_mode, boost::dll::fs::error_code &ec) {
void load(boost::dll::fs::path sl, load_mode::type portable_mode, std::error_code &ec) {
typedef boost::winapi::DWORD_ native_mode_t;
native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
unload();
@@ -115,22 +114,22 @@ public:
}
}
bool is_loaded() const BOOST_NOEXCEPT {
bool is_loaded() const noexcept {
return (handle_ != 0);
}
void unload() BOOST_NOEXCEPT {
void unload() noexcept {
if (handle_) {
boost::winapi::FreeLibrary(handle_);
handle_ = 0;
}
}
void swap(shared_library_impl& rhs) BOOST_NOEXCEPT {
void swap(shared_library_impl& rhs) noexcept {
boost::core::invoke_swap(handle_, rhs.handle_);
}
boost::dll::fs::path full_module_path(boost::dll::fs::error_code &ec) const {
boost::dll::fs::path full_module_path(std::error_code &ec) const {
return boost::dll::detail::path_from_handle(handle_, ec);
}
@@ -138,16 +137,16 @@ public:
return L".dll";
}
void* symbol_addr(const char* sb, boost::dll::fs::error_code &ec) const BOOST_NOEXCEPT {
void* symbol_addr(const char* sb, std::error_code &ec) const noexcept {
if (is_resource()) {
// `GetProcAddress` could not be called for libraries loaded with
// `LOAD_LIBRARY_AS_DATAFILE`, `LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE`
// or `LOAD_LIBRARY_AS_IMAGE_RESOURCE`.
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::operation_not_supported
ec = std::make_error_code(
std::errc::operation_not_supported
);
return NULL;
return nullptr;
}
// Judging by the documentation of GetProcAddress
@@ -156,20 +155,20 @@ public:
void* const symbol = boost::dll::detail::aggressive_ptr_cast<void*>(
boost::winapi::get_proc_address(handle_, sb)
);
if (symbol == NULL) {
if (symbol == nullptr) {
ec = boost::dll::detail::last_error_code();
}
return symbol;
}
native_handle_t native() const BOOST_NOEXCEPT {
native_handle_t native() const noexcept {
return handle_;
}
private:
// Returns true if this load attempt should be the last one.
bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, boost::dll::fs::error_code &ec) {
bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, std::error_code &ec) {
handle_ = boost::winapi::LoadLibraryExW(load_path.c_str(), 0, mode);
if (handle_) {
return true;
@@ -185,7 +184,7 @@ private:
return false;
}
bool is_resource() const BOOST_NOEXCEPT {
bool is_resource() const noexcept {
return false; /*!!(
reinterpret_cast<boost::winapi::ULONG_PTR_>(handle_) & static_cast<boost::winapi::ULONG_PTR_>(3)
);*/

View File

@@ -9,16 +9,11 @@
#define BOOST_DLL_IMPORT_HPP
#include <boost/dll/config.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_object.hpp>
#include <boost/make_shared.hpp>
#include <boost/dll/shared_library.hpp>
#include <boost/move/move.hpp>
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
# include <boost/function.hpp>
#endif
#include <memory> // std::addressof
#include <type_traits>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
@@ -40,16 +35,10 @@ namespace detail {
boost::shared_ptr<T> f_;
public:
inline library_function(const boost::shared_ptr<shared_library>& lib, T* func_ptr) BOOST_NOEXCEPT
inline library_function(const boost::shared_ptr<shared_library>& lib, T* func_ptr) noexcept
: f_(lib, func_ptr)
{}
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
operator T*() const BOOST_NOEXCEPT {
return f_.get();
}
#else
// Compilation error at this point means that imported function
// was called with unmatching parameters.
//
@@ -64,33 +53,20 @@ namespace detail {
{
return (*f_)(static_cast<Args&&>(args)...);
}
#endif
};
template <class T, class = void>
struct import_type;
template <class T>
struct import_type<T, typename boost::disable_if<boost::is_object<T> >::type> {
typedef boost::dll::detail::library_function<T> base_type;
#if defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) || defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
typedef boost::function<T> type;
#else
typedef boost::dll::detail::library_function<T> type;
#endif
};
template <class T>
struct import_type<T, typename boost::enable_if<boost::is_object<T> >::type> {
typedef boost::shared_ptr<T> base_type;
typedef boost::shared_ptr<T> type;
};
using import_type = typename std::conditional<
std::is_object<T>::value,
boost::shared_ptr<T>,
boost::dll::detail::library_function<T>
>::type;
} // namespace detail
#ifndef BOOST_DLL_DOXYGEN
# define BOOST_DLL_IMPORT_RESULT_TYPE inline typename boost::dll::detail::import_type<T>::type
# define BOOST_DLL_IMPORT_RESULT_TYPE inline boost::dll::detail::import_type<T>
#endif
@@ -108,7 +84,7 @@ namespace detail {
* \b Examples:
*
* \code
* boost::function<int(int)> f = import_symbol<int(int)>("test_lib.so", "integer_func_name");
* std::function<int(int)> f = import_symbol<int(int)>("test_lib.so", "integer_func_name");
*
* auto f_cpp11 = import_symbol<int(int)>("test_lib.so", "integer_func_name");
* \endcode
@@ -132,10 +108,10 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, const char* name,
load_mode::type mode = load_mode::default_mode)
{
typedef typename boost::dll::detail::import_type<T>::base_type type;
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib, mode);
return type(p, boost::addressof(p->get<T>(name)));
auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
return type(p, std::addressof(p->get<T>(name)));
}
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
@@ -149,10 +125,10 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, cons
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const char* name) {
typedef typename boost::dll::detail::import_type<T>::base_type type;
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib);
return type(p, boost::addressof(p->get<T>(name)));
auto p = boost::make_shared<boost::dll::shared_library>(lib);
return type(p, std::addressof(p->get<T>(name)));
}
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
@@ -163,19 +139,19 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const std:
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, const char* name) {
typedef typename boost::dll::detail::import_type<T>::base_type type;
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(
boost::move(lib)
auto p = boost::make_shared<boost::dll::shared_library>(
std::move(lib)
);
return type(p, boost::addressof(p->get<T>(name)));
return type(p, std::addressof(p->get<T>(name)));
}
//! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, const std::string& name) {
return dll::import_symbol<T>(boost::move(lib), name.c_str());
BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::string& name) {
return dll::import_symbol<T>(std::move(lib), name.c_str());
}
@@ -195,7 +171,7 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(BOOST_RV_REF(shared_library) lib, con
* \b Examples:
*
* \code
* boost::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
* std::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
*
* auto f_cpp11 = import_alias<int(int)>("test_lib.so", "integer_func_alias_name");
* \endcode
@@ -222,9 +198,9 @@ template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const char* name,
load_mode::type mode = load_mode::default_mode)
{
typedef typename boost::dll::detail::import_type<T>::base_type type;
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib, mode);
auto p = boost::make_shared<boost::dll::shared_library>(lib, mode);
return type(p, p->get<T*>(name));
}
@@ -239,9 +215,9 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const char* name) {
typedef typename boost::dll::detail::import_type<T>::base_type type;
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(lib);
auto p = boost::make_shared<boost::dll::shared_library>(lib);
return type(p, p->get<T*>(name));
}
@@ -253,19 +229,19 @@ BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const std::
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(BOOST_RV_REF(shared_library) lib, const char* name) {
typedef typename boost::dll::detail::import_type<T>::base_type type;
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const char* name) {
using type = boost::dll::detail::import_type<T>;
boost::shared_ptr<boost::dll::shared_library> p = boost::make_shared<boost::dll::shared_library>(
boost::move(lib)
auto p = boost::make_shared<boost::dll::shared_library>(
std::move(lib)
);
return type(p, p->get<T*>(name));
}
//! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class T>
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(BOOST_RV_REF(shared_library) lib, const std::string& name) {
return dll::import_alias<T>(boost::move(lib), name.c_str());
BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const std::string& name) {
return dll::import_alias<T>(std::move(lib), name.c_str());
}
#undef BOOST_DLL_IMPORT_RESULT_TYPE

View File

@@ -15,6 +15,7 @@
#include <boost/dll/smart_library.hpp>
#include <boost/dll/import_mangled.hpp>
#include <memory>
#include <utility> // std::move
#if (__cplusplus < 201103L) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L)
# error This file requires C++11 at least!
@@ -68,7 +69,7 @@ struct mem_fn_call_proxy<Class, boost::dll::experimental::detail::mangled_librar
: t(t), mem_fn(mem_fn) {}
template<typename ...Args>
auto operator()(Args&&...args) const
auto operator()(Args&&...args) const -> decltype(mem_fn(t, std::forward<Args>(args)...))
{
return mem_fn(t, std::forward<Args>(args)...);
}
@@ -119,11 +120,11 @@ import_class(const smart_library& lib, std::size_t size,
template<typename T>
class imported_class
{
smart_library _lib;
std::unique_ptr<T, detail::deleter<T>> _data;
bool _is_allocating;
std::size_t _size;
const std::type_info& _ti;
smart_library lib_;
std::unique_ptr<T, detail::deleter<T>> data_;
bool is_allocating_;
std::size_t size_;
const std::type_info& ti_;
template<typename ... Args>
inline std::unique_ptr<T, detail::deleter<T>> make_data(const smart_library& lib, Args ... args);
@@ -147,14 +148,14 @@ public:
static imported_class<T> make(smart_library&& lib, Args...args)
{
typedef detail::sequence<Args...> *seq;
return imported_class(seq(), boost::move(lib), static_cast<Args>(args)...);
return imported_class(seq(), std::move(lib), static_cast<Args>(args)...);
}
template<typename ...Args>
static imported_class<T> make(smart_library&& lib, std::size_t size, Args...args)
{
typedef detail::sequence<Args...> *seq;
return imported_class(seq(), boost::move(lib), size, static_cast<Args>(args)...);
return imported_class(seq(), std::move(lib), size, static_cast<Args>(args)...);
}
template<typename ...Args>
static imported_class<T> make(const smart_library& lib, Args...args)
@@ -172,7 +173,7 @@ public:
typedef imported_class<T> base_t;
///Returns a pointer to the underlying class
T* get() {return _data.get();}
T* get() {return data_.get();}
imported_class() = delete;
imported_class(imported_class&) = delete;
@@ -181,13 +182,13 @@ public:
imported_class& operator=(imported_class&&) = default; ///<Move assignmend
///Check if the imported class is move-constructible
bool is_move_constructible() {return !_lib.symbol_storage().template get_constructor<T(T&&)> ().empty();}
bool is_move_constructible() {return !lib_.symbol_storage().template get_constructor<T(T&&)> ().empty();}
///Check if the imported class is move-assignable
bool is_move_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
bool is_move_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(T&&)> ("operator=").empty();}
///Check if the imported class is copy-constructible
bool is_copy_constructible() {return !_lib.symbol_storage().template get_constructor<T(const T&)>().empty();}
bool is_copy_constructible() {return !lib_.symbol_storage().template get_constructor<T(const T&)>().empty();}
///Check if the imported class is copy-assignable
bool is_copy_assignable() {return !_lib.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}
bool is_copy_assignable() {return !lib_.symbol_storage().template get_mem_fn<T, T&(const T&)>("operator=").empty();}
imported_class<T> copy() const; ///<Invoke the copy constructor. \attention Undefined behaviour if the imported object is not copy constructible.
imported_class<T> move(); ///<Invoke the move constructor. \attention Undefined behaviour if the imported object is not move constructible.
@@ -198,10 +199,10 @@ public:
void move_assign( imported_class<T> & lhs);
///Check if the class is loaded.
explicit operator bool() const {return _data;}
explicit operator bool() const {return data_;}
///Get a const reference to the std::type_info.
const std::type_info& get_type_info() {return _ti;};
const std::type_info& get_type_info() {return ti_;};
/*! Call a member function. This returns a proxy to the function.
* The proxy mechanic mechanic is necessary, so the signaute can be passed.
@@ -215,7 +216,7 @@ public:
template<class Signature>
const detail::mem_fn_call_proxy<T, Signature> call(const std::string& name)
{
return detail::mem_fn_call_proxy<T, Signature>(_data.get(), name, _lib);
return detail::mem_fn_call_proxy<T, Signature>(data_.get(), name, lib_);
}
/*! Call a qualified member function, i.e. const and or volatile.
*
@@ -228,14 +229,14 @@ public:
template<class Tin, class Signature, class = boost::enable_if<detail::unqalified_is_same<T, Tin>>>
const detail::mem_fn_call_proxy<Tin, Signature> call(const std::string& name)
{
return detail::mem_fn_call_proxy<Tin, Signature>(_data.get(), name, _lib);
return detail::mem_fn_call_proxy<Tin, Signature>(data_.get(), name, lib_);
}
///Overload of ->* for an imported method.
template<class Tin, class T2>
const detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>
operator->*(detail::mangled_library_mem_fn<Tin, T2>& mn)
{
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(_data.get(), mn);
return detail::mem_fn_call_proxy<Tin, boost::dll::experimental::detail::mangled_library_mem_fn<Tin, T2>>(data_.get(), mn);
}
///Import a method of the class.
@@ -243,7 +244,7 @@ public:
typename boost::dll::experimental::detail::mangled_import_type<boost::dll::experimental::detail::sequence<T, Args...>>::type
import(const std::string & name)
{
return boost::dll::experimental::import_mangled<T, Args...>(_lib, name);
return boost::dll::experimental::import_mangled<T, Args...>(lib_, name);
}
};
@@ -259,10 +260,8 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
if (!ctor.has_allocating() || !dtor.has_deleting())
{
boost::dll::fs::error_code ec;
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
std::error_code ec = std::make_error_code(
std::errc::bad_file_descriptor
);
// report_error() calls dlsym, do not use it here!
@@ -288,10 +287,8 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
if (!ctor.has_standard() || !dtor.has_standard())
{
boost::dll::fs::error_code ec;
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
std::error_code ec = std::make_error_code(
std::errc::bad_file_descriptor
);
// report_error() calls dlsym, do not use it here!
@@ -316,11 +313,11 @@ inline std::unique_ptr<T, detail::deleter<T>> imported_class<T>::make_data(const
template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, Args...args)
: _lib(lib),
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
_is_allocating(false),
_size(0),
_ti(lib.get_type_info<T>())
: lib_(lib),
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
is_allocating_(false),
size_(0),
ti_(lib.get_type_info<T>())
{
}
@@ -328,11 +325,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_libra
template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_library & lib, std::size_t size, Args...args)
: _lib(lib),
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
_is_allocating(true),
_size(size),
_ti(lib.get_type_info<T>())
: lib_(lib),
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
is_allocating_(true),
size_(size),
ti_(lib.get_type_info<T>())
{
}
@@ -340,11 +337,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, const smart_libra
template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, Args...args)
: _lib(boost::move(lib)),
_data(make_data<Args...>(lib, static_cast<Args>(args)...)),
_is_allocating(false),
_size(0),
_ti(lib.get_type_info<T>())
: lib_(std::move(lib)),
data_(make_data<Args...>(lib_, static_cast<Args>(args)...)),
is_allocating_(false),
size_(0),
ti_(lib.get_type_info<T>())
{
}
@@ -352,11 +349,11 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library &&
template<typename T>
template<typename ...Args>
imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library && lib, std::size_t size, Args...args)
: _lib(boost::move(lib)),
_data(make_data<Args...>(lib, size, static_cast<Args>(args)...)),
_is_allocating(true),
_size(size),
_ti(lib.get_type_info<T>())
: lib_(std::move(lib)),
data_(make_data<Args...>(lib_, size, static_cast<Args>(args)...)),
is_allocating_(true),
size_(size),
ti_(lib.get_type_info<T>())
{
}
@@ -364,31 +361,31 @@ imported_class<T>::imported_class(detail::sequence<Args...> *, smart_library &&
template<typename T>
inline imported_class<T> boost::dll::experimental::imported_class<T>::copy() const
{
if (this->_is_allocating)
return imported_class<T>::template make<const T&>(_lib, *_data);
if (this->is_allocating_)
return imported_class<T>::template make<const T&>(lib_, *data_);
else
return imported_class<T>::template make<const T&>(_lib, _size, *_data);
return imported_class<T>::template make<const T&>(lib_, size_, *data_);
}
template<typename T>
inline imported_class<T> boost::dll::experimental::imported_class<T>::move()
{
if (this->_is_allocating)
return imported_class<T>::template make<T&&>(_lib, *_data);
if (this->is_allocating_)
return imported_class<T>::template make<T&&>(lib_, *data_);
else
return imported_class<T>::template make<T&&>(_lib, _size, *_data);
return imported_class<T>::template make<T&&>(lib_, size_, *data_);
}
template<typename T>
inline void boost::dll::experimental::imported_class<T>::copy_assign(const imported_class<T>& lhs) const
{
this->call<T&(const T&)>("operator=")(*lhs._data);
this->call<T&(const T&)>("operator=")(*lhs.data_);
}
template<typename T>
inline void boost::dll::experimental::imported_class<T>::move_assign(imported_class<T>& lhs)
{
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs._data));
this->call<T&(T&&)>("operator=")(static_cast<T&&>(*lhs.data_));
}
@@ -423,90 +420,43 @@ inline void boost::dll::experimental::imported_class<T>::move_assign(imported_cl
* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
*/
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, std::size_t size, Args...args)
import_class(smart_library lib, std::size_t size, Args...args)
{
smart_library lib(lib_);
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, Args...args)
import_class(smart_library lib, Args...args)
{
smart_library lib(lib_);
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, const std::string & alias_name, Args...args)
{
smart_library lib(lib_);
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, std::size_t size, const std::string & alias_name, Args...args)
{
smart_library lib(lib_);
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(const smart_library& lib_, const std::string & alias_name, std::size_t size, Args...args)
{
smart_library lib(lib_);
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, Args...args)
{
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, const std::string & alias_name, Args...args)
import_class(smart_library lib, const std::string & alias_name, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), static_cast<Args>(args)...);
return imported_class<T>::template make<Args...>(std::move(lib), static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, std::size_t size, Args...args)
{
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, std::size_t size, const std::string & alias_name, Args...args)
import_class(smart_library lib, std::size_t size, const std::string & alias_name, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}
//! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
template<typename T, typename ... Args> imported_class<T>
import_class(smart_library && lib, const std::string & alias_name, std::size_t size, Args...args)
import_class(smart_library lib, const std::string & alias_name, std::size_t size, Args...args)
{
lib.add_type_alias<T>(alias_name);
return imported_class<T>::template make<Args...>(boost::move(lib), size, static_cast<Args>(args)...);
return imported_class<T>::template make<Args...>(std::move(lib), size, static_cast<Args>(args)...);
}
/*! \overload boost::dll::import_class(const smart_library& lib, std::size_t, Args...)
* \note This function does add the type alias to the \ref boost::dll::experimental::smart_library.
*/

View File

@@ -19,13 +19,11 @@
#endif
#include <boost/make_shared.hpp>
#include <boost/move/move.hpp>
#include <boost/dll/smart_library.hpp>
#include <boost/dll/detail/import_mangled_helpers.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_object.hpp>
#include <memory> // std::addressof
#include <type_traits>
#ifdef BOOST_HAS_PRAGMA_ONCE
@@ -43,7 +41,7 @@ class mangled_library_function {
boost::shared_ptr<shared_library> lib_;
function_tuple<Ts...> f_;
public:
constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) BOOST_NOEXCEPT
constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) noexcept
: lib_(lib)
, f_(func_ptr...)
{}
@@ -77,7 +75,7 @@ class mangled_library_mem_fn<Class, sequence<Ts...>> {
call_tuple_t f_;
public:
constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT
constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) noexcept
: lib_(lib)
, f_(func_ptr...)
{}
@@ -94,8 +92,8 @@ public:
// simple enough to be here
template<class Seq> struct is_variable : boost::false_type {};
template<typename T> struct is_variable<sequence<T>> : boost::is_object<T> {};
template<class Seq> struct is_variable : std::false_type {};
template<typename T> struct is_variable<sequence<T>> : std::is_object<T> {};
template <class Sequence,
bool isFunction = is_function_seq<Sequence>::value,
@@ -113,7 +111,7 @@ struct mangled_import_type<sequence<Args...>, true,false,false> //is function
{
return type(
boost::make_shared<shared_library>(p.shared_lib()),
boost::addressof(p.get_function<Args>(name))...);
std::addressof(p.get_function<Args>(name))...);
}
};
@@ -154,7 +152,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
{
return type(
boost::make_shared<shared_library>(p.shared_lib()),
boost::addressof(p.get_variable<T>(name)));
std::addressof(p.get_variable<T>(name)));
}
};
@@ -186,7 +184,7 @@ struct mangled_import_type<sequence<T>, false, false, true> //is variable
* \b Examples:
*
* \code
* boost::function<int(int)> f = import_mangled<int(int)>("test_lib.so", "integer_func_name");
* std::function<int(int)> f = import_mangled<int(int)>("test_lib.so", "integer_func_name");
*
* auto f_cpp11 = import_mangled<int(int)>("test_lib.so", "integer_func_name");
* \endcode
@@ -264,7 +262,7 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, co
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class ...Args>
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const char* name) {
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(smart_library&& lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
return type::make(lib, name);
@@ -272,8 +270,8 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library)
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class ...Args>
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const std::string& name) {
return import_mangled<Args...>(boost::move(lib), name.c_str());
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(smart_library&& lib, const std::string& name) {
return import_mangled<Args...>(std::move(lib), name.c_str());
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
@@ -282,7 +280,7 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, c
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);
return type::make(p, name);
return type::boostmake(p, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
@@ -293,18 +291,18 @@ BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, c
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class ...Args>
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const char* name) {
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(shared_library&& lib, const char* name) {
typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
boost::dll::experimental::smart_library p(boost::move(lib));
boost::dll::experimental::smart_library p(std::move(lib));
return type::make(p, name);
}
//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
template <class ...Args>
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const std::string& name) {
return import_mangled<Args...>(boost::move(lib), name.c_str());
BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(shared_library&& lib, const std::string& name) {
return import_mangled<Args...>(std::move(lib), name.c_str());
}
#undef BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE

View File

@@ -14,9 +14,9 @@
#include <boost/predef/os.h>
#include <boost/predef/architecture.h>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <fstream>
#include <type_traits>
#include <boost/dll/detail/pe_info.hpp>
#include <boost/dll/detail/elf_info.hpp>
@@ -50,15 +50,15 @@ private:
} fmt_;
/// @cond
inline static void throw_if_in_32bit_impl(boost::true_type /* is_32bit_platform */) {
inline static void throw_if_in_32bit_impl(std::true_type /* is_32bit_platform */) {
boost::throw_exception(std::runtime_error("Not native format: 64bit binary"));
}
inline static void throw_if_in_32bit_impl(boost::false_type /* is_32bit_platform */) BOOST_NOEXCEPT {}
inline static void throw_if_in_32bit_impl(std::false_type /* is_32bit_platform */) noexcept {}
inline static void throw_if_in_32bit() {
throw_if_in_32bit_impl( boost::integral_constant<bool, (sizeof(void*) == 4)>() );
throw_if_in_32bit_impl( std::integral_constant<bool, (sizeof(void*) == 4)>() );
}
static void throw_if_in_windows() {

View File

@@ -12,6 +12,7 @@
#include <boost/predef/os.h>
#include <boost/predef/compiler/visualc.h>
#include <boost/dll/detail/aggressive_ptr_cast.hpp>
#if BOOST_OS_WINDOWS
# include <boost/winapi/dll.hpp>
# include <boost/dll/detail/windows/path_from_handle.hpp>
@@ -20,6 +21,8 @@
# include <boost/dll/detail/posix/program_location_impl.hpp>
#endif
#include <memory> // std::addressof
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
@@ -30,7 +33,7 @@ namespace boost { namespace dll {
#if BOOST_OS_WINDOWS
namespace detail {
inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
inline boost::dll::fs::path program_location_impl(std::error_code& ec) {
return boost::dll::detail::path_from_handle(NULL, ec);
}
} // namespace detail
@@ -53,12 +56,12 @@ namespace detail {
* \endcode
*/
template <class T>
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol, boost::dll::fs::error_code& ec) {
static_assert(boost::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer");
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol, std::error_code& ec) {
static_assert(std::is_pointer<T>::value, "boost::dll::symbol_location_ptr works only with pointers! `ptr_to_symbol` must be a pointer");
boost::dll::fs::path ret;
if (!ptr_to_symbol) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_address
ec = std::make_error_code(
std::errc::bad_address
);
return ret;
@@ -85,8 +88,8 @@ namespace detail {
ret = info.dli_fname;
} else {
boost::dll::detail::reset_dlerror();
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_address
ec = std::make_error_code(
std::errc::bad_address
);
}
@@ -94,11 +97,11 @@ namespace detail {
#endif
}
//! \overload symbol_location_ptr(const void* ptr_to_symbol, boost::dll::fs::error_code& ec)
//! \overload symbol_location_ptr(const void* ptr_to_symbol, std::error_code& ec)
template <class T>
inline boost::dll::fs::path symbol_location_ptr(T ptr_to_symbol) {
boost::dll::fs::path ret;
boost::dll::fs::error_code ec;
std::error_code ec;
ret = boost::dll::symbol_location_ptr(ptr_to_symbol, ec);
if (ec) {
@@ -132,10 +135,10 @@ namespace detail {
* \endcode
*/
template <class T>
inline boost::dll::fs::path symbol_location(const T& symbol, boost::dll::fs::error_code& ec) {
inline boost::dll::fs::path symbol_location(const T& symbol, std::error_code& ec) {
ec.clear();
return boost::dll::symbol_location_ptr(
boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
boost::dll::detail::aggressive_ptr_cast<const void*>(std::addressof(symbol)),
ec
);
}
@@ -146,15 +149,15 @@ namespace detail {
template <class T>
inline boost::dll::fs::path symbol_location(const T& symbol, const char* /*workaround*/ = 0)
#else
//! \overload symbol_location(const T& symbol, boost::dll::fs::error_code& ec)
//! \overload symbol_location(const T& symbol, std::error_code& ec)
template <class T>
inline boost::dll::fs::path symbol_location(const T& symbol)
#endif
{
boost::dll::fs::path ret;
boost::dll::fs::error_code ec;
std::error_code ec;
ret = boost::dll::symbol_location_ptr(
boost::dll::detail::aggressive_ptr_cast<const void*>(boost::addressof(symbol)),
boost::dll::detail::aggressive_ptr_cast<const void*>(std::addressof(symbol)),
ec
);
@@ -180,16 +183,16 @@ namespace detail {
* \param ec Variable that will be set to the result of the operation.
* \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
*/
static inline boost::dll::fs::path this_line_location(boost::dll::fs::error_code& ec) {
typedef boost::dll::fs::path(func_t)(boost::dll::fs::error_code& );
static inline boost::dll::fs::path this_line_location(std::error_code& ec) {
typedef boost::dll::fs::path(func_t)(std::error_code& );
func_t& f = this_line_location;
return boost::dll::symbol_location(f, ec);
}
//! \overload this_line_location(boost::dll::fs::error_code& ec)
//! \overload this_line_location(std::error_code& ec)
static inline boost::dll::fs::path this_line_location() {
boost::dll::fs::path ret;
boost::dll::fs::error_code ec;
std::error_code ec;
ret = this_line_location(ec);
if (ec) {
@@ -213,15 +216,15 @@ namespace detail {
* \param ec Variable that will be set to the result of the operation.
* \throws std::bad_alloc in case of insufficient memory. Overload that does not accept \forcedlinkfs{error_code} also throws \forcedlinkfs{system_error}.
*/
inline boost::dll::fs::path program_location(boost::dll::fs::error_code& ec) {
inline boost::dll::fs::path program_location(std::error_code& ec) {
ec.clear();
return boost::dll::detail::program_location_impl(ec);
}
//! \overload program_location(boost::dll::fs::error_code& ec) {
//! \overload program_location(std::error_code& ec) {
inline boost::dll::fs::path program_location() {
boost::dll::fs::path ret;
boost::dll::fs::error_code ec;
std::error_code ec;
ret = boost::dll::detail::program_location_impl(ec);
if (ec) {

View File

@@ -16,7 +16,6 @@
#include <boost/predef/os.h>
#include <boost/core/enable_if.hpp>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/dll/detail/system_error.hpp>
#include <boost/dll/detail/aggressive_ptr_cast.hpp>
@@ -26,6 +25,9 @@
# include <boost/dll/detail/posix/shared_library_impl.hpp>
#endif
#include <type_traits>
#include <utility> // std::move
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
@@ -50,7 +52,6 @@ class shared_library
/// @endcond
{
typedef boost::dll::detail::shared_library_impl base_t;
BOOST_COPYABLE_AND_MOVABLE(shared_library)
public:
#ifdef BOOST_DLL_DOXYGEN
@@ -65,7 +66,7 @@ public:
* \post this->is_loaded() returns false.
* \throw Nothing.
*/
shared_library() BOOST_NOEXCEPT {}
shared_library() noexcept = default;
/*!
* Copy constructor that increments the reference count of an underlying shared library.
@@ -90,7 +91,7 @@ public:
* \post lib == *this
* \throw std::bad_alloc in case of insufficient memory.
*/
shared_library(const shared_library& lib, boost::dll::fs::error_code& ec)
shared_library(const shared_library& lib, std::error_code& ec)
: base_t()
{
assign(lib, ec);
@@ -103,8 +104,8 @@ public:
* \post lib.is_loaded() returns false, this->is_loaded() return true.
* \throw Nothing.
*/
shared_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT
: base_t(boost::move(static_cast<base_t&>(lib)))
shared_library(shared_library&& lib) noexcept
: base_t(std::move(lib))
{}
/*!
@@ -128,12 +129,12 @@ public:
* \param ec Variable that will be set to the result of the operation.
* \throw std::bad_alloc in case of insufficient memory.
*/
shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
shared_library(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode) {
shared_library::load(lib_path, mode, ec);
}
//! \overload shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
//! \overload shared_library(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode)
shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode, std::error_code& ec) {
shared_library::load(lib_path, mode, ec);
}
@@ -142,7 +143,7 @@ public:
*
* \param handle The native handle.
*/
explicit shared_library(native_handle_t handle)
explicit shared_library(native_handle_t handle) noexcept
: base_t(handle)
{}
@@ -153,8 +154,8 @@ public:
* \post lib == *this
* \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory.
*/
shared_library& operator=(BOOST_COPY_ASSIGN_REF(shared_library) lib) {
boost::dll::fs::error_code ec;
shared_library& operator=(const shared_library& lib) {
std::error_code ec;
assign(lib, ec);
if (ec) {
boost::dll::detail::report_error(ec, "boost::dll::shared_library::operator= failed");
@@ -170,7 +171,7 @@ public:
* \post lib.is_loaded() returns false.
* \throw Nothing.
*/
shared_library& operator=(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT {
shared_library& operator=(shared_library&& lib) noexcept {
if (lib.native() != native()) {
swap(lib);
}
@@ -185,7 +186,7 @@ public:
*
* \throw Nothing.
*/
~shared_library() BOOST_NOEXCEPT {}
~shared_library() = default;
/*!
* Makes *this share the same shared object as lib. If *this is loaded, then unloads it.
@@ -195,7 +196,7 @@ public:
* \param ec Variable that will be set to the result of the operation.
* \throw std::bad_alloc in case of insufficient memory.
*/
shared_library& assign(const shared_library& lib, boost::dll::fs::error_code& ec) {
shared_library& assign(const shared_library& lib, std::error_code& ec) {
ec.clear();
if (native() == lib.native()) {
@@ -229,7 +230,7 @@ public:
* \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory.
*/
shared_library& assign(const shared_library& lib) {
boost::dll::fs::error_code ec;
std::error_code ec;
assign(lib, ec);
if (ec) {
boost::dll::detail::report_error(ec, "boost::dll::shared_library::assign() failed");
@@ -251,7 +252,7 @@ public:
*
*/
void load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
boost::dll::fs::error_code ec;
std::error_code ec;
base_t::load(lib_path, mode, ec);
@@ -272,13 +273,13 @@ public:
* \param mode A mode that will be used on library load.
* \throw std::bad_alloc in case of insufficient memory.
*/
void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
void load(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode) {
ec.clear();
base_t::load(lib_path, mode, ec);
}
//! \overload void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
//! \overload void load(const boost::dll::fs::path& lib_path, std::error_code& ec, load_mode::type mode = load_mode::default_mode)
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, std::error_code& ec) {
ec.clear();
base_t::load(lib_path, mode, ec);
}
@@ -291,7 +292,7 @@ public:
* \post this->is_loaded() returns false.
* \throw Nothing.
*/
void unload() BOOST_NOEXCEPT {
void unload() noexcept {
base_t::unload();
}
@@ -301,27 +302,19 @@ public:
* \return true if a library has been loaded.
* \throw Nothing.
*/
bool is_loaded() const BOOST_NOEXCEPT {
bool is_loaded() const noexcept {
return base_t::is_loaded();
}
/*!
* Check if an library is not loaded.
*
* \return true if a library has not been loaded.
* \throw Nothing.
*/
bool operator!() const BOOST_NOEXCEPT {
return !is_loaded();
}
/*!
* Check if an library is loaded.
*
* \return true if a library has been loaded.
* \throw Nothing.
*/
BOOST_EXPLICIT_OPERATOR_BOOL()
explicit operator bool() const noexcept {
return is_loaded();
}
/*!
* Search for a given symbol on loaded library. Works for all symbols, including alias names.
@@ -330,13 +323,13 @@ public:
* \return `true` if the loaded library contains a symbol with a given name.
* \throw Nothing.
*/
bool has(const char* symbol_name) const BOOST_NOEXCEPT {
boost::dll::fs::error_code ec;
bool has(const char* symbol_name) const noexcept {
std::error_code ec;
return is_loaded() && !!base_t::symbol_addr(symbol_name, ec) && !ec;
}
//! \overload bool has(const char* symbol_name) const
bool has(const std::string& symbol_name) const BOOST_NOEXCEPT {
bool has(const std::string& symbol_name) const noexcept {
return has(symbol_name.c_str());
}
@@ -357,19 +350,19 @@ public:
* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
*/
template <typename T>
inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const std::string& symbol_name) const {
inline typename std::enable_if<std::is_member_pointer<T>::value || std::is_reference<T>::value, T>::type get(const std::string& symbol_name) const {
return get<T>(symbol_name.c_str());
}
//! \overload T& get(const std::string& symbol_name) const
template <typename T>
inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const std::string& symbol_name) const {
inline typename std::enable_if<!(std::is_member_pointer<T>::value || std::is_reference<T>::value), T&>::type get(const std::string& symbol_name) const {
return get<T>(symbol_name.c_str());
}
//! \overload T& get(const std::string& symbol_name) const
template <typename T>
inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const char* symbol_name) const {
inline typename std::enable_if<std::is_member_pointer<T>::value || std::is_reference<T>::value, T>::type get(const char* symbol_name) const {
return boost::dll::detail::aggressive_ptr_cast<T>(
get_void(symbol_name)
);
@@ -377,7 +370,7 @@ public:
//! \overload T& get(const std::string& symbol_name) const
template <typename T>
inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const char* symbol_name) const {
inline typename std::enable_if<!(std::is_member_pointer<T>::value || std::is_reference<T>::value), T&>::type get(const char* symbol_name) const {
return *boost::dll::detail::aggressive_ptr_cast<T*>(
get_void(symbol_name)
);
@@ -411,11 +404,11 @@ private:
// get_void is required to reduce binary size: it does not depend on a template
// parameter and will be instantiated only once.
void* get_void(const char* sb) const {
boost::dll::fs::error_code ec;
std::error_code ec;
if (!is_loaded()) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
// report_error() calls dlsym, do not use it here!
@@ -442,7 +435,7 @@ public:
*
* \return Platform-specific handle.
*/
native_handle_t native() const BOOST_NOEXCEPT {
native_handle_t native() const noexcept {
return base_t::native();
}
@@ -459,10 +452,10 @@ public:
* \throw \forcedlinkfs{system_error}, std::bad_alloc.
*/
boost::dll::fs::path location() const {
boost::dll::fs::error_code ec;
std::error_code ec;
if (!is_loaded()) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
boost::throw_exception(
@@ -494,10 +487,10 @@ public:
* \return Full path to the shared library.
* \throw std::bad_alloc.
*/
boost::dll::fs::path location(boost::dll::fs::error_code& ec) const {
boost::dll::fs::path location(std::error_code& ec) const {
if (!is_loaded()) {
ec = boost::dll::fs::make_error_code(
boost::dll::fs::errc::bad_file_descriptor
ec = std::make_error_code(
std::errc::bad_file_descriptor
);
return boost::dll::fs::path();
@@ -546,7 +539,7 @@ public:
* \param rhs Library to swap with.
* \throw Nothing.
*/
void swap(shared_library& rhs) BOOST_NOEXCEPT {
void swap(shared_library& rhs) noexcept {
base_t::swap(rhs);
}
};
@@ -554,22 +547,22 @@ public:
/// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing.
inline bool operator==(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
inline bool operator==(const shared_library& lhs, const shared_library& rhs) noexcept {
return lhs.native() == rhs.native();
}
/// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing.
inline bool operator!=(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
inline bool operator!=(const shared_library& lhs, const shared_library& rhs) noexcept {
return lhs.native() != rhs.native();
}
/// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing.
inline bool operator<(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT {
inline bool operator<(const shared_library& lhs, const shared_library& rhs) noexcept {
return lhs.native() < rhs.native();
}
/// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing.
inline void swap(shared_library& lhs, shared_library& rhs) BOOST_NOEXCEPT {
inline void swap(shared_library& lhs, shared_library& rhs) noexcept {
lhs.swap(rhs);
}

View File

@@ -207,37 +207,37 @@ enum type {
/// Free operators for load_mode::type flag manipulation.
BOOST_CONSTEXPR inline type operator|(type left, type right) BOOST_NOEXCEPT {
BOOST_CONSTEXPR inline type operator|(type left, type right) noexcept {
return static_cast<type>(
static_cast<unsigned int>(left) | static_cast<unsigned int>(right)
);
}
BOOST_CXX14_CONSTEXPR inline type& operator|=(type& left, type right) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline type& operator|=(type& left, type right) noexcept {
left = left | right;
return left;
}
BOOST_CONSTEXPR inline type operator&(type left, type right) BOOST_NOEXCEPT {
BOOST_CONSTEXPR inline type operator&(type left, type right) noexcept {
return static_cast<type>(
static_cast<unsigned int>(left) & static_cast<unsigned int>(right)
);
}
BOOST_CXX14_CONSTEXPR inline type& operator&=(type& left, type right) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline type& operator&=(type& left, type right) noexcept {
left = left & right;
return left;
}
BOOST_CONSTEXPR inline type operator^(type left, type right) BOOST_NOEXCEPT {
BOOST_CONSTEXPR inline type operator^(type left, type right) noexcept {
return static_cast<type>(
static_cast<unsigned int>(left) ^ static_cast<unsigned int>(right)
);
}
BOOST_CXX14_CONSTEXPR inline type& operator^=(type& left, type right) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline type& operator^=(type& left, type right) noexcept {
left = left ^ right;
return left;
}
BOOST_CONSTEXPR inline type operator~(type left) BOOST_NOEXCEPT {
BOOST_CONSTEXPR inline type operator~(type left) noexcept {
return static_cast<type>(
~static_cast<unsigned int>(left)
);

View File

@@ -9,7 +9,7 @@
#define BOOST_DLL_SMART_LIBRARY_HPP_
/// \file boost/dll/smart_library.hpp
/// \warning Extremely experimental! Requires C++11! Will change in next version of Boost! boost/dll/smart_library.hpp is not included in boost/dll.hpp
/// \warning Extremely experimental! May change in next version of Boost! boost/dll/smart_library.hpp is not included in boost/dll.hpp
/// \brief Contains the boost::dll::experimental::smart_library class for loading mangled symbols.
#include <boost/dll/config.hpp>
@@ -27,11 +27,9 @@
#include <boost/dll/detail/get_mem_fn_type.hpp>
#include <boost/dll/detail/ctor_dtor.hpp>
#include <boost/dll/detail/type_info.hpp>
#include <boost/type_traits/is_object.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_function.hpp>
#include <type_traits>
#include <utility> // std::move
namespace boost {
namespace dll {
@@ -53,10 +51,10 @@ using boost::dll::detail::destructor;
* Member functions must be defined outside of the class to be exported. That is:
* \code
* //not exported:
* struct BOOST_SYMBOL_EXPORT my_class { void func() {}};
* struct BOOST_SYMBOL_EXPORT my_class { void func() {} };
* //exported
* struct BOOST_SYMBOL_EXPORT my_class { void func();};
* void my_class::func() {};
* struct BOOST_SYMBOL_EXPORT my_class { void func(); };
* void my_class::func() {}
* \endcode
*
* With the current analysis, the first version does get exported in MSVC.
@@ -72,14 +70,14 @@ using boost::dll::detail::destructor;
* This does however not happen when the value is set inside the constructor function.
*/
class smart_library {
shared_library _lib;
detail::mangled_storage_impl _storage;
shared_library lib_;
detail::mangled_storage_impl storage_;
public:
/*!
* Get the underlying shared_library
*/
const shared_library &shared_lib() const {return _lib;}
const shared_library &shared_lib() const noexcept { return lib_;}
using mangled_storage = detail::mangled_storage_impl;
/*!
@@ -87,18 +85,18 @@ public:
*
* \throw Nothing.
*/
const mangled_storage &symbol_storage() const {return _storage;}
const mangled_storage &symbol_storage() const noexcept { return storage_; }
///Overload, for current development.
mangled_storage &symbol_storage() {return _storage;}
mangled_storage &symbol_storage() noexcept { return storage_; }
//! \copydoc shared_library::shared_library()
smart_library() BOOST_NOEXCEPT {};
smart_library() = default;
//! \copydoc shared_library::shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode)
smart_library(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
_lib.load(lib_path, mode);
_storage.load(lib_path);
lib_.load(lib_path, mode);
storage_.load(lib_path);
}
//! \copydoc shared_library::shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
@@ -117,9 +115,7 @@ public:
*
* \throw Nothing.
*/
smart_library(const smart_library & lib) BOOST_NOEXCEPT
: _lib(lib._lib), _storage(lib._storage)
{}
smart_library(const smart_library & lib) = default;
/*!
* Move a smart_library object.
*
@@ -127,9 +123,7 @@ public:
*
* \throw Nothing.
*/
smart_library(BOOST_RV_REF(smart_library) lib) BOOST_NOEXCEPT
: _lib(boost::move(lib._lib)), _storage(boost::move(lib._storage))
{}
smart_library(smart_library&& lib) = default;
/*!
* Construct from a shared_library object.
@@ -138,10 +132,10 @@ public:
*
* \throw Nothing.
*/
explicit smart_library(const shared_library & lib) BOOST_NOEXCEPT
: _lib(lib)
explicit smart_library(const shared_library & lib) noexcept
: lib_(lib)
{
_storage.load(lib.location());
storage_.load(lib.location());
}
/*!
* Construct from a shared_library object.
@@ -150,10 +144,10 @@ public:
*
* \throw Nothing.
*/
explicit smart_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT
: _lib(boost::move(static_cast<shared_library&>(lib)))
explicit smart_library(shared_library&& lib) noexcept
: lib_(std::move(lib))
{
_storage.load(lib.location());
storage_.load(lib.location());
}
/*!
@@ -164,13 +158,13 @@ public:
*
* \throw Nothing.
*/
~smart_library() BOOST_NOEXCEPT {};
~smart_library() = default;
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode)
void load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) {
boost::dll::fs::error_code ec;
_storage.load(lib_path);
_lib.load(lib_path, mode, ec);
storage_.load(lib_path);
lib_.load(lib_path, mode, ec);
if (ec) {
boost::dll::detail::report_error(ec, "load() failed");
@@ -180,15 +174,15 @@ public:
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode)
void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) {
ec.clear();
_storage.load(lib_path);
_lib.load(lib_path, mode, ec);
storage_.load(lib_path);
lib_.load(lib_path, mode, ec);
}
//! \copydoc shared_library::load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec)
void load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) {
ec.clear();
_storage.load(lib_path);
_lib.load(lib_path, mode, ec);
storage_.load(lib_path);
lib_.load(lib_path, mode, ec);
}
/*!
@@ -206,7 +200,7 @@ public:
*/
template<typename T>
T& get_variable(const std::string &name) const {
return _lib.get<T>(_storage.get_variable<T>(name));
return lib_.get<T>(storage_.get_variable<T>(name));
}
/*!
@@ -232,7 +226,7 @@ public:
*/
template<typename Func>
Func& get_function(const std::string &name) const {
return _lib.get<Func>(_storage.get_function<Func>(name));
return lib_.get<Func>(storage_.get_function<Func>(name));
}
/*!
@@ -261,8 +255,8 @@ public:
*/
template<typename Class, typename Func>
typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn get_mem_fn(const std::string& name) const {
return _lib.get<typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn>(
_storage.get_mem_fn<Class, Func>(name)
return lib_.get<typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn>(
storage_.get_mem_fn<Class, Func>(name)
);
}
@@ -284,7 +278,7 @@ public:
*/
template<typename Signature>
constructor<Signature> get_constructor() const {
return boost::dll::detail::load_ctor<Signature>(_lib, _storage.get_constructor<Signature>());
return boost::dll::detail::load_ctor<Signature>(lib_, storage_.get_constructor<Signature>());
}
/*!
@@ -306,7 +300,7 @@ public:
*/
template<typename Class>
destructor<Class> get_destructor() const {
return boost::dll::detail::load_dtor<Class>(_lib, _storage.get_destructor<Class>());
return boost::dll::detail::load_dtor<Class>(lib_, storage_.get_destructor<Class>());
}
/*!
* Load the typeinfo of the given type.
@@ -328,7 +322,7 @@ public:
template<typename Class>
const std::type_info& get_type_info() const
{
return boost::dll::detail::load_type_info<Class>(_lib, _storage);
return boost::dll::detail::load_type_info<Class>(lib_, storage_);
}
/**
* This function can be used to add a type alias.
@@ -352,69 +346,66 @@ public:
* \warning The alias will only be applied for the type signature, it will not replace the token in the scoped name.
*/
template<typename Alias> void add_type_alias(const std::string& name) {
this->_storage.add_alias<Alias>(name);
this->storage_.add_alias<Alias>(name);
}
//! \copydoc shared_library::unload()
void unload() BOOST_NOEXCEPT {
_storage.clear();
_lib.unload();
void unload() noexcept {
storage_.clear();
lib_.unload();
}
//! \copydoc shared_library::is_loaded() const
bool is_loaded() const BOOST_NOEXCEPT {
return _lib.is_loaded();
}
//! \copydoc shared_library::operator!() const
bool operator!() const BOOST_NOEXCEPT {
return !is_loaded();
bool is_loaded() const noexcept {
return lib_.is_loaded();
}
//! \copydoc shared_library::operator bool() const
BOOST_EXPLICIT_OPERATOR_BOOL()
explicit operator bool() const noexcept {
return is_loaded();
}
//! \copydoc shared_library::has(const char* symbol_name) const
bool has(const char* symbol_name) const BOOST_NOEXCEPT {
return _lib.has(symbol_name);
bool has(const char* symbol_name) const noexcept {
return lib_.has(symbol_name);
}
//! \copydoc shared_library::has(const std::string& symbol_name) const
bool has(const std::string& symbol_name) const BOOST_NOEXCEPT {
return _lib.has(symbol_name);
bool has(const std::string& symbol_name) const noexcept {
return lib_.has(symbol_name);
}
//! \copydoc shared_library::assign(const shared_library& lib)
smart_library& assign(const smart_library& lib) {
_lib.assign(lib._lib);
_storage.assign(lib._storage);
lib_.assign(lib.lib_);
storage_.assign(lib.storage_);
return *this;
}
//! \copydoc shared_library::swap(shared_library& rhs)
void swap(smart_library& rhs) BOOST_NOEXCEPT {
_lib.swap(rhs._lib);
_storage.swap(rhs._storage);
void swap(smart_library& rhs) noexcept {
lib_.swap(rhs.lib_);
storage_.swap(rhs.storage_);
}
};
/// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing.
inline bool operator==(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
inline bool operator==(const smart_library& lhs, const smart_library& rhs) noexcept {
return lhs.shared_lib().native() == rhs.shared_lib().native();
}
/// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing.
inline bool operator!=(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
inline bool operator!=(const smart_library& lhs, const smart_library& rhs) noexcept {
return lhs.shared_lib().native() != rhs.shared_lib().native();
}
/// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing.
inline bool operator<(const smart_library& lhs, const smart_library& rhs) BOOST_NOEXCEPT {
inline bool operator<(const smart_library& lhs, const smart_library& rhs) noexcept {
return lhs.shared_lib().native() < rhs.shared_lib().native();
}
/// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing.
inline void swap(smart_library& lhs, smart_library& rhs) BOOST_NOEXCEPT {
inline void swap(smart_library& lhs, smart_library& rhs) noexcept {
lhs.swap(rhs);
}
@@ -439,14 +430,14 @@ void get(const smart_library& sm, const std::string &name);
#endif
template<class T>
typename boost::enable_if<boost::is_object<T>, T&>::type get(const smart_library& sm, const std::string &name)
typename std::enable_if<std::is_object<T>::value, T&>::type get(const smart_library& sm, const std::string &name)
{
return sm.get_variable<T>(name);
}
template<class T>
typename boost::enable_if<boost::is_function<T>, T&>::type get(const smart_library& sm, const std::string &name)
typename std::enable_if<std::is_function<T>::value, T&>::type get(const smart_library& sm, const std::string &name)
{
return sm.get_function<T>(name);
}

View File

@@ -99,6 +99,7 @@ project
[ 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_mangling.cpp ]
[ run cpp_load_test.cpp : : cpp_plugin ]
[ run cpp_import_test.cpp : : cpp_plugin ]
[ run template_method_linux_test.cpp : : cpp_plugin ]

View File

@@ -21,7 +21,7 @@ init:
# From this point and below code is same for all the Boost libs
###############################################################################################################
version: 1.64.{build}-{branch}
version: 1.87.{build}-{branch}
# branches to build
branches:
@@ -63,10 +63,11 @@ environment:
# ADDPATH: C:\cygwin64\bin;
# TOOLSET: gcc
# CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 11,14,1z
# MinGW 32 bit is not supported by boost system any more
#- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\mingw\bin;
# TOOLSET: gcc
# CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc

View File

@@ -8,8 +8,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include <boost/dll/config.hpp>
#include <string>
@@ -138,4 +136,3 @@ cpp_plugin_type_pasrser::type_test(
{}
} // namespace space
#endif

View File

@@ -9,8 +9,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include "../example/b2_workarounds.hpp"
#include <iostream>
@@ -24,7 +22,7 @@ using namespace std;
#include <boost/core/lightweight_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <functional>
#define L cout << __LINE__ << endl;
@@ -92,7 +90,7 @@ int main(int argc, char* argv[])
BOOST_TEST((cl->*fun2)(5 ,2 ) == 7 );
//test if it binds.
boost::function<int(override_class* const, int, int)> mem_fn_obj = func;
std::function<int(override_class* const, int, int)> mem_fn_obj = func;
const std::type_info & ti = cl.get_type_info();
@@ -109,7 +107,3 @@ int main(int argc, char* argv[])
return boost::report_errors();
}
#else
int main() {return 0;}
#endif

View File

@@ -8,8 +8,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include "../example/b2_workarounds.hpp"
#include <boost/dll/smart_library.hpp>
@@ -18,8 +16,8 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include <functional>
#include <iostream>
struct override_class
@@ -51,7 +49,7 @@ int main(int argc, char* argv[])
ovl(5.0);
BOOST_TEST(*sp_variable == 5.0);
boost::function<void(int)> f_test = ovl;//test if it binds
std::function<void(int)> f_test = ovl;//test if it binds
f_test(-2);
BOOST_TEST(*unscoped_var == -2);
@@ -76,6 +74,3 @@ int main(int argc, char* argv[])
return boost::report_errors();
}
#else
int main() {return 0;}
#endif

View File

@@ -10,12 +10,7 @@
#include <boost/config.hpp>
#include <boost/predef.h>
#if (__cplusplus >= 201103L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
// Make sure that it at least compiles
# include <boost/dll/smart_library.hpp>
#endif
#if (__cplusplus >= 201402L) || (BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(14,0,0))
#include "../example/b2_workarounds.hpp"
@@ -231,7 +226,3 @@ int main(int argc, char* argv[])
std::cerr << 28 << ' ';
return boost::report_errors();
}
#else
int main() {return 0;}
#endif

View File

@@ -8,8 +8,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include "../example/b2_workarounds.hpp"
#include <boost/dll/smart_library.hpp>
@@ -128,6 +126,3 @@ int main(int argc, char* argv[])
return boost::report_errors();
}
#else
int main() {return 0;}
#endif

155
test/cpp_mangling.cpp Normal file
View File

@@ -0,0 +1,155 @@
// Copyright 2024 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/core/lightweight_test.hpp>
#include <boost/dll/detail/demangling/msvc.hpp>
int main() {
namespace parser = boost::dll::detail::parser;
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: virtual __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: virtual __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: virtual __cdecl foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __cdecl foo::~foo(void) __ptr64"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __cdecl foo::~foo(void) __ptr64"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __cdecl foo::~foo(void) __ptr64"));
BOOST_TEST(parser::is_destructor_with_name("some_space::some_father::~some_father(void)")("public: __cdecl some_space::some_father::~some_father(void) __ptr64"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: virtual __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: virtual __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: virtual __thiscall foo::~foo(void)"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("public: __thiscall foo::~foo(void) __ptr32"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("private: __thiscall foo::~foo(void) __ptr32"));
BOOST_TEST(parser::is_destructor_with_name("foo::~foo(void)")("protected: __thiscall foo::~foo(void) __ptr32"));
BOOST_TEST(parser::is_destructor_with_name("some_space::some_father::~some_father(void)")("public: __thiscall some_space::some_father::~some_father(void) __ptr64"));
boost::dll::detail::mangled_storage_impl ms;
{
void(*ptr0)(int) = nullptr;
boost::core::string_view s = "integer";
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr0));
BOOST_TEST_EQ(s, "eger");
}
{
void(*ptr1)(int) = nullptr;
boost::core::string_view s = "int";
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr1));
BOOST_TEST(s.empty());
}
{
void(*ptr2)() = nullptr;
boost::core::string_view s = "void";
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr2));
BOOST_TEST(s.empty());
}
{
void(*ptr3)(int,int) = nullptr;
boost::core::string_view s = "int,int";
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr3));
BOOST_TEST(s.empty());
}
{
void(*ptr4)(int,int,int) = nullptr;
boost::core::string_view s = "int,int,int";
BOOST_TEST(parser::try_consume_arg_list(s, ms, ptr4));
BOOST_TEST(s.empty());
}
BOOST_TEST((
parser::is_constructor_with_name<void(*)()>("some_space::some_class::some_class", ms)
("public: __cdecl some_space::some_class::some_class(void) __ptr64")
));
BOOST_TEST((
parser::is_constructor_with_name<void(*)(int)>("some_space::some_class::some_class", ms)
("private: __cdecl some_space::some_class::some_class(int)")
));
BOOST_TEST((
parser::is_constructor_with_name<void(*)(int,int)>("some_space::some_class::some_class", ms)
("private: __cdecl some_space::some_class::some_class(int,int)")
));
BOOST_TEST((
parser::is_variable_with_name<int>("some_space::some_class::value", ms)
("public: static int some_space::some_class::value")
));
BOOST_TEST((
parser::is_variable_with_name<int>("some_space::some_class::value", ms)
("int some_space::some_class::value")
));
BOOST_TEST((
parser::is_variable_with_name<double>("some_space::variable", ms)
("public: static double some_space::variable")
));
BOOST_TEST((
!parser::is_variable_with_name<double>("some_space::variable", ms)
("public: static int some_space::variable_that_is_not_exist")
));
BOOST_TEST((
parser::is_variable_with_name<const double>("unscoped_c_var", ms)
("double const unscoped_c_var")
));
BOOST_TEST((
parser::is_function_with_name<void(*)(int)>("overloaded", ms)
("void __cdecl overloaded(int)")
));
BOOST_TEST((
parser::is_function_with_name<void(*)(double)>("overloaded", ms)
("void __cdecl overloaded(double)")
));
BOOST_TEST((
parser::is_function_with_name<const int&(*)()>("some_space::scoped_fun", ms)
("int const & __ptr64 __cdecl some_space::scoped_fun(void)")
));
BOOST_TEST((
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
("public: int __thiscall int::func(int,int)volatile ")
));
BOOST_TEST((
parser::is_mem_fn_with_name<const volatile int, double(*)(double)>("func", ms)
("private: double __thiscall int::func(double)const volatile ")
));
BOOST_TEST((
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
("public: int __cdecl int::func(int,int)volatile __ptr64")
));
BOOST_TEST((
parser::is_mem_fn_with_name<volatile int, int(*)(int,int)>("func", ms)
("public: virtual int __cdecl int::func(int,int)volatile __ptr64")
));
return boost::report_errors();
}

View File

@@ -9,8 +9,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include <boost/dll/config.hpp>
#include <boost/variant.hpp>
@@ -198,6 +196,3 @@ namespace space {
template BOOST_SYMBOL_EXPORT int my_plugin::Func2<::space::my_plugin>();
template BOOST_SYMBOL_EXPORT int my_plugin::AFunc<::space::my_plugin>();
}
#endif

View File

@@ -8,7 +8,6 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include "../example/b2_workarounds.hpp"
#include <boost/core/lightweight_test.hpp>
@@ -165,10 +164,3 @@ main(int argc, char* argv[])
return boost::report_errors();
}
#else
int
main()
{
return 0;
}
#endif

View File

@@ -39,7 +39,8 @@ int main(int argc, char* argv[])
#if defined(__GNUC__) && __GNUC__ >= 4 && defined(__ELF__)
BOOST_TEST(std::find(symb.begin(), symb.end(), "protected_function") != symb.end());
#endif
std::cout << "\n\n'boostdll' symbols:\n";
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());
@@ -48,6 +49,7 @@ int main(int argc, char* argv[])
BOOST_TEST(std::find(symb.begin(), symb.end(), "say_hello") == symb.end());
BOOST_TEST(lib_info.symbols(std::string("boostdll")) == symb);
std::cout << "\n\n'empty' symbols:\n";
std::vector<std::string> empty = lib_info.symbols("empty");
BOOST_TEST(empty.empty() == true);

View File

@@ -9,13 +9,8 @@
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include <boost/dll/smart_library.hpp>
#include <boost/dll/import_mangled.hpp>
#include <boost/dll/import_class.hpp>
#endif
#include <boost/dll.hpp>

View File

@@ -12,7 +12,6 @@
#include <boost/dll/shared_library.hpp>
#include <boost/dll/library_info.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/function.hpp>
// Unit Tests

View File

@@ -11,7 +11,7 @@
#include "../example/b2_workarounds.hpp"
#include <boost/dll.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/function.hpp>
#include <functional>
#include <boost/fusion/container.hpp>
// lib functions
@@ -35,7 +35,7 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
std::vector<int> v(1000);
{
boost::function<say_hello_func> sz2
std::function<say_hello_func> sz2
= import_symbol<say_hello_func>(shared_library_path, "say_hello");
sz2();
@@ -52,17 +52,17 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
#endif
{
boost::function<std::size_t(const std::vector<int>&)> sz
std::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;
std::function<do_share_t> f;
{
boost::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
std::function<do_share_t> f2 = import_alias<do_share_t>(shared_library_path, "do_share");
f = f2;
}
@@ -91,13 +91,13 @@ void refcountable_test(boost::dll::fs::path shared_library_path) {
}
{
boost::function<int&()> f = import_alias<int&()>(shared_library_path, "ref_returning_function");
std::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");
std::function<int&()> f1 = import_alias<int&()>(shared_library_path, "ref_returning_function");
BOOST_TEST(f1() == 10);
f1() += 10;
@@ -157,7 +157,7 @@ int main(int argc, char* argv[]) {
BOOST_TEST(sl.get<const int>("const_integer_g") == 777);
boost::function<int(int)> inc = sl.get<int(int)>("increment");
std::function<int(int)> inc = sl.get<int(int)>("increment");
BOOST_TEST(inc(1) == 2);
BOOST_TEST(inc(2) == 3);
BOOST_TEST(inc(3) == 4);
@@ -170,7 +170,7 @@ int main(int argc, char* argv[]) {
// Checking aliases
boost::function<std::size_t(const std::vector<int>&)> sz
std::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);

View File

@@ -9,6 +9,11 @@
#include "../example/b2_workarounds.hpp"
#include <boost/dll.hpp>
#include <system_error>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/core/lightweight_test.hpp>
// Unit Tests
@@ -403,7 +408,8 @@ int main(int argc, char* argv[])
std::cout << "\nLibrary location: " << sl.location();
BOOST_TEST( boost::dll::fs::equivalent(sl.location(), program_location()) );
boost::dll::fs::error_code ec;
// Make sure that works with boost::system::error_code
boost::system::error_code ec;
shared_library sl2(program_location());
BOOST_TEST(sl2.is_loaded());
BOOST_TEST( boost::dll::fs::equivalent(sl2.location(), program_location()) );
@@ -478,7 +484,7 @@ int main(int argc, char* argv[])
{ // error_code load calls test
boost::dll::fs::error_code ec;
std::error_code ec;
shared_library sl(shared_library_path / "dir_that_does_not_exist", ec);
BOOST_TEST(ec);
BOOST_TEST(!sl.is_loaded());
@@ -512,6 +518,75 @@ int main(int argc, char* argv[])
BOOST_TEST(!sl);
}
{ // error_code load calls test
std::error_code ec; // make sure that works with std::error_code
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);
}
{ // error_code load calls test
boost::system::error_code ec; // make sure that works with boost::system::error_code
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);

View File

@@ -6,7 +6,6 @@
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include <boost/dll/smart_library.hpp>
#include <boost/dll/import_mangled.hpp>
@@ -60,8 +59,3 @@ int main(int argc, char** argv) {
return boost::report_errors();
}
#else
int main() {}
#endif