]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/dll/import_mangled.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / dll / import_mangled.hpp
CommitLineData
92f5a8d4 1// Copyright 2015-2018 Klemens D. Morgenstern
1e59de90 2// Copyright Antony Polukhin, 2019-2022
7c673cae
FG
3//
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt
6// or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8
9#ifndef BOOST_DLL_IMPORT_MANGLED_HPP_
10#define BOOST_DLL_IMPORT_MANGLED_HPP_
11
20effc67
TL
12/// \file boost/dll/import_mangled.hpp
13/// \warning Extremely experimental! Requires C++11! Will change in next version of Boost! boost/dll/import_mangled.hpp is not included in boost/dll.hpp
14/// \brief Contains the boost::dll::experimental::import_mangled function for importing mangled symbols.
15
92f5a8d4 16#include <boost/dll/config.hpp>
20effc67
TL
17#if (__cplusplus < 201103L) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L)
18# error This file requires C++11 at least!
19#endif
20
7c673cae
FG
21#include <boost/make_shared.hpp>
22#include <boost/move/move.hpp>
23#include <boost/dll/smart_library.hpp>
24#include <boost/dll/detail/import_mangled_helpers.hpp>
11fdf7f2
TL
25#include <boost/core/addressof.hpp>
26#include <boost/core/enable_if.hpp>
7c673cae
FG
27#include <boost/type_traits/conditional.hpp>
28#include <boost/type_traits/is_object.hpp>
29
30
7c673cae
FG
31#ifdef BOOST_HAS_PRAGMA_ONCE
32# pragma once
33#endif
34
35namespace boost { namespace dll { namespace experimental {
36
37namespace detail
38{
39
7c673cae
FG
40template <class ... Ts>
41class mangled_library_function {
42 // Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
b32b8144
FG
43 boost::shared_ptr<shared_library> lib_;
44 function_tuple<Ts...> f_;
7c673cae 45public:
b32b8144
FG
46 constexpr mangled_library_function(const boost::shared_ptr<shared_library>& lib, Ts*... func_ptr) BOOST_NOEXCEPT
47 : lib_(lib)
48 , f_(func_ptr...)
7c673cae
FG
49 {}
50
51
52 // Compilation error at this point means that imported function
53 // was called with unmatching parameters.
54 //
55 // Example:
56 // auto f = dll::import_mangled<void(int), void(double)>("function", "lib.so");
57 // f("Hello"); // error: invalid conversion from 'const char*' to 'int'
58 // f(1, 2); // error: too many arguments to function
59 // f(); // error: too few arguments to function
60 template <class... Args>
b32b8144
FG
61 auto operator()(Args&&... args) const
62 -> decltype( f_(static_cast<Args&&>(args)...) )
7c673cae 63 {
b32b8144 64 return f_(static_cast<Args&&>(args)...);
7c673cae
FG
65 }
66};
67
68
69template<class Class, class Sequence>
70class mangled_library_mem_fn;
71
72template <class Class, class ... Ts>
73class mangled_library_mem_fn<Class, sequence<Ts...>> {
74 // Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster.
75 typedef mem_fn_tuple<Ts...> call_tuple_t;
b32b8144
FG
76 boost::shared_ptr<shared_library> lib_;
77 call_tuple_t f_;
7c673cae
FG
78
79public:
b32b8144
FG
80 constexpr mangled_library_mem_fn(const boost::shared_ptr<shared_library>& lib, typename Ts::mem_fn... func_ptr) BOOST_NOEXCEPT
81 : lib_(lib)
82 , f_(func_ptr...)
7c673cae
FG
83 {}
84
85 template <class ClassIn, class... Args>
b32b8144
FG
86 auto operator()(ClassIn *cl, Args&&... args) const
87 -> decltype( f_(cl, static_cast<Args&&>(args)...) )
7c673cae 88 {
b32b8144 89 return f_(cl, static_cast<Args&&>(args)...);
7c673cae
FG
90 }
91};
92
93
94
95
96// simple enough to be here
97template<class Seq> struct is_variable : boost::false_type {};
98template<typename T> struct is_variable<sequence<T>> : boost::is_object<T> {};
99
100template <class Sequence,
101 bool isFunction = is_function_seq<Sequence>::value,
102 bool isMemFn = is_mem_fn_seq <Sequence>::value,
103 bool isVariable = is_variable <Sequence>::value>
104struct mangled_import_type;
105
106template <class ...Args>
107struct mangled_import_type<sequence<Args...>, true,false,false> //is function
108{
109 typedef boost::dll::experimental::detail::mangled_library_function<Args...> type;
110 static type make(
111 const boost::dll::experimental::smart_library& p,
112 const std::string& name)
113 {
114 return type(
115 boost::make_shared<shared_library>(p.shared_lib()),
116 boost::addressof(p.get_function<Args>(name))...);
117 }
118};
119
120template <class Class, class ...Args>
121struct mangled_import_type<sequence<Class, Args...>, false, true, false> //is member-function
122{
123 typedef typename boost::dll::experimental::detail::make_mem_fn_seq<Class, Args...>::type actual_sequence;
124 typedef typename boost::dll::experimental::detail::mangled_library_mem_fn<Class, actual_sequence> type;
125
126
127 template<class ... ArgsIn>
128 static type make_impl(
129 const boost::dll::experimental::smart_library& p,
130 const std::string & name,
131 sequence<ArgsIn...> * )
132 {
133 return type(boost::make_shared<shared_library>(p.shared_lib()),
134 p.get_mem_fn<typename ArgsIn::class_type, typename ArgsIn::func_type>(name)...);
135 }
136
137 static type make(
138 const boost::dll::experimental::smart_library& p,
139 const std::string& name)
140 {
141 return make_impl(p, name, static_cast<actual_sequence*>(nullptr));
142 }
143
144};
145
146template <class T>
147struct mangled_import_type<sequence<T>, false, false, true> //is variable
148{
149 typedef boost::shared_ptr<T> type;
150
151 static type make(
152 const boost::dll::experimental::smart_library& p,
153 const std::string& name)
154 {
155 return type(
156 boost::make_shared<shared_library>(p.shared_lib()),
157 boost::addressof(p.get_variable<T>(name)));
158 }
159
160};
161
162
163} // namespace detail
164
165
166#ifndef BOOST_DLL_DOXYGEN
167# define BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE inline typename \
168 boost::dll::experimental::detail::mangled_import_type<boost::dll::experimental::detail::sequence<Args...>>::type
169#endif
170
171/*
172 * Variants:
173 * import_mangled<int>("Stuff");
174 * import_mangled<thingy(xyz)>("Function");
175 * import mangled<thingy, void(int)>("Function");
176 */
177
178/*!
179* Returns callable object or boost::shared_ptr<T> that holds the symbol imported
180* from the loaded library. Returned value refcounts usage
181* of the loaded shared library, so that it won't get unload until all copies of return value
182* are not destroyed.
183*
184* For importing symbols by \b alias names use \forcedlink{import_alias} method.
185*
186* \b Examples:
187*
188* \code
189* boost::function<int(int)> f = import_mangled<int(int)>("test_lib.so", "integer_func_name");
190*
191* auto f_cpp11 = import_mangled<int(int)>("test_lib.so", "integer_func_name");
192* \endcode
193*
194* \code
195* boost::shared_ptr<int> i = import_mangled<int>("test_lib.so", "integer_name");
196* \endcode
197*
198* Additionally you can also import overloaded symbols, including member-functions.
199*
200* \code
201* auto fp = import_mangled<void(int), void(double)>("test_lib.so", "func");
202* \endcode
203*
204* \code
205* auto fp = import_mangled<my_class, void(int), void(double)>("test_lib.so", "func");
206* \endcode
207*
208* If qualified member-functions are needed, this can be set by repeating the class name with const or volatile.
209* All following signatures after the redifintion will use this, i.e. the latest.
210*
211* * * \code
212* auto fp = import_mangled<my_class, void(int), void(double),
213* const my_class, void(int), void(double)>("test_lib.so", "func");
214* \endcode
215*
216* \b Template \b parameter \b T: Type of the symbol that we are going to import. Must be explicitly specified.
217*
218* \param lib Path to shared library or shared library to load function from.
219* \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*.
220* \param mode An mode that will be used on library load.
221*
222* \return callable object if T is a function type, or boost::shared_ptr<T> if T is an object type.
223*
92f5a8d4 224* \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded.
7c673cae
FG
225* Overload that accepts path also throws std::bad_alloc in case of insufficient memory.
226*/
227
228
229template <class ...Args>
92f5a8d4 230BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const boost::dll::fs::path& lib, const char* name,
7c673cae
FG
231 load_mode::type mode = load_mode::default_mode)
232{
233 typedef typename boost::dll::experimental::detail::mangled_import_type<
234 boost::dll::experimental::detail::sequence<Args...>> type;
235
236 boost::dll::experimental::smart_library p(lib, mode);
237 //the load
238 return type::make(p, name);
239}
240
241
242
92f5a8d4 243//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae 244template <class ...Args>
92f5a8d4 245BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const boost::dll::fs::path& lib, const std::string& name,
7c673cae
FG
246 load_mode::type mode = load_mode::default_mode)
247{
248 return import_mangled<Args...>(lib, name.c_str(), mode);
249}
250
92f5a8d4 251//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
252template <class ...Args>
253BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, const char* name) {
254 typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
255
256 return type::make(lib, name);
257}
258
92f5a8d4 259//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
260template <class ...Args>
261BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const smart_library& lib, const std::string& name) {
262 return import_mangled<Args...>(lib, name.c_str());
263}
264
92f5a8d4 265//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
266template <class ...Args>
267BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const char* name) {
268 typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
269
270 return type::make(lib, name);
271}
272
92f5a8d4 273//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
274template <class ...Args>
275BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(smart_library) lib, const std::string& name) {
276 return import_mangled<Args...>(boost::move(lib), name.c_str());
277}
278
92f5a8d4 279//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
280template <class ...Args>
281BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, const char* name) {
282 typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
283
284 boost::shared_ptr<boost::dll::experimental::smart_library> p = boost::make_shared<boost::dll::experimental::smart_library>(lib);
285 return type::make(p, name);
286}
287
92f5a8d4 288//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
289template <class ...Args>
290BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(const shared_library& lib, const std::string& name) {
291 return import_mangled<Args...>(lib, name.c_str());
292}
293
92f5a8d4 294//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
295template <class ...Args>
296BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const char* name) {
297 typedef typename boost::dll::experimental::detail::mangled_import_type<detail::sequence<Args...>> type;
298
299 boost::dll::experimental::smart_library p(boost::move(lib));
300
301 return type::make(p, name);
302}
303
92f5a8d4 304//! \overload boost::dll::import(const boost::dll::fs::path& lib, const char* name, load_mode::type mode)
7c673cae
FG
305template <class ...Args>
306BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE import_mangled(BOOST_RV_REF(shared_library) lib, const std::string& name) {
307 return import_mangled<Args...>(boost::move(lib), name.c_str());
308}
309
310#undef BOOST_DLL_MANGLED_IMPORT_RESULT_TYPE
311
312}}}
313
314
315#endif /* BOOST_DLL_IMPORT_MANGLED_HPP_ */