]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/dll/include/boost/dll/detail/ctor_dtor.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / dll / include / boost / dll / detail / ctor_dtor.hpp
CommitLineData
7c673cae
FG
1// Copyright 2016 Klemens Morgenstern, Antony Polukhin
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt
5// or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7// For more information, see http://www.boost.org
8
9#ifndef BOOST_DLL_DETAIL_CTOR_DTOR_HPP_
10#define BOOST_DLL_DETAIL_CTOR_DTOR_HPP_
11
12#include <boost/config.hpp>
13#ifdef BOOST_HAS_PRAGMA_ONCE
14# pragma once
15#endif
16
17#include <boost/dll/detail/aggressive_ptr_cast.hpp>
18#include <boost/dll/detail/get_mem_fn_type.hpp>
19
20#if defined(BOOST_MSVC) || defined(BOOST_MSVC_VER)
21# include <boost/dll/detail/demangling/msvc.hpp>
22#else
23# include <boost/dll/detail/demangling/itanium.hpp>
24#endif
25
26
27namespace boost { namespace dll { namespace detail {
28
29/*!
30 * This class stores a constructor.
31 *
32 * In some compilers there are several constructors in code, which may include an allocating one.
33 * This can be used if the imported class shall be put on the heap, which is why the class provied both types.
34 */
35template<typename Signature>
36struct constructor;
37
38template<typename Class, typename ...Args>
39struct constructor<Class(Args...)> {
40 typedef typename detail::get_mem_fn_type<Class, void(Args...)>::mem_fn standard_t;
41 typedef Class*(*allocating_t)(Args...);
42
43
44 //! The standard, i.e. not allocating constructor. @warning May differ with the compiler. Use @ref constructor::call_standard instead.
45 standard_t standard;
46 //! The allocating constructor. @warning May differ with the compiler. Use @ref constructor::call_allocating instead.
47 allocating_t allocating;
48
49 //! Call the standard contructor
50 void call_standard (Class * const ptr, Args...args){ (ptr->*standard)(static_cast<Args>(args)...); }
51
52 //! Call the deleting destructor
53 Class * call_allocating(Args...args){ return allocating(static_cast<Args>(args)...); }
54
55
56 //! True if a allocating constructor could be loaded.
57 bool has_allocating() const { return allocating != nullptr; }
58
59 //! True if a standard constructor could be loaded.
60 bool has_standard() const { return standard != nullptr; }
61
62 //! False if neither the allocating nor the standard constructor is available.
63 bool is_empty() const { return (allocating == nullptr) && (standard == nullptr) ; }
64
65 constructor() = delete;
66 constructor(const constructor &) = default;
67
68 explicit constructor(standard_t standard, allocating_t allocating = nullptr)
69 : standard(standard)
70 , allocating(allocating)
71 {}
72};
73
74
75
76template <typename Class>
77struct destructor {
78#if !defined(_WIN32)
79 typedef void(*type)(Class* const);
80#elif !defined(_WIN64)
81 typedef void(__thiscall * type)(Class* const);
82#else
83 typedef void(__cdecl * type)(Class* const);
84#endif
85
86 typedef type standard_t;
87 typedef type deleting_t;
88
89 //! The standard, i.e. not deleting destructor. @warning May differ with the compiler. Use @ref destructor::call_standard instead.
90 standard_t standard;
91 //! The deleting destructor. @warning May differ with the compiler. Use @ref destructor::call_deallocating instead.
92 deleting_t deleting;
93
94 //! Call the standard contructor
95 void call_standard(Class * const ptr){ standard(ptr); }
96
97 //! Call the deleting destructor
98 void call_deleting(Class * const ptr){ deleting(ptr); }
99
100 //! True if a deleting destructor could be loaded.
101 bool has_deleting() const { return deleting != nullptr; }
102
103 //! True if a standard destructor could be loaded.
104 bool has_standard() const { return standard != nullptr; }
105
106 //! False if neither the deleting nor the standard destructor is available.
107 bool is_empty() const { return (deleting == nullptr) && (standard == nullptr) ; }
108 destructor() = delete;
109
110 //! Copy destructor.
111 destructor(const destructor &) = default;
112
113 //! Construct it from both the standard destructor and the allocating destructor
114 explicit destructor(const standard_t &standard, const deleting_t &deleting = nullptr)
115 : standard(standard)
116 , deleting(deleting)
117 {}
118};
119
120#if defined(BOOST_MSVC) || defined(BOOST_MSVC_VER)
121template<typename Signature, typename Lib>
122constructor<Signature> load_ctor(Lib & lib, const mangled_storage_impl::ctor_sym & ct) {
123 typedef typename constructor<Signature>::standard_t standard_t;
124 standard_t ctor = lib.template get<standard_t>(ct);
125 return constructor<Signature>(ctor);
126}
127
128template<typename Class, typename Lib>
129destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt) {
130 typedef typename destructor<Class>::standard_t standard_t;
131 //@apolukhin That does NOT work this way with MSVC-14 x32 via memcpy. The x64 is different.
132 //standard_t dtor = &lib.template get< typename boost::remove_pointer<standard_t>::type >(dt);
133 void * buf = &lib.template get<int>(dt);
134 standard_t dtor;
135 std::memcpy(&dtor, &buf, sizeof(dtor));
136 return destructor<Class>(dtor);
137}
138
139#else
140
141template<typename Signature, typename Lib>
142constructor<Signature> load_ctor(Lib & lib, const mangled_storage_impl::ctor_sym & ct) {
143 typedef typename constructor<Signature>::standard_t stand;
144 typedef typename constructor<Signature>::allocating_t alloc;
145
146 stand s = nullptr;
147 alloc a = nullptr;
148
149 //see here for the abi http://mentorembedded.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor
150
151 if (!ct.C1.empty())
152 {
153 //the only way this works on mingw/win.
154 //For some reason there is always an 0xA in the following poniter, which screws with the this pointer.
155 void *buf = &lib.template get<int>(ct.C1);
156 std::memcpy(&s, &buf, sizeof(void*));
157 }
158 if (!ct.C3.empty())
159 {
160 void *buf = &lib.template get<int>(ct.C3);
161 std::memcpy(&a, &buf, sizeof(void*));
162 }
163
164 return constructor<Signature>(s,a);
165}
166
167template<typename Class, typename Lib>
168destructor<Class> load_dtor(Lib & lib, const mangled_storage_impl::dtor_sym & dt) {
169 typedef typename destructor<Class>::standard_t stand;
170 typedef typename destructor<Class>::deleting_t delet;
171
172 stand s = nullptr;
173 delet d = nullptr;
174
175 //see here for the abi http://mentorembedded.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor
176 if (!dt.D1.empty()) {
177 s = &lib.template get< typename boost::remove_pointer<stand>::type >(dt.D1);
178 }
179
180 if (!dt.D0.empty()) {
181 d = &lib.template get< typename boost::remove_pointer<delet>::type >(dt.D0);
182 }
183
184 return destructor<Class>(s,d);
185
186}
187
188#endif
189
190}}} // namespace boost::dll::detail
191
192#endif /* BOOST_DLL_DETAIL_CTOR_DTOR_HPP_ */