00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef ABSL_MEMORY_MEMORY_H_
00024 #define ABSL_MEMORY_MEMORY_H_
00025
00026 #include <cstddef>
00027 #include <limits>
00028 #include <memory>
00029 #include <new>
00030 #include <type_traits>
00031 #include <utility>
00032
00033 #include "absl/base/macros.h"
00034 #include "absl/meta/type_traits.h"
00035
00036 namespace absl {
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 template <typename T>
00071 std::unique_ptr<T> WrapUnique(T* ptr) {
00072 static_assert(!std::is_array<T>::value, "array types are unsupported");
00073 static_assert(std::is_object<T>::value, "non-object types are unsupported");
00074 return std::unique_ptr<T>(ptr);
00075 }
00076
00077 namespace memory_internal {
00078
00079
00080 template <typename T>
00081 struct MakeUniqueResult {
00082 using scalar = std::unique_ptr<T>;
00083 };
00084 template <typename T>
00085 struct MakeUniqueResult<T[]> {
00086 using array = std::unique_ptr<T[]>;
00087 };
00088 template <typename T, size_t N>
00089 struct MakeUniqueResult<T[N]> {
00090 using invalid = void;
00091 };
00092
00093 }
00094
00095
00096
00097
00098 #if (__cplusplus > 201103L || defined(_MSC_VER)) && \
00099 !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8)
00100 using std::make_unique;
00101 #else
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 template <typename T, typename... Args>
00166 typename memory_internal::MakeUniqueResult<T>::scalar make_unique(
00167 Args&&... args) {
00168 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
00169 }
00170
00171
00172
00173
00174
00175 template <typename T>
00176 typename memory_internal::MakeUniqueResult<T>::array make_unique(size_t n) {
00177 return std::unique_ptr<T>(new typename absl::remove_extent_t<T>[n]());
00178 }
00179
00180
00181
00182 template <typename T, typename... Args>
00183 typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
00184 Args&&... ) = delete;
00185 #endif
00186
00187
00188
00189
00190
00191
00192
00193
00194 template <typename T>
00195 auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) {
00196
00197 return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
00198 }
00199 inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 template <typename T, typename D>
00225 std::shared_ptr<T> ShareUniquePtr(std::unique_ptr<T, D>&& ptr) {
00226 return ptr ? std::shared_ptr<T>(std::move(ptr)) : std::shared_ptr<T>();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 template <typename T>
00245 std::weak_ptr<T> WeakenPtr(const std::shared_ptr<T>& ptr) {
00246 return std::weak_ptr<T>(ptr);
00247 }
00248
00249 namespace memory_internal {
00250
00251
00252 template <template <typename> class Extract, typename Obj, typename Default,
00253 typename>
00254 struct ExtractOr {
00255 using type = Default;
00256 };
00257
00258 template <template <typename> class Extract, typename Obj, typename Default>
00259 struct ExtractOr<Extract, Obj, Default, void_t<Extract<Obj>>> {
00260 using type = Extract<Obj>;
00261 };
00262
00263 template <template <typename> class Extract, typename Obj, typename Default>
00264 using ExtractOrT = typename ExtractOr<Extract, Obj, Default, void>::type;
00265
00266
00267 template <typename T>
00268 using GetPointer = typename T::pointer;
00269
00270 template <typename T>
00271 using GetConstPointer = typename T::const_pointer;
00272
00273 template <typename T>
00274 using GetVoidPointer = typename T::void_pointer;
00275
00276 template <typename T>
00277 using GetConstVoidPointer = typename T::const_void_pointer;
00278
00279 template <typename T>
00280 using GetDifferenceType = typename T::difference_type;
00281
00282 template <typename T>
00283 using GetSizeType = typename T::size_type;
00284
00285 template <typename T>
00286 using GetPropagateOnContainerCopyAssignment =
00287 typename T::propagate_on_container_copy_assignment;
00288
00289 template <typename T>
00290 using GetPropagateOnContainerMoveAssignment =
00291 typename T::propagate_on_container_move_assignment;
00292
00293 template <typename T>
00294 using GetPropagateOnContainerSwap = typename T::propagate_on_container_swap;
00295
00296 template <typename T>
00297 using GetIsAlwaysEqual = typename T::is_always_equal;
00298
00299 template <typename T>
00300 struct GetFirstArg;
00301
00302 template <template <typename...> class Class, typename T, typename... Args>
00303 struct GetFirstArg<Class<T, Args...>> {
00304 using type = T;
00305 };
00306
00307 template <typename Ptr, typename = void>
00308 struct ElementType {
00309 using type = typename GetFirstArg<Ptr>::type;
00310 };
00311
00312 template <typename T>
00313 struct ElementType<T, void_t<typename T::element_type>> {
00314 using type = typename T::element_type;
00315 };
00316
00317 template <typename T, typename U>
00318 struct RebindFirstArg;
00319
00320 template <template <typename...> class Class, typename T, typename... Args,
00321 typename U>
00322 struct RebindFirstArg<Class<T, Args...>, U> {
00323 using type = Class<U, Args...>;
00324 };
00325
00326 template <typename T, typename U, typename = void>
00327 struct RebindPtr {
00328 using type = typename RebindFirstArg<T, U>::type;
00329 };
00330
00331 template <typename T, typename U>
00332 struct RebindPtr<T, U, void_t<typename T::template rebind<U>>> {
00333 using type = typename T::template rebind<U>;
00334 };
00335
00336 template <typename T, typename U>
00337 constexpr bool HasRebindAlloc(...) {
00338 return false;
00339 }
00340
00341 template <typename T, typename U>
00342 constexpr bool HasRebindAlloc(typename T::template rebind<U>::other*) {
00343 return true;
00344 }
00345
00346 template <typename T, typename U, bool = HasRebindAlloc<T, U>(nullptr)>
00347 struct RebindAlloc {
00348 using type = typename RebindFirstArg<T, U>::type;
00349 };
00350
00351 template <typename T, typename U>
00352 struct RebindAlloc<T, U, true> {
00353 using type = typename T::template rebind<U>::other;
00354 };
00355
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 template <typename Ptr>
00370 struct pointer_traits {
00371 using pointer = Ptr;
00372
00373
00374
00375
00376 using element_type = typename memory_internal::ElementType<Ptr>::type;
00377
00378
00379
00380 using difference_type =
00381 memory_internal::ExtractOrT<memory_internal::GetDifferenceType, Ptr,
00382 std::ptrdiff_t>;
00383
00384
00385
00386
00387 template <typename U>
00388 using rebind = typename memory_internal::RebindPtr<Ptr, U>::type;
00389
00390
00391
00392 static pointer pointer_to(element_type& r) {
00393 return Ptr::pointer_to(r);
00394 }
00395 };
00396
00397
00398 template <typename T>
00399 struct pointer_traits<T*> {
00400 using pointer = T*;
00401 using element_type = T;
00402 using difference_type = std::ptrdiff_t;
00403
00404 template <typename U>
00405 using rebind = U*;
00406
00407
00408
00409 static pointer pointer_to(
00410 element_type& r) noexcept {
00411 return std::addressof(r);
00412 }
00413 };
00414
00415
00416
00417
00418
00419
00420
00421 template <typename Alloc>
00422 struct allocator_traits {
00423 using allocator_type = Alloc;
00424
00425
00426
00427 using value_type = typename Alloc::value_type;
00428
00429
00430
00431 using pointer = memory_internal::ExtractOrT<memory_internal::GetPointer,
00432 Alloc, value_type*>;
00433
00434
00435
00436
00437 using const_pointer =
00438 memory_internal::ExtractOrT<memory_internal::GetConstPointer, Alloc,
00439 typename absl::pointer_traits<pointer>::
00440 template rebind<const value_type>>;
00441
00442
00443
00444
00445 using void_pointer = memory_internal::ExtractOrT<
00446 memory_internal::GetVoidPointer, Alloc,
00447 typename absl::pointer_traits<pointer>::template rebind<void>>;
00448
00449
00450
00451
00452 using const_void_pointer = memory_internal::ExtractOrT<
00453 memory_internal::GetConstVoidPointer, Alloc,
00454 typename absl::pointer_traits<pointer>::template rebind<const void>>;
00455
00456
00457
00458
00459 using difference_type = memory_internal::ExtractOrT<
00460 memory_internal::GetDifferenceType, Alloc,
00461 typename absl::pointer_traits<pointer>::difference_type>;
00462
00463
00464
00465
00466 using size_type = memory_internal::ExtractOrT<
00467 memory_internal::GetSizeType, Alloc,
00468 typename std::make_unsigned<difference_type>::type>;
00469
00470
00471
00472
00473 using propagate_on_container_copy_assignment = memory_internal::ExtractOrT<
00474 memory_internal::GetPropagateOnContainerCopyAssignment, Alloc,
00475 std::false_type>;
00476
00477
00478
00479
00480 using propagate_on_container_move_assignment = memory_internal::ExtractOrT<
00481 memory_internal::GetPropagateOnContainerMoveAssignment, Alloc,
00482 std::false_type>;
00483
00484
00485
00486 using propagate_on_container_swap =
00487 memory_internal::ExtractOrT<memory_internal::GetPropagateOnContainerSwap,
00488 Alloc, std::false_type>;
00489
00490
00491
00492 using is_always_equal =
00493 memory_internal::ExtractOrT<memory_internal::GetIsAlwaysEqual, Alloc,
00494 typename std::is_empty<Alloc>::type>;
00495
00496
00497
00498
00499 template <typename T>
00500 using rebind_alloc = typename memory_internal::RebindAlloc<Alloc, T>::type;
00501
00502
00503
00504 template <typename T>
00505 using rebind_traits = absl::allocator_traits<rebind_alloc<T>>;
00506
00507
00508
00509 static pointer allocate(Alloc& a,
00510 size_type n) {
00511 return a.allocate(n);
00512 }
00513
00514
00515
00516
00517 static pointer allocate(Alloc& a, size_type n,
00518 const_void_pointer hint) {
00519 return allocate_impl(0, a, n, hint);
00520 }
00521
00522
00523
00524 static void deallocate(Alloc& a, pointer p,
00525 size_type n) {
00526 a.deallocate(p, n);
00527 }
00528
00529
00530
00531
00532
00533 template <typename T, typename... Args>
00534 static void construct(Alloc& a, T* p,
00535 Args&&... args) {
00536 construct_impl(0, a, p, std::forward<Args>(args)...);
00537 }
00538
00539
00540
00541 template <typename T>
00542 static void destroy(Alloc& a, T* p) {
00543 destroy_impl(0, a, p);
00544 }
00545
00546
00547
00548
00549 static size_type max_size(const Alloc& a) { return max_size_impl(0, a); }
00550
00551
00552
00553
00554 static Alloc select_on_container_copy_construction(const Alloc& a) {
00555 return select_on_container_copy_construction_impl(0, a);
00556 }
00557
00558 private:
00559 template <typename A>
00560 static auto allocate_impl(int, A& a,
00561 size_type n, const_void_pointer hint)
00562 -> decltype(a.allocate(n, hint)) {
00563 return a.allocate(n, hint);
00564 }
00565 static pointer allocate_impl(char, Alloc& a,
00566 size_type n, const_void_pointer) {
00567 return a.allocate(n);
00568 }
00569
00570 template <typename A, typename... Args>
00571 static auto construct_impl(int, A& a,
00572 Args&&... args)
00573 -> decltype(a.construct(std::forward<Args>(args)...)) {
00574 a.construct(std::forward<Args>(args)...);
00575 }
00576
00577 template <typename T, typename... Args>
00578 static void construct_impl(char, Alloc&, T* p, Args&&... args) {
00579 ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
00580 }
00581
00582 template <typename A, typename T>
00583 static auto destroy_impl(int, A& a,
00584 T* p) -> decltype(a.destroy(p)) {
00585 a.destroy(p);
00586 }
00587 template <typename T>
00588 static void destroy_impl(char, Alloc&, T* p) {
00589 p->~T();
00590 }
00591
00592 template <typename A>
00593 static auto max_size_impl(int, const A& a) -> decltype(a.max_size()) {
00594 return a.max_size();
00595 }
00596 static size_type max_size_impl(char, const Alloc&) {
00597 return (std::numeric_limits<size_type>::max)() / sizeof(value_type);
00598 }
00599
00600 template <typename A>
00601 static auto select_on_container_copy_construction_impl(int, const A& a)
00602 -> decltype(a.select_on_container_copy_construction()) {
00603 return a.select_on_container_copy_construction();
00604 }
00605 static Alloc select_on_container_copy_construction_impl(char,
00606 const Alloc& a) {
00607 return a;
00608 }
00609 };
00610
00611 namespace memory_internal {
00612
00613
00614
00615 template <typename Alloc>
00616 using GetIsNothrow = typename Alloc::is_nothrow;
00617
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 template <typename Alloc>
00640 struct allocator_is_nothrow
00641 : memory_internal::ExtractOrT<memory_internal::GetIsNothrow, Alloc,
00642 std::false_type> {};
00643
00644 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
00645 template <typename T>
00646 struct allocator_is_nothrow<std::allocator<T>> : std::true_type {};
00647 struct default_allocator_is_nothrow : std::true_type {};
00648 #else
00649 struct default_allocator_is_nothrow : std::false_type {};
00650 #endif
00651
00652 namespace memory_internal {
00653 template <typename Allocator, typename Iterator, typename... Args>
00654 void ConstructRange(Allocator& alloc, Iterator first, Iterator last,
00655 const Args&... args) {
00656 for (Iterator cur = first; cur != last; ++cur) {
00657 ABSL_INTERNAL_TRY {
00658 std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur),
00659 args...);
00660 }
00661 ABSL_INTERNAL_CATCH_ANY {
00662 while (cur != first) {
00663 --cur;
00664 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
00665 }
00666 ABSL_INTERNAL_RETHROW;
00667 }
00668 }
00669 }
00670
00671 template <typename Allocator, typename Iterator, typename InputIterator>
00672 void CopyRange(Allocator& alloc, Iterator destination, InputIterator first,
00673 InputIterator last) {
00674 for (Iterator cur = destination; first != last;
00675 static_cast<void>(++cur), static_cast<void>(++first)) {
00676 ABSL_INTERNAL_TRY {
00677 std::allocator_traits<Allocator>::construct(alloc, std::addressof(*cur),
00678 *first);
00679 }
00680 ABSL_INTERNAL_CATCH_ANY {
00681 while (cur != destination) {
00682 --cur;
00683 std::allocator_traits<Allocator>::destroy(alloc, std::addressof(*cur));
00684 }
00685 ABSL_INTERNAL_RETHROW;
00686 }
00687 }
00688 }
00689 }
00690 }
00691
00692 #endif // ABSL_MEMORY_MEMORY_H_