30 #ifndef BPSTD_MEMORY_HPP
31 #define BPSTD_MEMORY_HPP
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
37 #include "detail/config.hpp"
43 #include <type_traits>
45 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
51 struct make_unique_result
56 struct make_unique_result<T[]>
58 using unbounded_array = T[];
60 template <
typename T, std::
size_t N>
61 struct make_unique_result<T[N]>
63 using bounded_array = T[N];
76 template <
typename T,
typename...Args>
77 std::unique_ptr<typename detail::make_unique_result<T>::object>
89 std::unique_ptr<typename detail::make_unique_result<T>::unbounded_array>
94 std::unique_ptr<typename detail::make_unique_result<T>::bounded_array>
107 template <
typename T>
108 std::unique_ptr<typename detail::make_unique_result<T>::object>
121 template <
typename T>
122 std::unique_ptr<typename detail::make_unique_result<T>::unbounded_array>
126 template <
typename T>
127 std::unique_ptr<typename detail::make_unique_result<T>::bounded_array>
134 template <
typename T,
typename =
void>
135 struct has_to_address : false_type{};
137 template <
typename T>
138 struct has_to_address<T,void_t<decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))>>
143 template <
bool,
typename T>
144 struct operator_deref
146 using type = decltype(std::declval<const T&>().operator->());
149 template <
typename T>
150 struct operator_deref<true, T>{};
154 template <
typename T,
typename =
void>
155 struct to_address_result
156 : operator_deref<std::is_pointer<remove_cvref_t<T>>::value, T>{};
158 template <
typename T>
159 struct to_address_result<T,void_t<decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))>>
161 using type = decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()));
164 template <
typename T>
165 using to_address_result_t =
typename to_address_result<T>::type;
175 template <
typename T>
177 template <
typename T>
178 constexpr detail::to_address_result_t<T>
to_address(
const T& p) noexcept;
183 template <
typename T,
typename...Args>
184 inline BPSTD_INLINE_VISIBILITY
185 std::unique_ptr<typename bpstd::detail::make_unique_result<T>::object>
186 bpstd::make_unique(Args&&...args)
188 return std::unique_ptr<T>{
new T(bpstd::forward<Args>(args)...)};
191 template <
typename T>
192 inline BPSTD_INLINE_VISIBILITY
193 std::unique_ptr<typename bpstd::detail::make_unique_result<T>::unbounded_array>
194 bpstd::make_unique(std::size_t size)
196 return std::unique_ptr<T>{
new remove_extent_t<T>[
size]()};
199 template <
typename T>
200 inline BPSTD_INLINE_VISIBILITY
201 std::unique_ptr<typename bpstd::detail::make_unique_result<T>::object>
202 bpstd::make_unique_for_overwrite()
204 return std::unique_ptr<T>{
new T};
207 template <
typename T>
208 inline BPSTD_INLINE_VISIBILITY
209 std::unique_ptr<typename bpstd::detail::make_unique_result<T>::unbounded_array>
210 bpstd::make_unique_for_overwrite(std::size_t size)
212 return std::unique_ptr<T>{
new remove_extent_t<T>[
size]};
218 template <
typename T>
219 inline BPSTD_INLINE_VISIBILITY constexpr
220 auto to_address_impl(
const T& p, std::true_type)
221 -> decltype(std::pointer_traits<T>::to_address(std::declval<const T&>()))
223 return to_address(std::pointer_traits<T>::to_address(p));
226 template <
typename T>
227 inline BPSTD_INLINE_VISIBILITY constexpr
228 auto to_address_impl(
const T& p, std::false_type)
229 -> decltype(std::declval<const T&>().operator->())
237 template <
typename T>
238 inline BPSTD_INLINE_VISIBILITY constexpr
243 !std::is_function<T>::value,
244 "T* must not be a function pointer"
250 template <
typename T>
251 inline BPSTD_INLINE_VISIBILITY constexpr
252 bpstd::detail::to_address_result_t<T>
256 return detail::to_address_impl(p, detail::has_to_address<T>{});
259 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE