You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

memory.h 29 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  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. #ifndef ABSL_MEMORY_MEMORY_H_
  23. #define ABSL_MEMORY_MEMORY_H_
  24. #include <cstddef>
  25. #include <limits>
  26. #include <memory>
  27. #include <new>
  28. #include <type_traits>
  29. #include <utility>
  30. #include "absl/base/macros.h"
  31. #include "absl/meta/type_traits.h"
  32. namespace absl
  33. {
  34. ABSL_NAMESPACE_BEGIN
  35. // -----------------------------------------------------------------------------
  36. // Function Template: WrapUnique()
  37. // -----------------------------------------------------------------------------
  38. //
  39. // Adopts ownership from a raw pointer and transfers it to the returned
  40. // `std::unique_ptr`, whose type is deduced. Because of this deduction, *do not*
  41. // specify the template type `T` when calling `WrapUnique`.
  42. //
  43. // Example:
  44. // X* NewX(int, int);
  45. // auto x = WrapUnique(NewX(1, 2)); // 'x' is std::unique_ptr<X>.
  46. //
  47. // Do not call WrapUnique with an explicit type, as in
  48. // `WrapUnique<X>(NewX(1, 2))`. The purpose of WrapUnique is to automatically
  49. // deduce the pointer type. If you wish to make the type explicit, just use
  50. // `std::unique_ptr` directly.
  51. //
  52. // auto x = std::unique_ptr<X>(NewX(1, 2));
  53. // - or -
  54. // std::unique_ptr<X> x(NewX(1, 2));
  55. //
  56. // While `absl::WrapUnique` is useful for capturing the output of a raw
  57. // pointer factory, prefer 'absl::make_unique<T>(args...)' over
  58. // 'absl::WrapUnique(new T(args...))'.
  59. //
  60. // auto x = WrapUnique(new X(1, 2)); // works, but nonideal.
  61. // auto x = make_unique<X>(1, 2); // safer, standard, avoids raw 'new'.
  62. //
  63. // Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid
  64. // expression. In particular, `absl::WrapUnique()` cannot wrap pointers to
  65. // arrays, functions or void, and it must not be used to capture pointers
  66. // obtained from array-new expressions (even though that would compile!).
  67. template<typename T>
  68. std::unique_ptr<T> WrapUnique(T* ptr)
  69. {
  70. static_assert(!std::is_array<T>::value, "array types are unsupported");
  71. static_assert(std::is_object<T>::value, "non-object types are unsupported");
  72. return std::unique_ptr<T>(ptr);
  73. }
  74. namespace memory_internal
  75. {
  76. // Traits to select proper overload and return type for `absl::make_unique<>`.
  77. template<typename T>
  78. struct MakeUniqueResult
  79. {
  80. using scalar = std::unique_ptr<T>;
  81. };
  82. template<typename T>
  83. struct MakeUniqueResult<T[]>
  84. {
  85. using array = std::unique_ptr<T[]>;
  86. };
  87. template<typename T, size_t N>
  88. struct MakeUniqueResult<T[N]>
  89. {
  90. using invalid = void;
  91. };
  92. } // namespace memory_internal
  93. // gcc 4.8 has __cplusplus at 201301 but the libstdc++ shipped with it doesn't
  94. // define make_unique. Other supported compilers either just define __cplusplus
  95. // as 201103 but have make_unique (msvc), or have make_unique whenever
  96. // __cplusplus > 201103 (clang).
  97. #if (__cplusplus > 201103L || defined(_MSC_VER)) && \
  98. !(defined(__GLIBCXX__) && !defined(__cpp_lib_make_unique))
  99. using std::make_unique;
  100. #else
  101. // -----------------------------------------------------------------------------
  102. // Function Template: make_unique<T>()
  103. // -----------------------------------------------------------------------------
  104. //
  105. // Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries
  106. // during the construction process. `absl::make_unique<>` also avoids redundant
  107. // type declarations, by avoiding the need to explicitly use the `new` operator.
  108. //
  109. // This implementation of `absl::make_unique<>` is designed for C++11 code and
  110. // will be replaced in C++14 by the equivalent `std::make_unique<>` abstraction.
  111. // `absl::make_unique<>` is designed to be 100% compatible with
  112. // `std::make_unique<>` so that the eventual migration will involve a simple
  113. // rename operation.
  114. //
  115. // For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic,
  116. // see Herb Sutter's explanation on
  117. // (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/].
  118. // (In general, reviewers should treat `new T(a,b)` with scrutiny.)
  119. //
  120. // Example usage:
  121. //
  122. // auto p = make_unique<X>(args...); // 'p' is a std::unique_ptr<X>
  123. // auto pa = make_unique<X[]>(5); // 'pa' is a std::unique_ptr<X[]>
  124. //
  125. // Three overloads of `absl::make_unique` are required:
  126. //
  127. // - For non-array T:
  128. //
  129. // Allocates a T with `new T(std::forward<Args> args...)`,
  130. // forwarding all `args` to T's constructor.
  131. // Returns a `std::unique_ptr<T>` owning that object.
  132. //
  133. // - For an array of unknown bounds T[]:
  134. //
  135. // `absl::make_unique<>` will allocate an array T of type U[] with
  136. // `new U[n]()` and return a `std::unique_ptr<U[]>` owning that array.
  137. //
  138. // Note that 'U[n]()' is different from 'U[n]', and elements will be
  139. // value-initialized. Note as well that `std::unique_ptr` will perform its
  140. // own destruction of the array elements upon leaving scope, even though
  141. // the array [] does not have a default destructor.
  142. //
  143. // NOTE: an array of unknown bounds T[] may still be (and often will be)
  144. // initialized to have a size, and will still use this overload. E.g:
  145. //
  146. // auto my_array = absl::make_unique<int[]>(10);
  147. //
  148. // - For an array of known bounds T[N]:
  149. //
  150. // `absl::make_unique<>` is deleted (like with `std::make_unique<>`) as
  151. // this overload is not useful.
  152. //
  153. // NOTE: an array of known bounds T[N] is not considered a useful
  154. // construction, and may cause undefined behavior in templates. E.g:
  155. //
  156. // auto my_array = absl::make_unique<int[10]>();
  157. //
  158. // In those cases, of course, you can still use the overload above and
  159. // simply initialize it to its desired size:
  160. //
  161. // auto my_array = absl::make_unique<int[]>(10);
  162. // `absl::make_unique` overload for non-array types.
  163. template<typename T, typename... Args>
  164. typename memory_internal::MakeUniqueResult<T>::scalar make_unique(
  165. Args&&... args
  166. )
  167. {
  168. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  169. }
  170. // `absl::make_unique` overload for an array T[] of unknown bounds.
  171. // The array allocation needs to use the `new T[size]` form and cannot take
  172. // element constructor arguments. The `std::unique_ptr` will manage destructing
  173. // these array elements.
  174. template<typename T>
  175. typename memory_internal::MakeUniqueResult<T>::array make_unique(size_t n)
  176. {
  177. return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]());
  178. }
  179. // `absl::make_unique` overload for an array T[N] of known bounds.
  180. // This construction will be rejected.
  181. template<typename T, typename... Args>
  182. typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
  183. Args&&... /* args */
  184. ) = delete;
  185. #endif
  186. // -----------------------------------------------------------------------------
  187. // Function Template: RawPtr()
  188. // -----------------------------------------------------------------------------
  189. //
  190. // Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is
  191. // useful within templates that need to handle a complement of raw pointers,
  192. // `std::nullptr_t`, and smart pointers.
  193. template<typename T>
  194. auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr))
  195. {
  196. // ptr is a forwarding reference to support Ts with non-const operators.
  197. return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
  198. }
  199. inline std::nullptr_t RawPtr(std::nullptr_t)
  200. {
  201. return nullptr;
  202. }
  203. // -----------------------------------------------------------------------------
  204. // Function Template: ShareUniquePtr()
  205. // -----------------------------------------------------------------------------
  206. //
  207. // Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced
  208. // type. Ownership (if any) of the held value is transferred to the returned
  209. // shared pointer.
  210. //
  211. // Example:
  212. //
  213. // auto up = absl::make_unique<int>(10);
  214. // auto sp = absl::ShareUniquePtr(std::move(up)); // shared_ptr<int>
  215. // CHECK_EQ(*sp, 10);
  216. // CHECK(up == nullptr);
  217. //
  218. // Note that this conversion is correct even when T is an array type, and more
  219. // generally it works for *any* deleter of the `unique_ptr` (single-object
  220. // deleter, array deleter, or any custom deleter), since the deleter is adopted
  221. // by the shared pointer as well. The deleter is copied (unless it is a
  222. // reference).
  223. //
  224. // Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a
  225. // null shared pointer does not attempt to call the deleter.
  226. template<typename T, typename D>
  227. std::shared_ptr<T> ShareUniquePtr(std::unique_ptr<T, D>&& ptr)
  228. {
  229. return ptr ? std::shared_ptr<T>(std::move(ptr)) : std::shared_ptr<T>();
  230. }
  231. // -----------------------------------------------------------------------------
  232. // Function Template: WeakenPtr()
  233. // -----------------------------------------------------------------------------
  234. //
  235. // Creates a weak pointer associated with a given shared pointer. The returned
  236. // value is a `std::weak_ptr` of deduced type.
  237. //
  238. // Example:
  239. //
  240. // auto sp = std::make_shared<int>(10);
  241. // auto wp = absl::WeakenPtr(sp);
  242. // CHECK_EQ(sp.get(), wp.lock().get());
  243. // sp.reset();
  244. // CHECK(wp.lock() == nullptr);
  245. //
  246. template<typename T>
  247. std::weak_ptr<T> WeakenPtr(const std::shared_ptr<T>& ptr)
  248. {
  249. return std::weak_ptr<T>(ptr);
  250. }
  251. namespace memory_internal
  252. {
  253. // ExtractOr<E, O, D>::type evaluates to E<O> if possible. Otherwise, D.
  254. template<template<typename> class Extract, typename Obj, typename Default, typename>
  255. struct ExtractOr
  256. {
  257. using type = Default;
  258. };
  259. template<template<typename> class Extract, typename Obj, typename Default>
  260. struct ExtractOr<Extract, Obj, Default, void_t<Extract<Obj>>>
  261. {
  262. using type = Extract<Obj>;
  263. };
  264. template<template<typename> class Extract, typename Obj, typename Default>
  265. using ExtractOrT = typename ExtractOr<Extract, Obj, Default, void>::type;
  266. // Extractors for the features of allocators.
  267. template<typename T>
  268. using GetPointer = typename T::pointer;
  269. template<typename T>
  270. using GetConstPointer = typename T::const_pointer;
  271. template<typename T>
  272. using GetVoidPointer = typename T::void_pointer;
  273. template<typename T>
  274. using GetConstVoidPointer = typename T::const_void_pointer;
  275. template<typename T>
  276. using GetDifferenceType = typename T::difference_type;
  277. template<typename T>
  278. using GetSizeType = typename T::size_type;
  279. template<typename T>
  280. using GetPropagateOnContainerCopyAssignment =
  281. typename T::propagate_on_container_copy_assignment;
  282. template<typename T>
  283. using GetPropagateOnContainerMoveAssignment =
  284. typename T::propagate_on_container_move_assignment;
  285. template<typename T>
  286. using GetPropagateOnContainerSwap = typename T::propagate_on_container_swap;
  287. template<typename T>
  288. using GetIsAlwaysEqual = typename T::is_always_equal;
  289. template<typename T>
  290. struct GetFirstArg;
  291. template<template<typename...> class Class, typename T, typename... Args>
  292. struct GetFirstArg<Class<T, Args...>>
  293. {
  294. using type = T;
  295. };
  296. template<typename Ptr, typename = void>
  297. struct ElementType
  298. {
  299. using type = typename GetFirstArg<Ptr>::type;
  300. };
  301. template<typename T>
  302. struct ElementType<T, void_t<typename T::element_type>>
  303. {
  304. using type = typename T::element_type;
  305. };
  306. template<typename T, typename U>
  307. struct RebindFirstArg;
  308. template<template<typename...> class Class, typename T, typename... Args, typename U>
  309. struct RebindFirstArg<Class<T, Args...>, U>
  310. {
  311. using type = Class<U, Args...>;
  312. };
  313. template<typename T, typename U, typename = void>
  314. struct RebindPtr
  315. {
  316. using type = typename RebindFirstArg<T, U>::type;
  317. };
  318. template<typename T, typename U>
  319. struct RebindPtr<T, U, void_t<typename T::template rebind<U>>>
  320. {
  321. using type = typename T::template rebind<U>;
  322. };
  323. template<typename T, typename U>
  324. constexpr bool HasRebindAlloc(...)
  325. {
  326. return false;
  327. }
  328. template<typename T, typename U>
  329. constexpr bool HasRebindAlloc(typename T::template rebind<U>::other*)
  330. {
  331. return true;
  332. }
  333. template<typename T, typename U, bool = HasRebindAlloc<T, U>(nullptr)>
  334. struct RebindAlloc
  335. {
  336. using type = typename RebindFirstArg<T, U>::type;
  337. };
  338. template<typename T, typename U>
  339. struct RebindAlloc<T, U, true>
  340. {
  341. using type = typename T::template rebind<U>::other;
  342. };
  343. } // namespace memory_internal
  344. // -----------------------------------------------------------------------------
  345. // Class Template: pointer_traits
  346. // -----------------------------------------------------------------------------
  347. //
  348. // An implementation of C++11's std::pointer_traits.
  349. //
  350. // Provided for portability on toolchains that have a working C++11 compiler,
  351. // but the standard library is lacking in C++11 support. For example, some
  352. // version of the Android NDK.
  353. //
  354. template<typename Ptr>
  355. struct pointer_traits
  356. {
  357. using pointer = Ptr;
  358. // element_type:
  359. // Ptr::element_type if present. Otherwise T if Ptr is a template
  360. // instantiation Template<T, Args...>
  361. using element_type = typename memory_internal::ElementType<Ptr>::type;
  362. // difference_type:
  363. // Ptr::difference_type if present, otherwise std::ptrdiff_t
  364. using difference_type =
  365. memory_internal::ExtractOrT<memory_internal::GetDifferenceType, Ptr, std::ptrdiff_t>;
  366. // rebind:
  367. // Ptr::rebind<U> if exists, otherwise Template<U, Args...> if Ptr is a
  368. // template instantiation Template<T, Args...>
  369. template<typename U>
  370. using rebind = typename memory_internal::RebindPtr<Ptr, U>::type;
  371. // pointer_to:
  372. // Calls Ptr::pointer_to(r)
  373. static pointer pointer_to(element_type& r)
  374. { // NOLINT(runtime/references)
  375. return Ptr::pointer_to(r);
  376. }
  377. };
  378. // Specialization for T*.
  379. template<typename T>
  380. struct pointer_traits<T*>
  381. {
  382. using pointer = T*;
  383. using element_type = T;
  384. using difference_type = std::ptrdiff_t;
  385. template<typename U>
  386. using rebind = U*;
  387. // pointer_to:
  388. // Calls std::addressof(r)
  389. static pointer pointer_to(
  390. element_type& r
  391. ) noexcept
  392. { // NOLINT(runtime/references)
  393. return std::addressof(r);
  394. }
  395. };
  396. // -----------------------------------------------------------------------------
  397. // Class Template: allocator_traits
  398. // -----------------------------------------------------------------------------
  399. //
  400. // A C++11 compatible implementation of C++17's std::allocator_traits.
  401. //
  402. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  403. using std::allocator_traits;
  404. #else // __cplusplus >= 201703L
  405. template<typename Alloc>
  406. struct allocator_traits
  407. {
  408. using allocator_type = Alloc;
  409. // value_type:
  410. // Alloc::value_type
  411. using value_type = typename Alloc::value_type;
  412. // pointer:
  413. // Alloc::pointer if present, otherwise value_type*
  414. using pointer = memory_internal::ExtractOrT<memory_internal::GetPointer, Alloc, value_type*>;
  415. // const_pointer:
  416. // Alloc::const_pointer if present, otherwise
  417. // absl::pointer_traits<pointer>::rebind<const value_type>
  418. using const_pointer =
  419. memory_internal::ExtractOrT<memory_internal::GetConstPointer, Alloc, typename absl::pointer_traits<pointer>::template rebind<const value_type>>;
  420. // void_pointer:
  421. // Alloc::void_pointer if present, otherwise
  422. // absl::pointer_traits<pointer>::rebind<void>
  423. using void_pointer = memory_internal::ExtractOrT<
  424. memory_internal::GetVoidPointer,
  425. Alloc,
  426. typename absl::pointer_traits<pointer>::template rebind<void>>;
  427. // const_void_pointer:
  428. // Alloc::const_void_pointer if present, otherwise
  429. // absl::pointer_traits<pointer>::rebind<const void>
  430. using const_void_pointer = memory_internal::ExtractOrT<
  431. memory_internal::GetConstVoidPointer,
  432. Alloc,
  433. typename absl::pointer_traits<pointer>::template rebind<const void>>;
  434. // difference_type:
  435. // Alloc::difference_type if present, otherwise
  436. // absl::pointer_traits<pointer>::difference_type
  437. using difference_type = memory_internal::ExtractOrT<
  438. memory_internal::GetDifferenceType,
  439. Alloc,
  440. typename absl::pointer_traits<pointer>::difference_type>;
  441. // size_type:
  442. // Alloc::size_type if present, otherwise
  443. // std::make_unsigned<difference_type>::type
  444. using size_type = memory_internal::ExtractOrT<
  445. memory_internal::GetSizeType,
  446. Alloc,
  447. typename std::make_unsigned<difference_type>::type>;
  448. // propagate_on_container_copy_assignment:
  449. // Alloc::propagate_on_container_copy_assignment if present, otherwise
  450. // std::false_type
  451. using propagate_on_container_copy_assignment = memory_internal::ExtractOrT<
  452. memory_internal::GetPropagateOnContainerCopyAssignment,
  453. Alloc,
  454. std::false_type>;
  455. // propagate_on_container_move_assignment:
  456. // Alloc::propagate_on_container_move_assignment if present, otherwise
  457. // std::false_type
  458. using propagate_on_container_move_assignment = memory_internal::ExtractOrT<
  459. memory_internal::GetPropagateOnContainerMoveAssignment,
  460. Alloc,
  461. std::false_type>;
  462. // propagate_on_container_swap:
  463. // Alloc::propagate_on_container_swap if present, otherwise std::false_type
  464. using propagate_on_container_swap =
  465. memory_internal::ExtractOrT<memory_internal::GetPropagateOnContainerSwap, Alloc, std::false_type>;
  466. // is_always_equal:
  467. // Alloc::is_always_equal if present, otherwise std::is_empty<Alloc>::type
  468. using is_always_equal =
  469. memory_internal::ExtractOrT<memory_internal::GetIsAlwaysEqual, Alloc, typename std::is_empty<Alloc>::type>;
  470. // rebind_alloc:
  471. // Alloc::rebind<T>::other if present, otherwise Alloc<T, Args> if this Alloc
  472. // is Alloc<U, Args>
  473. template<typename T>
  474. using rebind_alloc = typename memory_internal::RebindAlloc<Alloc, T>::type;
  475. // rebind_traits:
  476. // absl::allocator_traits<rebind_alloc<T>>
  477. template<typename T>
  478. using rebind_traits = absl::allocator_traits<rebind_alloc<T>>;
  479. // allocate(Alloc& a, size_type n):
  480. // Calls a.allocate(n)
  481. static pointer allocate(Alloc& a, // NOLINT(runtime/references)
  482. size_type n)
  483. {
  484. return a.allocate(n);
  485. }
  486. // allocate(Alloc& a, size_type n, const_void_pointer hint):
  487. // Calls a.allocate(n, hint) if possible.
  488. // If not possible, calls a.allocate(n)
  489. static pointer allocate(Alloc& a, size_type n, // NOLINT(runtime/references)
  490. const_void_pointer hint)
  491. {
  492. return allocate_impl(0, a, n, hint);
  493. }
  494. // deallocate(Alloc& a, pointer p, size_type n):
  495. // Calls a.deallocate(p, n)
  496. static void deallocate(Alloc& a, pointer p, // NOLINT(runtime/references)
  497. size_type n)
  498. {
  499. a.deallocate(p, n);
  500. }
  501. // construct(Alloc& a, T* p, Args&&... args):
  502. // Calls a.construct(p, std::forward<Args>(args)...) if possible.
  503. // If not possible, calls
  504. // ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)
  505. template<typename T, typename... Args>
  506. static void construct(Alloc& a, T* p, // NOLINT(runtime/references)
  507. Args&&... args)
  508. {
  509. construct_impl(0, a, p, std::forward<Args>(args)...);
  510. }
  511. // destroy(Alloc& a, T* p):
  512. // Calls a.destroy(p) if possible. If not possible, calls p->~T().
  513. template<typename T>
  514. static void destroy(Alloc& a, T* p)
  515. { // NOLINT(runtime/references)
  516. destroy_impl(0, a, p);
  517. }
  518. // max_size(const Alloc& a):
  519. // Returns a.max_size() if possible. If not possible, returns
  520. // std::numeric_limits<size_type>::max() / sizeof(value_type)
  521. static size_type max_size(const Alloc& a)
  522. {
  523. return max_size_impl(0, a);
  524. }
  525. // select_on_container_copy_construction(const Alloc& a):
  526. // Returns a.select_on_container_copy_construction() if possible.
  527. // If not possible, returns a.
  528. static Alloc select_on_container_copy_construction(const Alloc& a)
  529. {
  530. return select_on_container_copy_construction_impl(0, a);
  531. }
  532. private:
  533. template<typename A>
  534. static auto allocate_impl(int, A& a, // NOLINT(runtime/references)
  535. size_type n,
  536. const_void_pointer hint)
  537. -> decltype(a.allocate(n, hint))
  538. {
  539. return a.allocate(n, hint);
  540. }
  541. static pointer allocate_impl(char, Alloc& a, // NOLINT(runtime/references)
  542. size_type n,
  543. const_void_pointer)
  544. {
  545. return a.allocate(n);
  546. }
  547. template<typename A, typename... Args>
  548. static auto construct_impl(int, A& a, // NOLINT(runtime/references)
  549. Args&&... args)
  550. -> decltype(a.construct(std::forward<Args>(args)...))
  551. {
  552. a.construct(std::forward<Args>(args)...);
  553. }
  554. template<typename T, typename... Args>
  555. static void construct_impl(char, Alloc&, T* p, Args&&... args)
  556. {
  557. ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
  558. }
  559. template<typename A, typename T>
  560. static auto destroy_impl(int, A& a, // NOLINT(runtime/references)
  561. T* p) -> decltype(a.destroy(p))
  562. {
  563. a.destroy(p);
  564. }
  565. template<typename T>
  566. static void destroy_impl(char, Alloc&, T* p)
  567. {
  568. p->~T();
  569. }
  570. template<typename A>
  571. static auto max_size_impl(int, const A& a) -> decltype(a.max_size())
  572. {
  573. return a.max_size();
  574. }
  575. static size_type max_size_impl(char, const Alloc&)
  576. {
  577. return (std::numeric_limits<size_type>::max)() / sizeof(value_type);
  578. }
  579. template<typename A>
  580. static auto select_on_container_copy_construction_impl(int, const A& a)
  581. -> decltype(a.select_on_container_copy_construction())
  582. {
  583. return a.select_on_container_copy_construction();
  584. }
  585. static Alloc select_on_container_copy_construction_impl(char, const Alloc& a)
  586. {
  587. return a;
  588. }
  589. };
  590. #endif // __cplusplus >= 201703L
  591. namespace memory_internal
  592. {
  593. // This template alias transforms Alloc::is_nothrow into a metafunction with
  594. // Alloc as a parameter so it can be used with ExtractOrT<>.
  595. template<typename Alloc>
  596. using GetIsNothrow = typename Alloc::is_nothrow;
  597. } // namespace memory_internal
  598. // ABSL_ALLOCATOR_NOTHROW is a build time configuration macro for user to
  599. // specify whether the default allocation function can throw or never throws.
  600. // If the allocation function never throws, user should define it to a non-zero
  601. // value (e.g. via `-DABSL_ALLOCATOR_NOTHROW`).
  602. // If the allocation function can throw, user should leave it undefined or
  603. // define it to zero.
  604. //
  605. // allocator_is_nothrow<Alloc> is a traits class that derives from
  606. // Alloc::is_nothrow if present, otherwise std::false_type. It's specialized
  607. // for Alloc = std::allocator<T> for any type T according to the state of
  608. // ABSL_ALLOCATOR_NOTHROW.
  609. //
  610. // default_allocator_is_nothrow is a class that derives from std::true_type
  611. // when the default allocator (global operator new) never throws, and
  612. // std::false_type when it can throw. It is a convenience shorthand for writing
  613. // allocator_is_nothrow<std::allocator<T>> (T can be any type).
  614. // NOTE: allocator_is_nothrow<std::allocator<T>> is guaranteed to derive from
  615. // the same type for all T, because users should specialize neither
  616. // allocator_is_nothrow nor std::allocator.
  617. template<typename Alloc>
  618. struct allocator_is_nothrow : memory_internal::ExtractOrT<memory_internal::GetIsNothrow, Alloc, std::false_type>
  619. {
  620. };
  621. #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
  622. template<typename T>
  623. struct allocator_is_nothrow<std::allocator<T>> : std::true_type
  624. {
  625. };
  626. struct default_allocator_is_nothrow : std::true_type
  627. {
  628. };
  629. #else
  630. struct default_allocator_is_nothrow : std::false_type
  631. {
  632. };
  633. #endif
  634. namespace memory_internal
  635. {
  636. template<typename Allocator, typename Iterator, typename... Args>
  637. void ConstructRange(Allocator& alloc, Iterator first, Iterator last, const Args&... args)
  638. {
  639. for (Iterator cur = first; cur != last; ++cur)
  640. {
  641. ABSL_INTERNAL_TRY
  642. {
  643. std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), args...);
  644. }
  645. ABSL_INTERNAL_CATCH_ANY
  646. {
  647. while (cur != first)
  648. {
  649. --cur;
  650. std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
  651. }
  652. ABSL_INTERNAL_RETHROW;
  653. }
  654. }
  655. }
  656. template<typename Allocator, typename Iterator, typename InputIterator>
  657. void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, InputIterator last)
  658. {
  659. for (Iterator cur = destination; first != last;
  660. static_cast<void>(++cur), static_cast<void>(++first))
  661. {
  662. ABSL_INTERNAL_TRY
  663. {
  664. std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur), *first);
  665. }
  666. ABSL_INTERNAL_CATCH_ANY
  667. {
  668. while (cur != destination)
  669. {
  670. --cur;
  671. std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
  672. }
  673. ABSL_INTERNAL_RETHROW;
  674. }
  675. }
  676. }
  677. } // namespace memory_internal
  678. ABSL_NAMESPACE_END
  679. } // namespace absl
  680. #endif // ABSL_MEMORY_MEMORY_H_