xref: /freebsd/contrib/kyua/utils/auto_array.ipp (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
1*b0d29bc4SBrooks Davis// Copyright 2010 The Kyua Authors.
2*b0d29bc4SBrooks Davis// All rights reserved.
3*b0d29bc4SBrooks Davis//
4*b0d29bc4SBrooks Davis// Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis// modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis// met:
7*b0d29bc4SBrooks Davis//
8*b0d29bc4SBrooks Davis// * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis//   notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis// * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis//   notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis//   documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis// * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis//   may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis//   without specific prior written permission.
16*b0d29bc4SBrooks Davis//
17*b0d29bc4SBrooks Davis// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis
29*b0d29bc4SBrooks Davis#if !defined(UTILS_AUTO_ARRAY_IPP)
30*b0d29bc4SBrooks Davis#define UTILS_AUTO_ARRAY_IPP
31*b0d29bc4SBrooks Davis
32*b0d29bc4SBrooks Davis#include "utils/auto_array.hpp"
33*b0d29bc4SBrooks Davis
34*b0d29bc4SBrooks Davisnamespace utils {
35*b0d29bc4SBrooks Davis
36*b0d29bc4SBrooks Davis
37*b0d29bc4SBrooks Davisnamespace detail {
38*b0d29bc4SBrooks Davis
39*b0d29bc4SBrooks Davis
40*b0d29bc4SBrooks Davis/// Constructs a new auto_array_ref from a pointer.
41*b0d29bc4SBrooks Davis///
42*b0d29bc4SBrooks Davis/// \param ptr The pointer to wrap.
43*b0d29bc4SBrooks Davistemplate< class T > inline
44*b0d29bc4SBrooks Davisauto_array_ref< T >::auto_array_ref(T* ptr) :
45*b0d29bc4SBrooks Davis    _ptr(ptr)
46*b0d29bc4SBrooks Davis{
47*b0d29bc4SBrooks Davis}
48*b0d29bc4SBrooks Davis
49*b0d29bc4SBrooks Davis
50*b0d29bc4SBrooks Davis}  // namespace detail
51*b0d29bc4SBrooks Davis
52*b0d29bc4SBrooks Davis
53*b0d29bc4SBrooks Davis/// Constructs a new auto_array from a given pointer.
54*b0d29bc4SBrooks Davis///
55*b0d29bc4SBrooks Davis/// This grabs ownership of the pointer unless it is NULL.
56*b0d29bc4SBrooks Davis///
57*b0d29bc4SBrooks Davis/// \param ptr The pointer to wrap.  If not NULL, the memory pointed to must
58*b0d29bc4SBrooks Davis/// have been allocated with operator new[].
59*b0d29bc4SBrooks Davistemplate< class T > inline
60*b0d29bc4SBrooks Davisauto_array< T >::auto_array(T* ptr) throw() :
61*b0d29bc4SBrooks Davis    _ptr(ptr)
62*b0d29bc4SBrooks Davis{
63*b0d29bc4SBrooks Davis}
64*b0d29bc4SBrooks Davis
65*b0d29bc4SBrooks Davis
66*b0d29bc4SBrooks Davis/// Constructs a copy of an auto_array.
67*b0d29bc4SBrooks Davis///
68*b0d29bc4SBrooks Davis/// \param ptr The pointer to copy from.  This pointer is invalidated and the
69*b0d29bc4SBrooks Davis/// new copy grabs ownership of the object pointed to.
70*b0d29bc4SBrooks Davistemplate< class T > inline
71*b0d29bc4SBrooks Davisauto_array< T >::auto_array(auto_array< T >& ptr) throw() :
72*b0d29bc4SBrooks Davis    _ptr(ptr.release())
73*b0d29bc4SBrooks Davis{
74*b0d29bc4SBrooks Davis}
75*b0d29bc4SBrooks Davis
76*b0d29bc4SBrooks Davis
77*b0d29bc4SBrooks Davis/// Constructs a new auto_array form a reference.
78*b0d29bc4SBrooks Davis///
79*b0d29bc4SBrooks Davis/// Internal function used to construct a new auto_array from an object
80*b0d29bc4SBrooks Davis/// returned, for example, from a function.
81*b0d29bc4SBrooks Davis///
82*b0d29bc4SBrooks Davis/// \param ref The reference.
83*b0d29bc4SBrooks Davistemplate< class T > inline
84*b0d29bc4SBrooks Davisauto_array< T >::auto_array(detail::auto_array_ref< T > ref) throw() :
85*b0d29bc4SBrooks Davis    _ptr(ref._ptr)
86*b0d29bc4SBrooks Davis{
87*b0d29bc4SBrooks Davis}
88*b0d29bc4SBrooks Davis
89*b0d29bc4SBrooks Davis
90*b0d29bc4SBrooks Davis/// Destructor for auto_array objects.
91*b0d29bc4SBrooks Davistemplate< class T > inline
92*b0d29bc4SBrooks Davisauto_array< T >::~auto_array(void) throw()
93*b0d29bc4SBrooks Davis{
94*b0d29bc4SBrooks Davis    if (_ptr != NULL)
95*b0d29bc4SBrooks Davis        delete [] _ptr;
96*b0d29bc4SBrooks Davis}
97*b0d29bc4SBrooks Davis
98*b0d29bc4SBrooks Davis
99*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer without releasing ownership.
100*b0d29bc4SBrooks Davis///
101*b0d29bc4SBrooks Davis/// \return The raw mutable pointer.
102*b0d29bc4SBrooks Davistemplate< class T > inline
103*b0d29bc4SBrooks DavisT*
104*b0d29bc4SBrooks Davisauto_array< T >::get(void) throw()
105*b0d29bc4SBrooks Davis{
106*b0d29bc4SBrooks Davis    return _ptr;
107*b0d29bc4SBrooks Davis}
108*b0d29bc4SBrooks Davis
109*b0d29bc4SBrooks Davis
110*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer without releasing ownership.
111*b0d29bc4SBrooks Davis///
112*b0d29bc4SBrooks Davis/// \return The raw immutable pointer.
113*b0d29bc4SBrooks Davistemplate< class T > inline
114*b0d29bc4SBrooks Davisconst T*
115*b0d29bc4SBrooks Davisauto_array< T >::get(void) const throw()
116*b0d29bc4SBrooks Davis{
117*b0d29bc4SBrooks Davis    return _ptr;
118*b0d29bc4SBrooks Davis}
119*b0d29bc4SBrooks Davis
120*b0d29bc4SBrooks Davis
121*b0d29bc4SBrooks Davis/// Gets the value of the wrapped pointer and releases ownership.
122*b0d29bc4SBrooks Davis///
123*b0d29bc4SBrooks Davis/// \return The raw mutable pointer.
124*b0d29bc4SBrooks Davistemplate< class T > inline
125*b0d29bc4SBrooks DavisT*
126*b0d29bc4SBrooks Davisauto_array< T >::release(void) throw()
127*b0d29bc4SBrooks Davis{
128*b0d29bc4SBrooks Davis    T* ptr = _ptr;
129*b0d29bc4SBrooks Davis    _ptr = NULL;
130*b0d29bc4SBrooks Davis    return ptr;
131*b0d29bc4SBrooks Davis}
132*b0d29bc4SBrooks Davis
133*b0d29bc4SBrooks Davis
134*b0d29bc4SBrooks Davis/// Changes the value of the wrapped pointer.
135*b0d29bc4SBrooks Davis///
136*b0d29bc4SBrooks Davis/// If the auto_array was pointing to an array, such array is released and the
137*b0d29bc4SBrooks Davis/// wrapped pointer is replaced with the new pointer provided.
138*b0d29bc4SBrooks Davis///
139*b0d29bc4SBrooks Davis/// \param ptr The pointer to use as a replacement; may be NULL.
140*b0d29bc4SBrooks Davistemplate< class T > inline
141*b0d29bc4SBrooks Davisvoid
142*b0d29bc4SBrooks Davisauto_array< T >::reset(T* ptr) throw()
143*b0d29bc4SBrooks Davis{
144*b0d29bc4SBrooks Davis    if (_ptr != NULL)
145*b0d29bc4SBrooks Davis        delete [] _ptr;
146*b0d29bc4SBrooks Davis    _ptr = ptr;
147*b0d29bc4SBrooks Davis}
148*b0d29bc4SBrooks Davis
149*b0d29bc4SBrooks Davis
150*b0d29bc4SBrooks Davis/// Assignment operator.
151*b0d29bc4SBrooks Davis///
152*b0d29bc4SBrooks Davis/// \param ptr The object to copy from.  This is invalidated after the copy.
153*b0d29bc4SBrooks Davis/// \return A reference to the auto_array object itself.
154*b0d29bc4SBrooks Davistemplate< class T > inline
155*b0d29bc4SBrooks Davisauto_array< T >&
156*b0d29bc4SBrooks Davisauto_array< T >::operator=(auto_array< T >& ptr) throw()
157*b0d29bc4SBrooks Davis{
158*b0d29bc4SBrooks Davis    reset(ptr.release());
159*b0d29bc4SBrooks Davis    return *this;
160*b0d29bc4SBrooks Davis}
161*b0d29bc4SBrooks Davis
162*b0d29bc4SBrooks Davis
163*b0d29bc4SBrooks Davis/// Internal assignment operator for function returns.
164*b0d29bc4SBrooks Davis///
165*b0d29bc4SBrooks Davis/// \param ref The reference object to copy from.
166*b0d29bc4SBrooks Davis/// \return A reference to the auto_array object itself.
167*b0d29bc4SBrooks Davistemplate< class T > inline
168*b0d29bc4SBrooks Davisauto_array< T >&
169*b0d29bc4SBrooks Davisauto_array< T >::operator=(detail::auto_array_ref< T > ref) throw()
170*b0d29bc4SBrooks Davis{
171*b0d29bc4SBrooks Davis    if (_ptr != ref._ptr) {
172*b0d29bc4SBrooks Davis        delete [] _ptr;
173*b0d29bc4SBrooks Davis        _ptr = ref._ptr;
174*b0d29bc4SBrooks Davis    }
175*b0d29bc4SBrooks Davis    return *this;
176*b0d29bc4SBrooks Davis}
177*b0d29bc4SBrooks Davis
178*b0d29bc4SBrooks Davis
179*b0d29bc4SBrooks Davis/// Subscript operator to access the array by position.
180*b0d29bc4SBrooks Davis///
181*b0d29bc4SBrooks Davis/// This does not perform any bounds checking, in particular because auto_array
182*b0d29bc4SBrooks Davis/// does not know the size of the arrays pointed to by it.
183*b0d29bc4SBrooks Davis///
184*b0d29bc4SBrooks Davis/// \param pos The position to access, indexed from zero.
185*b0d29bc4SBrooks Davis///
186*b0d29bc4SBrooks Davis/// \return A mutable reference to the element at the specified position.
187*b0d29bc4SBrooks Davistemplate< class T > inline
188*b0d29bc4SBrooks DavisT&
189*b0d29bc4SBrooks Davisauto_array< T >::operator[](int pos) throw()
190*b0d29bc4SBrooks Davis{
191*b0d29bc4SBrooks Davis    return _ptr[pos];
192*b0d29bc4SBrooks Davis}
193*b0d29bc4SBrooks Davis
194*b0d29bc4SBrooks Davis
195*b0d29bc4SBrooks Davis/// Subscript operator to access the array by position.
196*b0d29bc4SBrooks Davis///
197*b0d29bc4SBrooks Davis/// This does not perform any bounds checking, in particular because auto_array
198*b0d29bc4SBrooks Davis/// does not know the size of the arrays pointed to by it.
199*b0d29bc4SBrooks Davis///
200*b0d29bc4SBrooks Davis/// \param pos The position to access, indexed from zero.
201*b0d29bc4SBrooks Davis///
202*b0d29bc4SBrooks Davis/// \return An immutable reference to the element at the specified position.
203*b0d29bc4SBrooks Davistemplate< class T > inline
204*b0d29bc4SBrooks Davisconst T&
205*b0d29bc4SBrooks Davisauto_array< T >::operator[](int pos) const throw()
206*b0d29bc4SBrooks Davis{
207*b0d29bc4SBrooks Davis    return _ptr[pos];
208*b0d29bc4SBrooks Davis}
209*b0d29bc4SBrooks Davis
210*b0d29bc4SBrooks Davis
211*b0d29bc4SBrooks Davis/// Internal conversion to a reference wrapper.
212*b0d29bc4SBrooks Davis///
213*b0d29bc4SBrooks Davis/// This is used internally to support returning auto_array objects from
214*b0d29bc4SBrooks Davis/// functions.  The auto_array is invalidated when used.
215*b0d29bc4SBrooks Davis///
216*b0d29bc4SBrooks Davis/// \return A new detail::auto_array_ref object holding the pointer.
217*b0d29bc4SBrooks Davistemplate< class T > inline
218*b0d29bc4SBrooks Davisauto_array< T >::operator detail::auto_array_ref< T >(void) throw()
219*b0d29bc4SBrooks Davis{
220*b0d29bc4SBrooks Davis    return detail::auto_array_ref< T >(release());
221*b0d29bc4SBrooks Davis}
222*b0d29bc4SBrooks Davis
223*b0d29bc4SBrooks Davis
224*b0d29bc4SBrooks Davis}  // namespace utils
225*b0d29bc4SBrooks Davis
226*b0d29bc4SBrooks Davis
227*b0d29bc4SBrooks Davis#endif  // !defined(UTILS_AUTO_ARRAY_IPP)
228