]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_unique_ptr.h
Initial vogl checkin
[vogl] / src / voglcore / vogl_unique_ptr.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_unique_ptr.h
28 #ifndef VOGL_UNIQUE_PTR_H
29 #define VOGL_UNIQUE_PTR_H
30
31 #include "vogl_core.h"
32
33 namespace vogl
34 {
35     template <typename T>
36     class vogl_unique_ptr_default_delete_policy
37     {
38     protected:
39         void swap(vogl_unique_ptr_default_delete_policy<T> &rhs)
40         {
41             VOGL_NOTE_UNUSED(rhs);
42         }
43
44         void delete_ptr(T *p)
45         {
46             vogl_delete(p);
47         }
48     };
49
50     // First attempt at a std::unique_ptr-like object. This shit is subtle so there are probably dragons in here. Note I could care less about exception safety.
51     // pointer must be allocated using vogl_new().
52     // Using a policy to handle deletion, vs. an object type to avoid this object from growing larger than a ptr in the default case.
53     template <typename T, typename D = vogl_unique_ptr_default_delete_policy<T> >
54     class vogl_unique_ptr : public utils::relative_ops<vogl_unique_ptr<T, D> >, public D
55     {
56     public:
57         typedef T element_type;
58         typedef T *pointer;
59         typedef D delete_policy;
60
61         vogl_unique_ptr()
62             : m_p()
63         {
64         }
65
66         vogl_unique_ptr(pointer p)
67             : m_p(p)
68         {
69         }
70
71         vogl_unique_ptr(vogl_unique_ptr &other)
72             : m_p(other.release())
73         {
74         }
75
76         ~vogl_unique_ptr()
77         {
78             reset();
79         }
80
81         void reset(pointer p = pointer())
82         {
83             VOGL_ASSUME(sizeof(T) > 0);
84             VOGL_ASSERT((!p) || (p != m_p));
85
86             pointer prev_ptr = m_p;
87             m_p = p;
88             if (prev_ptr)
89                 delete_policy::delete_ptr(prev_ptr);
90         }
91
92         pointer release()
93         {
94             pointer p = m_p;
95             m_p = NULL;
96             return p;
97         }
98
99         vogl_unique_ptr &operator=(vogl_unique_ptr &rhs)
100         {
101             if (this != &rhs)
102             {
103                 reset(rhs.release());
104             }
105             return *this;
106         }
107
108         void swap(vogl_unique_ptr &other)
109         {
110             std::swap(m_p, other.m_p);
111             delete_policy::swap(other);
112         }
113
114 #if 0
115         // Feels too dangerous without explicit, but we need C++0x for that.
116         explicit operator bool() const
117         {
118                 return m_p != NULL;
119         }
120 #endif
121
122         pointer get() const
123         {
124             return m_p;
125         }
126
127         pointer operator->() const
128         {
129             return m_p;
130         }
131
132         T &operator*() const
133         {
134             return *m_p;
135         }
136
137         bool operator==(const vogl_unique_ptr &rhs) const
138         {
139             return m_p == rhs.m_p;
140         }
141
142         bool operator<(const vogl_unique_ptr &rhs) const
143         {
144             return m_p < rhs.m_p;
145         }
146
147     private:
148         pointer m_p;
149     };
150 }
151
152 namespace std
153 {
154     template <typename T>
155     inline void swap(vogl::vogl_unique_ptr<T> &a, vogl::vogl_unique_ptr<T> &b)
156     {
157         a.swap(b);
158     }
159 }
160
161 #endif // VOGL_UNIQUE_PTR_H