1 // Copyright 2016 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 PDFIUM_THIRD_PARTY_BASE_PTR_UTIL_H_ 6 #define PDFIUM_THIRD_PARTY_BASE_PTR_UTIL_H_ 7 8 #include <memory> 9 #include <utility> 10 11 namespace pdfium { 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> WrapUnique(T * ptr)17std::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::MakeUnique 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 pdfium 73 74 #endif // PDFIUM_THIRD_PARTY_BASE_PTR_UTIL_H_ 75