1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include <wtf/FastMalloc.h>
29
30namespace WTF {
31
32// The purpose of this class is to ensure that the wrapped pointer will never be
33// used uninitialized.
34
35template <typename T> class NakedPtr {
36 WTF_MAKE_FAST_ALLOCATED;
37public:
38 ALWAYS_INLINE NakedPtr() : m_ptr(nullptr) { }
39 ALWAYS_INLINE NakedPtr(T* ptr) : m_ptr(ptr) { }
40 ALWAYS_INLINE NakedPtr(const NakedPtr& o) : m_ptr(o.m_ptr) { }
41 template<typename U> NakedPtr(const NakedPtr<U>& o) : m_ptr(o.get()) { }
42
43 ALWAYS_INLINE NakedPtr(NakedPtr&& o) : m_ptr(o.get()) { }
44 template<typename U> NakedPtr(NakedPtr<U>&& o) : m_ptr(o.get()) { }
45
46 T* get() const { return m_ptr; }
47
48 void clear() { m_ptr = nullptr; }
49
50 T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
51 ALWAYS_INLINE T* operator->() const { return m_ptr; }
52
53 operator T*() { return m_ptr; }
54
55 bool operator!() const { return !m_ptr; }
56
57 explicit operator bool() const { return !!m_ptr; }
58
59 NakedPtr& operator=(const NakedPtr&);
60 NakedPtr& operator=(T*);
61 template<typename U> NakedPtr& operator=(const NakedPtr<U>&);
62 NakedPtr& operator=(NakedPtr&&);
63 template<typename U> NakedPtr& operator=(NakedPtr<U>&&);
64
65 void swap(NakedPtr&);
66
67private:
68 T* m_ptr;
69};
70
71template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(const NakedPtr& o)
72{
73 m_ptr = o.m_ptr;
74 return *this;
75}
76
77template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(T* optr)
78{
79 m_ptr = optr;
80 return *this;
81}
82
83template<typename T> template<typename U> inline NakedPtr<T>& NakedPtr<T>::operator=(const NakedPtr<U>& o)
84{
85 NakedPtr ptr = o;
86 swap(ptr);
87 return *this;
88}
89
90template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(NakedPtr&& o)
91{
92 NakedPtr ptr = WTFMove(o);
93 swap(ptr);
94 return *this;
95}
96
97template<typename T> template<typename U> inline NakedPtr<T>& NakedPtr<T>::operator=(NakedPtr<U>&& o)
98{
99 NakedPtr ptr = WTFMove(o);
100 swap(ptr);
101 return *this;
102}
103
104template<class T> inline void NakedPtr<T>::swap(NakedPtr& o)
105{
106 std::swap(m_ptr, o.m_ptr);
107}
108
109template<class T> inline void swap(NakedPtr<T>& a, NakedPtr<T>& b)
110{
111 a.swap(b);
112}
113
114} // namespace WTF
115
116using WTF::NakedPtr;
117