1 // Copyright (c) 2007 The NetBSD Foundation, Inc.
2 // 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 THE NETBSD FOUNDATION, INC. AND
14 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 #if !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
27 #define ATF_CXX_DETAIL_AUTO_ARRAY_HPP
28
29 #include <cstddef>
30
31 namespace atf {
32
33 // ------------------------------------------------------------------------
34 // The "auto_array" class.
35 // ------------------------------------------------------------------------
36
37 template< class T >
38 struct auto_array_ref {
39 T* m_ptr;
40
41 explicit auto_array_ref(T*);
42 };
43
44 template< class T >
auto_array_ref(T * ptr)45 auto_array_ref< T >::auto_array_ref(T* ptr) :
46 m_ptr(ptr)
47 {
48 }
49
50 template< class T >
51 class auto_array {
52 T* m_ptr;
53
54 public:
55 auto_array(T* = NULL) throw();
56 auto_array(auto_array< T >&) throw();
57 auto_array(auto_array_ref< T >) throw();
58 ~auto_array(void) throw();
59
60 T* get(void) throw();
61 const T* get(void) const throw();
62 T* release(void) throw();
63 void reset(T* = NULL) throw();
64
65 auto_array< T >& operator=(auto_array< T >&) throw();
66 auto_array< T >& operator=(auto_array_ref< T >) throw();
67
68 T& operator[](int) throw();
69 operator auto_array_ref< T >(void) throw();
70 };
71
72 template< class T >
auto_array(T * ptr)73 auto_array< T >::auto_array(T* ptr)
74 throw() :
75 m_ptr(ptr)
76 {
77 }
78
79 template< class T >
auto_array(auto_array<T> & ptr)80 auto_array< T >::auto_array(auto_array< T >& ptr)
81 throw() :
82 m_ptr(ptr.release())
83 {
84 }
85
86 template< class T >
auto_array(auto_array_ref<T> ref)87 auto_array< T >::auto_array(auto_array_ref< T > ref)
88 throw() :
89 m_ptr(ref.m_ptr)
90 {
91 }
92
93 template< class T >
~auto_array(void)94 auto_array< T >::~auto_array(void)
95 throw()
96 {
97 if (m_ptr != NULL)
98 delete [] m_ptr;
99 }
100
101 template< class T >
102 T*
get(void)103 auto_array< T >::get(void)
104 throw()
105 {
106 return m_ptr;
107 }
108
109 template< class T >
110 const T*
get(void) const111 auto_array< T >::get(void)
112 const throw()
113 {
114 return m_ptr;
115 }
116
117 template< class T >
118 T*
release(void)119 auto_array< T >::release(void)
120 throw()
121 {
122 T* ptr = m_ptr;
123 m_ptr = NULL;
124 return ptr;
125 }
126
127 template< class T >
128 void
reset(T * ptr)129 auto_array< T >::reset(T* ptr)
130 throw()
131 {
132 if (m_ptr != NULL)
133 delete [] m_ptr;
134 m_ptr = ptr;
135 }
136
137 template< class T >
138 auto_array< T >&
operator =(auto_array<T> & ptr)139 auto_array< T >::operator=(auto_array< T >& ptr)
140 throw()
141 {
142 reset(ptr.release());
143 return *this;
144 }
145
146 template< class T >
147 auto_array< T >&
operator =(auto_array_ref<T> ref)148 auto_array< T >::operator=(auto_array_ref< T > ref)
149 throw()
150 {
151 if (m_ptr != ref.m_ptr) {
152 delete [] m_ptr;
153 m_ptr = ref.m_ptr;
154 }
155 return *this;
156 }
157
158 template< class T >
159 T&
operator [](int pos)160 auto_array< T >::operator[](int pos)
161 throw()
162 {
163 return m_ptr[pos];
164 }
165
166 template< class T >
operator auto_array_ref<T>(void)167 auto_array< T >::operator auto_array_ref< T >(void)
168 throw()
169 {
170 return auto_array_ref< T >(release());
171 }
172
173 } // namespace atf
174
175 #endif // !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
176