1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // ----------------------------------------------------------------------------- 16 // File: memory.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This header file contains utility functions for managing the creation and 20 // conversion of smart pointers. This file is an extension to the C++ 21 // standard <memory> library header file. 22 23 #ifndef ABSL_MEMORY_MEMORY_H_ 24 #define ABSL_MEMORY_MEMORY_H_ 25 26 #include <cstddef> 27 #include <limits> 28 #include <memory> 29 #include <new> 30 #include <type_traits> 31 #include <utility> 32 33 #include "third_party/abseil-cpp/absl/base/macros.h" 34 #include "third_party/abseil-cpp/absl/meta/type_traits.h" 35 36 namespace absl { 37 ABSL_NAMESPACE_BEGIN 38 39 // ----------------------------------------------------------------------------- 40 // Function Template: WrapUnique() 41 // ----------------------------------------------------------------------------- 42 // 43 // Adopts ownership from a raw pointer and transfers it to the returned 44 // `std::unique_ptr`, whose type is deduced. Because of this deduction, *do not* 45 // specify the template type `T` when calling `WrapUnique`. 46 // 47 // Example: 48 // X* NewX(int, int); 49 // auto x = WrapUnique(NewX(1, 2)); // 'x' is std::unique_ptr<X>. 50 // 51 // Do not call WrapUnique with an explicit type, as in 52 // `WrapUnique<X>(NewX(1, 2))`. The purpose of WrapUnique is to automatically 53 // deduce the pointer type. If you wish to make the type explicit, just use 54 // `std::unique_ptr` directly. 55 // 56 // auto x = std::unique_ptr<X>(NewX(1, 2)); 57 // - or - 58 // std::unique_ptr<X> x(NewX(1, 2)); 59 // 60 // While `absl::WrapUnique` is useful for capturing the output of a raw 61 // pointer factory, prefer 'absl::make_unique<T>(args...)' over 62 // 'absl::WrapUnique(new T(args...))'. 63 // 64 // auto x = WrapUnique(new X(1, 2)); // works, but nonideal. 65 // auto x = make_unique<X>(1, 2); // safer, standard, avoids raw 'new'. 66 // 67 // Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid 68 // expression. In particular, `absl::WrapUnique()` cannot wrap pointers to 69 // arrays, functions or void, and it must not be used to capture pointers 70 // obtained from array-new expressions (even though that would compile!). 71 template <typename T> WrapUnique(T * ptr)72 std::unique_ptr<T> WrapUnique(T* ptr) { 73 static_assert(!std::is_array<T>::value, "array types are unsupported"); 74 static_assert(std::is_object<T>::value, "non-object types are unsupported"); 75 return std::unique_ptr<T>(ptr); 76 } 77 78 // ----------------------------------------------------------------------------- 79 // Function Template: make_unique<T>() 80 // ----------------------------------------------------------------------------- 81 // 82 // Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries 83 // during the construction process. `absl::make_unique<>` also avoids redundant 84 // type declarations, by avoiding the need to explicitly use the `new` operator. 85 // 86 // https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique 87 // 88 // For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic, 89 // see Herb Sutter's explanation on 90 // (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/]. 91 // (In general, reviewers should treat `new T(a,b)` with scrutiny.) 92 // 93 // Historical note: Abseil once provided a C++11 compatible implementation of 94 // the C++14's `std::make_unique`. Now that C++11 support has been sunsetted, 95 // `absl::make_unique` simply uses the STL-provided implementation. New code 96 // should use `std::make_unique`. 97 using std::make_unique; 98 99 // absl:google3-begin(internal only pending LSC) 100 101 namespace memory_internal { 102 103 // Traits to select proper overload and return type for 104 // `absl::make_unique_for_overwrite<>`. 105 template <typename T> 106 struct MakeUniqueResult { 107 using scalar = std::unique_ptr<T>; 108 }; 109 template <typename T> 110 struct MakeUniqueResult<T[]> { 111 using array = std::unique_ptr<T[]>; 112 }; 113 template <typename T, size_t N> 114 struct MakeUniqueResult<T[N]> { 115 using invalid = void; 116 }; 117 118 } // namespace memory_internal 119 120 // These are make_unique_for_overwrite variants modeled after 121 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1973r1.pdf 122 // Unlike absl::make_unique, values are default initialized rather than value 123 // initialized. 124 // 125 // `absl::make_unique_for_overwrite` overload for non-array types. 126 template <typename T> 127 typename memory_internal::MakeUniqueResult<T>::scalar 128 make_unique_for_overwrite() { 129 return std::unique_ptr<T>(new T); 130 } 131 132 // `absl::make_unique_for_overwrite` overload for an array T[] of unknown 133 // bounds. The array allocation needs to use the `new T[size]` form and cannot 134 // take element constructor arguments. The `std::unique_ptr` will manage 135 // destructing these array elements. 136 template <typename T> 137 typename memory_internal::MakeUniqueResult<T>::array 138 make_unique_for_overwrite(size_t n) { 139 return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]); 140 } 141 142 // `absl::make_unique_for_overwrite` overload for an array T[N] of known bounds. 143 // This construction will be rejected. 144 template <typename T, typename... Args> 145 typename memory_internal::MakeUniqueResult<T>::invalid 146 make_unique_for_overwrite(Args&&... /* args */) = delete; 147 148 // absl:google3-end 149 150 // ----------------------------------------------------------------------------- 151 // Function Template: RawPtr() 152 // ----------------------------------------------------------------------------- 153 // 154 // Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is 155 // useful within templates that need to handle a complement of raw pointers, 156 // `std::nullptr_t`, and smart pointers. 157 template <typename T> 158 auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) { 159 // ptr is a forwarding reference to support Ts with non-const operators. 160 return (ptr != nullptr) ? std::addressof(*ptr) : nullptr; 161 } 162 inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; } 163 164 // ----------------------------------------------------------------------------- 165 // Function Template: ShareUniquePtr() 166 // ----------------------------------------------------------------------------- 167 // 168 // Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced 169 // type. Ownership (if any) of the held value is transferred to the returned 170 // shared pointer. 171 // 172 // Example: 173 // 174 // auto up = absl::make_unique<int>(10); 175 // auto sp = absl::ShareUniquePtr(std::move(up)); // shared_ptr<int> 176 // CHECK_EQ(*sp, 10); 177 // CHECK(up == nullptr); 178 // 179 // Note that this conversion is correct even when T is an array type, and more 180 // generally it works for *any* deleter of the `unique_ptr` (single-object 181 // deleter, array deleter, or any custom deleter), since the deleter is adopted 182 // by the shared pointer as well. The deleter is copied (unless it is a 183 // reference). 184 // 185 // Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a 186 // null shared pointer does not attempt to call the deleter. 187 template <typename T, typename D> 188 std::shared_ptr<T> ShareUniquePtr(std::unique_ptr<T, D>&& ptr) { 189 return ptr ? std::shared_ptr<T>(std::move(ptr)) : std::shared_ptr<T>(); 190 } 191 192 // ----------------------------------------------------------------------------- 193 // Function Template: WeakenPtr() 194 // ----------------------------------------------------------------------------- 195 // 196 // Creates a weak pointer associated with a given shared pointer. The returned 197 // value is a `std::weak_ptr` of deduced type. 198 // 199 // Example: 200 // 201 // auto sp = std::make_shared<int>(10); 202 // auto wp = absl::WeakenPtr(sp); 203 // CHECK_EQ(sp.get(), wp.lock().get()); 204 // sp.reset(); 205 // CHECK(wp.lock() == nullptr); 206 // 207 template <typename T> 208 std::weak_ptr<T> WeakenPtr(const std::shared_ptr<T>& ptr) { 209 return std::weak_ptr<T>(ptr); 210 } 211 212 // ----------------------------------------------------------------------------- 213 // Class Template: pointer_traits 214 // ----------------------------------------------------------------------------- 215 // 216 // Historical note: Abseil once provided an implementation of 217 // `std::pointer_traits` for platforms that had not yet provided it. Those 218 // platforms are no longer supported. New code should simply use 219 // `std::pointer_traits`. 220 using std::pointer_traits; 221 222 // ----------------------------------------------------------------------------- 223 // Class Template: allocator_traits 224 // ----------------------------------------------------------------------------- 225 // 226 // Historical note: Abseil once provided an implementation of 227 // `std::allocator_traits` for platforms that had not yet provided it. Those 228 // platforms are no longer supported. New code should simply use 229 // `std::allocator_traits`. 230 using std::allocator_traits; 231 232 namespace memory_internal { 233 234 // ExtractOr<E, O, D>::type evaluates to E<O> if possible. Otherwise, D. 235 template <template <typename> class Extract, typename Obj, typename Default, 236 typename> 237 struct ExtractOr { 238 using type = Default; 239 }; 240 241 template <template <typename> class Extract, typename Obj, typename Default> 242 struct ExtractOr<Extract, Obj, Default, void_t<Extract<Obj>>> { 243 using type = Extract<Obj>; 244 }; 245 246 template <template <typename> class Extract, typename Obj, typename Default> 247 using ExtractOrT = typename ExtractOr<Extract, Obj, Default, void>::type; 248 249 // This template alias transforms Alloc::is_nothrow into a metafunction with 250 // Alloc as a parameter so it can be used with ExtractOrT<>. 251 template <typename Alloc> 252 using GetIsNothrow = typename Alloc::is_nothrow; 253 254 } // namespace memory_internal 255 256 struct internal_b197379895_workaround; // absl:google3-only(TODO(b/197379895)) 257 258 // ABSL_ALLOCATOR_NOTHROW is a build time configuration macro for user to 259 // specify whether the default allocation function can throw or never throws. 260 // If the allocation function never throws, user should define it to a non-zero 261 // value (e.g. via `-DABSL_ALLOCATOR_NOTHROW`). 262 // If the allocation function can throw, user should leave it undefined or 263 // define it to zero. 264 // 265 // allocator_is_nothrow<Alloc> is a traits class that derives from 266 // Alloc::is_nothrow if present, otherwise std::false_type. It's specialized 267 // for Alloc = std::allocator<T> for any type T according to the state of 268 // ABSL_ALLOCATOR_NOTHROW. 269 // 270 // default_allocator_is_nothrow is a class that derives from std::true_type 271 // when the default allocator (global operator new) never throws, and 272 // std::false_type when it can throw. It is a convenience shorthand for writing 273 // allocator_is_nothrow<std::allocator<T>> (T can be any type). 274 // NOTE: allocator_is_nothrow<std::allocator<T>> is guaranteed to derive from 275 // the same type for all T, because users should specialize neither 276 // allocator_is_nothrow nor std::allocator. 277 template <typename Alloc> 278 struct allocator_is_nothrow 279 : memory_internal::ExtractOrT<memory_internal::GetIsNothrow, Alloc, 280 std::false_type> {}; 281 282 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW 283 template <typename T> 284 struct allocator_is_nothrow<std::allocator<T>> : std::true_type {}; 285 struct default_allocator_is_nothrow : std::true_type {}; 286 #else 287 struct default_allocator_is_nothrow : std::false_type {}; 288 #endif 289 290 namespace memory_internal { 291 template <typename Allocator, typename Iterator, typename... Args> 292 void ConstructRange(Allocator& alloc, Iterator first, Iterator last, 293 const Args&... args) { 294 for (Iterator cur = first; cur != last; ++cur) { 295 ABSL_INTERNAL_TRY { 296 std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), 297 args...); 298 } 299 ABSL_INTERNAL_CATCH_ANY { 300 while (cur != first) { 301 --cur; 302 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur)); 303 } 304 ABSL_INTERNAL_RETHROW; 305 } 306 } 307 } 308 309 template <typename Allocator, typename Iterator, typename InputIterator> 310 void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, 311 InputIterator last) { 312 for (Iterator cur = destination; first != last; 313 static_cast<void>(++cur), static_cast<void>(++first)) { 314 ABSL_INTERNAL_TRY { 315 std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), 316 *first); 317 } 318 ABSL_INTERNAL_CATCH_ANY { 319 while (cur != destination) { 320 --cur; 321 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur)); 322 } 323 ABSL_INTERNAL_RETHROW; 324 } 325 } 326 } 327 } // namespace memory_internal 328 ABSL_NAMESPACE_END 329 } // namespace absl 330 331 #endif // THIRD_PARTY_ABSL_MEMORY_MEMORY_H_