Home | History | Annotate | Download | only in memory
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_MEMORY_PTR_UTIL_H_
      6 #define BASE_MEMORY_PTR_UTIL_H_
      7 
      8 #include <memory>
      9 #include <utility>
     10 
     11 namespace base {
     12 
     13 // Helper to transfer ownership of a raw pointer to a std::unique_ptr<T>.
     14 // Note that std::unique_ptr<T> has very different semantics from
     15 // std::unique_ptr<T[]>: do not use this helper for array allocations.
     16 template <typename T>
     17 std::unique_ptr<T> WrapUnique(T* ptr) {
     18   return std::unique_ptr<T>(ptr);
     19 }
     20 
     21 namespace internal {
     22 
     23 template <typename T>
     24 struct MakeUniqueResult {
     25   using Scalar = std::unique_ptr<T>;
     26 };
     27 
     28 template <typename T>
     29 struct MakeUniqueResult<T[]> {
     30   using Array = std::unique_ptr<T[]>;
     31 };
     32 
     33 template <typename T, size_t N>
     34 struct MakeUniqueResult<T[N]> {
     35   using Invalid = void;
     36 };
     37 
     38 }  // namespace internal
     39 
     40 // Helper to construct an object wrapped in a std::unique_ptr. This is an
     41 // implementation of C++14's std::make_unique that can be used in Chrome.
     42 //
     43 // MakeUnique<T>(args) should be preferred over WrapUnique(new T(args)): bare
     44 // calls to `new` should be treated with scrutiny.
     45 //
     46 // Usage:
     47 //   // ptr is a std::unique_ptr<std::string>
     48 //   auto ptr = MakeUnique<std::string>("hello world!");
     49 //
     50 //   // arr is a std::unique_ptr<int[]>
     51 //   auto arr = MakeUnique<int[]>(5);
     52 
     53 // Overload for non-array types. Arguments are forwarded to T's constructor.
     54 template <typename T, typename... Args>
     55 typename internal::MakeUniqueResult<T>::Scalar MakeUnique(Args&&... args) {
     56   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
     57 }
     58 
     59 // Overload for array types of unknown bound, e.g. T[]. The array is allocated
     60 // with `new T[n]()` and value-initialized: note that this is distinct from
     61 // `new T[n]`, which default-initializes.
     62 template <typename T>
     63 typename internal::MakeUniqueResult<T>::Array MakeUnique(size_t size) {
     64   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
     65 }
     66 
     67 // Overload to reject array types of known bound, e.g. T[n].
     68 template <typename T, typename... Args>
     69 typename internal::MakeUniqueResult<T>::Invalid MakeUnique(Args&&... args) =
     70     delete;
     71 
     72 }  // namespace base
     73 
     74 #endif  // BASE_MEMORY_PTR_UTIL_H_
     75