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#ifndef WTF_NakedPtr_h
27#define WTF_NakedPtr_h
28
29#include <wtf/FastMalloc.h>
30
31namespace WTF {
32
33// The purpose of this class is to ensure that the wrapped pointer will never be
34// used uninitialized.
35
36template <typename T> class NakedPtr {
37 WTF_MAKE_FAST_ALLOCATED;
38public:
39 ALWAYS_INLINE NakedPtr() : m_ptr(nullptr) { }
40 ALWAYS_INLINE NakedPtr(T* ptr) : m_ptr(ptr) { }
41 ALWAYS_INLINE NakedPtr(const NakedPtr& o) : m_ptr(o.m_ptr) { }
42 template<typename U> NakedPtr(const NakedPtr<U>& o) : m_ptr(o.get()) { }
43
44 ALWAYS_INLINE NakedPtr(NakedPtr&& o) : m_ptr(o.get()) { }
45 template<typename U> NakedPtr(NakedPtr<U>&& o) : m_ptr(o.get()) { }
46
47 T* get() const { return m_ptr; }
48
49 void clear() { m_ptr = nullptr; }
50
51 T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
52 ALWAYS_INLINE T* operator->() const { return m_ptr; }
53
54 operator T*() { return m_ptr; }
55
56 bool operator!() const { return !m_ptr; }
57
58 explicit operator bool() const { return !!m_ptr; }
59
60 NakedPtr& operator=(const NakedPtr&);
61 NakedPtr& operator=(T*);
62 template<typename U> NakedPtr& operator=(const NakedPtr<U>&);
63 NakedPtr& operator=(NakedPtr&&);
64 template<typename U> NakedPtr& operator=(NakedPtr<U>&&);
65
66 void swap(NakedPtr&);
67
68private:
69 T* m_ptr;
70};
71
72template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(const NakedPtr& o)
73{
74 m_ptr = o.m_ptr;
75 return *this;
76}
77
78template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(T* optr)
79{
80 m_ptr = optr;
81 return *this;
82}
83
84template<typename T> template<typename U> inline NakedPtr<T>& NakedPtr<T>::operator=(const NakedPtr<U>& o)
85{
86 NakedPtr ptr = o;
87 swap(ptr);
88 return *this;
89}
90
91template<typename T> inline NakedPtr<T>& NakedPtr<T>::operator=(NakedPtr&& o)
92{
93 NakedPtr ptr = WTFMove(o);
94 swap(ptr);
95 return *this;
96}
97
98template<typename T> template<typename U> inline NakedPtr<T>& NakedPtr<T>::operator=(NakedPtr<U>&& o)
99{
100 NakedPtr ptr = WTFMove(o);
101 swap(ptr);
102 return *this;
103}
104
105template<class T> inline void NakedPtr<T>::swap(NakedPtr& o)
106{
107 std::swap(m_ptr, o.m_ptr);
108}
109
110template<class T> inline void swap(NakedPtr<T>& a, NakedPtr<T>& b)
111{
112 a.swap(b);
113}
114
115} // namespace WTF
116
117using WTF::NakedPtr;
118
119#endif // WTF_NakedPtr_h
120