catch_unique_ptr.hpp
1 2 // Copyright Catch2 Authors 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE.txt or copy at 5 // https://www.boost.org/LICENSE_1_0.txt) 6 7 // SPDX-License-Identifier: BSL-1.0 8 #ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED 9 #define CATCH_UNIQUE_PTR_HPP_INCLUDED 10 11 #include <cassert> 12 #include <type_traits> 13 14 #include <catch2/internal/catch_move_and_forward.hpp> 15 16 namespace Catch { 17 namespace Detail { 18 /** 19 * A reimplementation of `std::unique_ptr` for improved compilation performance 20 * 21 * Does not support arrays nor custom deleters. 22 */ 23 template <typename T> 24 class unique_ptr { 25 T* m_ptr; 26 public: 27 constexpr unique_ptr(std::nullptr_t = nullptr): 28 m_ptr{} 29 {} 30 explicit constexpr unique_ptr(T* ptr): 31 m_ptr(ptr) 32 {} 33 34 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>> 35 unique_ptr(unique_ptr<U>&& from): 36 m_ptr(from.release()) 37 {} 38 39 template <typename U, typename = std::enable_if_t<std::is_base_of<T, U>::value>> 40 unique_ptr& operator=(unique_ptr<U>&& from) { 41 reset(from.release()); 42 43 return *this; 44 } 45 46 unique_ptr(unique_ptr const&) = delete; 47 unique_ptr& operator=(unique_ptr const&) = delete; 48 49 unique_ptr(unique_ptr&& rhs) noexcept: 50 m_ptr(rhs.m_ptr) { 51 rhs.m_ptr = nullptr; 52 } 53 unique_ptr& operator=(unique_ptr&& rhs) noexcept { 54 reset(rhs.release()); 55 56 return *this; 57 } 58 59 ~unique_ptr() { 60 delete m_ptr; 61 } 62 63 T& operator*() { 64 assert(m_ptr); 65 return *m_ptr; 66 } 67 T const& operator*() const { 68 assert(m_ptr); 69 return *m_ptr; 70 } 71 T* operator->() noexcept { 72 assert(m_ptr); 73 return m_ptr; 74 } 75 T const* operator->() const noexcept { 76 assert(m_ptr); 77 return m_ptr; 78 } 79 80 T* get() { return m_ptr; } 81 T const* get() const { return m_ptr; } 82 83 void reset(T* ptr = nullptr) { 84 delete m_ptr; 85 m_ptr = ptr; 86 } 87 88 T* release() { 89 auto temp = m_ptr; 90 m_ptr = nullptr; 91 return temp; 92 } 93 94 explicit operator bool() const { 95 return m_ptr; 96 } 97 98 friend void swap(unique_ptr& lhs, unique_ptr& rhs) { 99 auto temp = lhs.m_ptr; 100 lhs.m_ptr = rhs.m_ptr; 101 rhs.m_ptr = temp; 102 } 103 }; 104 105 //! Specialization to cause compile-time error for arrays 106 template <typename T> 107 class unique_ptr<T[]>; 108 109 template <typename T, typename... Args> 110 unique_ptr<T> make_unique(Args&&... args) { 111 return unique_ptr<T>(new T(CATCH_FORWARD(args)...)); 112 } 113 114 115 } // end namespace Detail 116 } // end namespace Catch 117 118 #endif // CATCH_UNIQUE_PTR_HPP_INCLUDED