memory.h
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 //
00015 // -----------------------------------------------------------------------------
00016 // File: memory.h
00017 // -----------------------------------------------------------------------------
00018 //
00019 // This header file contains utility functions for managing the creation and
00020 // conversion of smart pointers. This file is an extension to the C++
00021 // standard <memory> library header file.
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 // Function Template: WrapUnique()
00040 // -----------------------------------------------------------------------------
00041 //
00042 // Adopts ownership from a raw pointer and transfers it to the returned
00043 // `std::unique_ptr`, whose type is deduced. Because of this deduction, *do not*
00044 // specify the template type `T` when calling `WrapUnique`.
00045 //
00046 // Example:
00047 //   X* NewX(int, int);
00048 //   auto x = WrapUnique(NewX(1, 2));  // 'x' is std::unique_ptr<X>.
00049 //
00050 // Do not call WrapUnique with an explicit type, as in
00051 // `WrapUnique<X>(NewX(1, 2))`.  The purpose of WrapUnique is to automatically
00052 // deduce the pointer type. If you wish to make the type explicit, just use
00053 // `std::unique_ptr` directly.
00054 //
00055 //   auto x = std::unique_ptr<X>(NewX(1, 2));
00056 //                  - or -
00057 //   std::unique_ptr<X> x(NewX(1, 2));
00058 //
00059 // While `absl::WrapUnique` is useful for capturing the output of a raw
00060 // pointer factory, prefer 'absl::make_unique<T>(args...)' over
00061 // 'absl::WrapUnique(new T(args...))'.
00062 //
00063 //   auto x = WrapUnique(new X(1, 2));  // works, but nonideal.
00064 //   auto x = make_unique<X>(1, 2);     // safer, standard, avoids raw 'new'.
00065 //
00066 // Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid
00067 // expression. In particular, `absl::WrapUnique()` cannot wrap pointers to
00068 // arrays, functions or void, and it must not be used to capture pointers
00069 // obtained from array-new expressions (even though that would compile!).
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 // Traits to select proper overload and return type for `absl::make_unique<>`.
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 }  // namespace memory_internal
00094 
00095 // gcc 4.8 has __cplusplus at 201301 but doesn't define make_unique.  Other
00096 // supported compilers either just define __cplusplus as 201103 but have
00097 // make_unique (msvc), or have make_unique whenever __cplusplus > 201103 (clang)
00098 #if (__cplusplus > 201103L || defined(_MSC_VER)) && \
00099     !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8)
00100 using std::make_unique;
00101 #else
00102 // -----------------------------------------------------------------------------
00103 // Function Template: make_unique<T>()
00104 // -----------------------------------------------------------------------------
00105 //
00106 // Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries
00107 // during the construction process. `absl::make_unique<>` also avoids redundant
00108 // type declarations, by avoiding the need to explicitly use the `new` operator.
00109 //
00110 // This implementation of `absl::make_unique<>` is designed for C++11 code and
00111 // will be replaced in C++14 by the equivalent `std::make_unique<>` abstraction.
00112 // `absl::make_unique<>` is designed to be 100% compatible with
00113 // `std::make_unique<>` so that the eventual migration will involve a simple
00114 // rename operation.
00115 //
00116 // For more background on why `std::unique_ptr<T>(new T(a,b))` is problematic,
00117 // see Herb Sutter's explanation on
00118 // (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/].
00119 // (In general, reviewers should treat `new T(a,b)` with scrutiny.)
00120 //
00121 // Example usage:
00122 //
00123 //    auto p = make_unique<X>(args...);  // 'p'  is a std::unique_ptr<X>
00124 //    auto pa = make_unique<X[]>(5);     // 'pa' is a std::unique_ptr<X[]>
00125 //
00126 // Three overloads of `absl::make_unique` are required:
00127 //
00128 //   - For non-array T:
00129 //
00130 //       Allocates a T with `new T(std::forward<Args> args...)`,
00131 //       forwarding all `args` to T's constructor.
00132 //       Returns a `std::unique_ptr<T>` owning that object.
00133 //
00134 //   - For an array of unknown bounds T[]:
00135 //
00136 //       `absl::make_unique<>` will allocate an array T of type U[] with
00137 //       `new U[n]()` and return a `std::unique_ptr<U[]>` owning that array.
00138 //
00139 //       Note that 'U[n]()' is different from 'U[n]', and elements will be
00140 //       value-initialized. Note as well that `std::unique_ptr` will perform its
00141 //       own destruction of the array elements upon leaving scope, even though
00142 //       the array [] does not have a default destructor.
00143 //
00144 //       NOTE: an array of unknown bounds T[] may still be (and often will be)
00145 //       initialized to have a size, and will still use this overload. E.g:
00146 //
00147 //         auto my_array = absl::make_unique<int[]>(10);
00148 //
00149 //   - For an array of known bounds T[N]:
00150 //
00151 //       `absl::make_unique<>` is deleted (like with `std::make_unique<>`) as
00152 //       this overload is not useful.
00153 //
00154 //       NOTE: an array of known bounds T[N] is not considered a useful
00155 //       construction, and may cause undefined behavior in templates. E.g:
00156 //
00157 //         auto my_array = absl::make_unique<int[10]>();
00158 //
00159 //       In those cases, of course, you can still use the overload above and
00160 //       simply initialize it to its desired size:
00161 //
00162 //         auto my_array = absl::make_unique<int[]>(10);
00163 
00164 // `absl::make_unique` overload for non-array types.
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 // `absl::make_unique` overload for an array T[] of unknown bounds.
00172 // The array allocation needs to use the `new T[size]` form and cannot take
00173 // element constructor arguments. The `std::unique_ptr` will manage destructing
00174 // these array elements.
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 // `absl::make_unique` overload for an array T[N] of known bounds.
00181 // This construction will be rejected.
00182 template <typename T, typename... Args>
00183 typename memory_internal::MakeUniqueResult<T>::invalid make_unique(
00184     Args&&... /* args */) = delete;
00185 #endif
00186 
00187 // -----------------------------------------------------------------------------
00188 // Function Template: RawPtr()
00189 // -----------------------------------------------------------------------------
00190 //
00191 // Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is
00192 // useful within templates that need to handle a complement of raw pointers,
00193 // `std::nullptr_t`, and smart pointers.
00194 template <typename T>
00195 auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) {
00196   // ptr is a forwarding reference to support Ts with non-const operators.
00197   return (ptr != nullptr) ? std::addressof(*ptr) : nullptr;
00198 }
00199 inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; }
00200 
00201 // -----------------------------------------------------------------------------
00202 // Function Template: ShareUniquePtr()
00203 // -----------------------------------------------------------------------------
00204 //
00205 // Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced
00206 // type. Ownership (if any) of the held value is transferred to the returned
00207 // shared pointer.
00208 //
00209 // Example:
00210 //
00211 //     auto up = absl::make_unique<int>(10);
00212 //     auto sp = absl::ShareUniquePtr(std::move(up));  // shared_ptr<int>
00213 //     CHECK_EQ(*sp, 10);
00214 //     CHECK(up == nullptr);
00215 //
00216 // Note that this conversion is correct even when T is an array type, and more
00217 // generally it works for *any* deleter of the `unique_ptr` (single-object
00218 // deleter, array deleter, or any custom deleter), since the deleter is adopted
00219 // by the shared pointer as well. The deleter is copied (unless it is a
00220 // reference).
00221 //
00222 // Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a
00223 // null shared pointer does not attempt to call the deleter.
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 // Function Template: WeakenPtr()
00231 // -----------------------------------------------------------------------------
00232 //
00233 // Creates a weak pointer associated with a given shared pointer. The returned
00234 // value is a `std::weak_ptr` of deduced type.
00235 //
00236 // Example:
00237 //
00238 //    auto sp = std::make_shared<int>(10);
00239 //    auto wp = absl::WeakenPtr(sp);
00240 //    CHECK_EQ(sp.get(), wp.lock().get());
00241 //    sp.reset();
00242 //    CHECK(wp.lock() == nullptr);
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 // ExtractOr<E, O, D>::type evaluates to E<O> if possible. Otherwise, D.
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 // Extractors for the features of allocators.
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 }  // namespace memory_internal
00357 
00358 // -----------------------------------------------------------------------------
00359 // Class Template: pointer_traits
00360 // -----------------------------------------------------------------------------
00361 //
00362 // An implementation of C++11's std::pointer_traits.
00363 //
00364 // Provided for portability on toolchains that have a working C++11 compiler,
00365 // but the standard library is lacking in C++11 support. For example, some
00366 // version of the Android NDK.
00367 //
00368 
00369 template <typename Ptr>
00370 struct pointer_traits {
00371   using pointer = Ptr;
00372 
00373   // element_type:
00374   // Ptr::element_type if present. Otherwise T if Ptr is a template
00375   // instantiation Template<T, Args...>
00376   using element_type = typename memory_internal::ElementType<Ptr>::type;
00377 
00378   // difference_type:
00379   // Ptr::difference_type if present, otherwise std::ptrdiff_t
00380   using difference_type =
00381       memory_internal::ExtractOrT<memory_internal::GetDifferenceType, Ptr,
00382                                   std::ptrdiff_t>;
00383 
00384   // rebind:
00385   // Ptr::rebind<U> if exists, otherwise Template<U, Args...> if Ptr is a
00386   // template instantiation Template<T, Args...>
00387   template <typename U>
00388   using rebind = typename memory_internal::RebindPtr<Ptr, U>::type;
00389 
00390   // pointer_to:
00391   // Calls Ptr::pointer_to(r)
00392   static pointer pointer_to(element_type& r) {  // NOLINT(runtime/references)
00393     return Ptr::pointer_to(r);
00394   }
00395 };
00396 
00397 // Specialization for T*.
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   // pointer_to:
00408   // Calls std::addressof(r)
00409   static pointer pointer_to(
00410       element_type& r) noexcept {  // NOLINT(runtime/references)
00411     return std::addressof(r);
00412   }
00413 };
00414 
00415 // -----------------------------------------------------------------------------
00416 // Class Template: allocator_traits
00417 // -----------------------------------------------------------------------------
00418 //
00419 // A C++11 compatible implementation of C++17's std::allocator_traits.
00420 //
00421 template <typename Alloc>
00422 struct allocator_traits {
00423   using allocator_type = Alloc;
00424 
00425   // value_type:
00426   // Alloc::value_type
00427   using value_type = typename Alloc::value_type;
00428 
00429   // pointer:
00430   // Alloc::pointer if present, otherwise value_type*
00431   using pointer = memory_internal::ExtractOrT<memory_internal::GetPointer,
00432                                               Alloc, value_type*>;
00433 
00434   // const_pointer:
00435   // Alloc::const_pointer if present, otherwise
00436   // absl::pointer_traits<pointer>::rebind<const value_type>
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   // void_pointer:
00443   // Alloc::void_pointer if present, otherwise
00444   // absl::pointer_traits<pointer>::rebind<void>
00445   using void_pointer = memory_internal::ExtractOrT<
00446       memory_internal::GetVoidPointer, Alloc,
00447       typename absl::pointer_traits<pointer>::template rebind<void>>;
00448 
00449   // const_void_pointer:
00450   // Alloc::const_void_pointer if present, otherwise
00451   // absl::pointer_traits<pointer>::rebind<const void>
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   // difference_type:
00457   // Alloc::difference_type if present, otherwise
00458   // absl::pointer_traits<pointer>::difference_type
00459   using difference_type = memory_internal::ExtractOrT<
00460       memory_internal::GetDifferenceType, Alloc,
00461       typename absl::pointer_traits<pointer>::difference_type>;
00462 
00463   // size_type:
00464   // Alloc::size_type if present, otherwise
00465   // std::make_unsigned<difference_type>::type
00466   using size_type = memory_internal::ExtractOrT<
00467       memory_internal::GetSizeType, Alloc,
00468       typename std::make_unsigned<difference_type>::type>;
00469 
00470   // propagate_on_container_copy_assignment:
00471   // Alloc::propagate_on_container_copy_assignment if present, otherwise
00472   // std::false_type
00473   using propagate_on_container_copy_assignment = memory_internal::ExtractOrT<
00474       memory_internal::GetPropagateOnContainerCopyAssignment, Alloc,
00475       std::false_type>;
00476 
00477   // propagate_on_container_move_assignment:
00478   // Alloc::propagate_on_container_move_assignment if present, otherwise
00479   // std::false_type
00480   using propagate_on_container_move_assignment = memory_internal::ExtractOrT<
00481       memory_internal::GetPropagateOnContainerMoveAssignment, Alloc,
00482       std::false_type>;
00483 
00484   // propagate_on_container_swap:
00485   // Alloc::propagate_on_container_swap if present, otherwise std::false_type
00486   using propagate_on_container_swap =
00487       memory_internal::ExtractOrT<memory_internal::GetPropagateOnContainerSwap,
00488                                   Alloc, std::false_type>;
00489 
00490   // is_always_equal:
00491   // Alloc::is_always_equal if present, otherwise std::is_empty<Alloc>::type
00492   using is_always_equal =
00493       memory_internal::ExtractOrT<memory_internal::GetIsAlwaysEqual, Alloc,
00494                                   typename std::is_empty<Alloc>::type>;
00495 
00496   // rebind_alloc:
00497   // Alloc::rebind<T>::other if present, otherwise Alloc<T, Args> if this Alloc
00498   // is Alloc<U, Args>
00499   template <typename T>
00500   using rebind_alloc = typename memory_internal::RebindAlloc<Alloc, T>::type;
00501 
00502   // rebind_traits:
00503   // absl::allocator_traits<rebind_alloc<T>>
00504   template <typename T>
00505   using rebind_traits = absl::allocator_traits<rebind_alloc<T>>;
00506 
00507   // allocate(Alloc& a, size_type n):
00508   // Calls a.allocate(n)
00509   static pointer allocate(Alloc& a,  // NOLINT(runtime/references)
00510                           size_type n) {
00511     return a.allocate(n);
00512   }
00513 
00514   // allocate(Alloc& a, size_type n, const_void_pointer hint):
00515   // Calls a.allocate(n, hint) if possible.
00516   // If not possible, calls a.allocate(n)
00517   static pointer allocate(Alloc& a, size_type n,  // NOLINT(runtime/references)
00518                           const_void_pointer hint) {
00519     return allocate_impl(0, a, n, hint);
00520   }
00521 
00522   // deallocate(Alloc& a, pointer p, size_type n):
00523   // Calls a.deallocate(p, n)
00524   static void deallocate(Alloc& a, pointer p,  // NOLINT(runtime/references)
00525                          size_type n) {
00526     a.deallocate(p, n);
00527   }
00528 
00529   // construct(Alloc& a, T* p, Args&&... args):
00530   // Calls a.construct(p, std::forward<Args>(args)...) if possible.
00531   // If not possible, calls
00532   //   ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)
00533   template <typename T, typename... Args>
00534   static void construct(Alloc& a, T* p,  // NOLINT(runtime/references)
00535                         Args&&... args) {
00536     construct_impl(0, a, p, std::forward<Args>(args)...);
00537   }
00538 
00539   // destroy(Alloc& a, T* p):
00540   // Calls a.destroy(p) if possible. If not possible, calls p->~T().
00541   template <typename T>
00542   static void destroy(Alloc& a, T* p) {  // NOLINT(runtime/references)
00543     destroy_impl(0, a, p);
00544   }
00545 
00546   // max_size(const Alloc& a):
00547   // Returns a.max_size() if possible. If not possible, returns
00548   //   std::numeric_limits<size_type>::max() / sizeof(value_type)
00549   static size_type max_size(const Alloc& a) { return max_size_impl(0, a); }
00550 
00551   // select_on_container_copy_construction(const Alloc& a):
00552   // Returns a.select_on_container_copy_construction() if possible.
00553   // If not possible, returns a.
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,  // NOLINT(runtime/references)
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,  // NOLINT(runtime/references)
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,  // NOLINT(runtime/references)
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,  // NOLINT(runtime/references)
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 // This template alias transforms Alloc::is_nothrow into a metafunction with
00614 // Alloc as a parameter so it can be used with ExtractOrT<>.
00615 template <typename Alloc>
00616 using GetIsNothrow = typename Alloc::is_nothrow;
00617 
00618 }  // namespace memory_internal
00619 
00620 // ABSL_ALLOCATOR_NOTHROW is a build time configuration macro for user to
00621 // specify whether the default allocation function can throw or never throws.
00622 // If the allocation function never throws, user should define it to a non-zero
00623 // value (e.g. via `-DABSL_ALLOCATOR_NOTHROW`).
00624 // If the allocation function can throw, user should leave it undefined or
00625 // define it to zero.
00626 //
00627 // allocator_is_nothrow<Alloc> is a traits class that derives from
00628 // Alloc::is_nothrow if present, otherwise std::false_type. It's specialized
00629 // for Alloc = std::allocator<T> for any type T according to the state of
00630 // ABSL_ALLOCATOR_NOTHROW.
00631 //
00632 // default_allocator_is_nothrow is a class that derives from std::true_type
00633 // when the default allocator (global operator new) never throws, and
00634 // std::false_type when it can throw. It is a convenience shorthand for writing
00635 // allocator_is_nothrow<std::allocator<T>> (T can be any type).
00636 // NOTE: allocator_is_nothrow<std::allocator<T>> is guaranteed to derive from
00637 // the same type for all T, because users should specialize neither
00638 // allocator_is_nothrow nor std::allocator.
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 }  // namespace memory_internal
00690 }  // namespace absl
00691 
00692 #endif  // ABSL_MEMORY_MEMORY_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15