2
// Copyright (C) 1997 - 2007, Paul C. Gregory
4
// Contact: pgregory@aqsis.org
6
// This library is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public
8
// License as published by the Free Software Foundation; either
9
// version 2 of the License, or (at your option) any later version.
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
// General Public License for more details.
16
// You should have received a copy of the GNU General Public
17
// License along with this library; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
* \brief Declare a variable sized buffer class containing an internal
23
* statically-sized array for commonly allocated array sizes.
25
* \author Chris Foster [ chris42f (at) gmail (dot) com ]
28
#ifndef AUTOBUFFER_H_INCLUDED
29
#define AUTOBUFFER_H_INCLUDED
31
#include <aqsis/aqsis.h>
33
#include <boost/scoped_array.hpp>
37
/** \brief Variable size buffer class which allocates on the stack if possible.
39
* Sometimes we want to allocate an array on the program stack, but the size of
40
* that array isn't known at compile time. Unfortunately there is no way to do
41
* this portably in standard C++.
43
* However, there is often a rough bound on the amount of space required and we
44
* can allocate this expected amount on the stack, and fall back to using the
45
* heap if necessary. The CqAutoBuffer class implements this strategy.
47
* This idea has been implemented in other software (undoubtably many times);
48
* stlsoft::auto_buffer one such example and the one from which this class
49
* takes its name. Something like this will probably make its way into boost
52
* Note also that this is a portable approximate replacement for the alloca()
55
* T - type to hold in the buffer
56
* defaultBufSize - Size of the internal buffer allocated with the object
57
* (allocated on the stack whenever the buffer instance itself
58
* is). Any runtime requested sizes which are larger than
59
* this will result in a heap allocation.
61
template<typename T, int defaultBufSize>
65
/** \brief Construct an autobuffer
67
* \param size - size of the array of T.
69
CqAutoBuffer(TqInt size);
71
/** \brief Construct an autobuffer and initialize elements.
73
* \param size - size of the array of T.
74
* \param defaultVal - value to initialalize the buffer with.
76
CqAutoBuffer(TqInt size, const T& defaultVal);
78
/// Array indexing operators
79
T& operator[](TqInt i);
80
const T& operator[](TqInt i) const;
82
/// Get a pointer to the start of the underlying buffer.
86
/// Get the buffer size
89
/// Fixed-size array of the given expected size.
90
T m_defaultBuf[defaultBufSize];
91
/// Heap-allocated array, used if we need more than defaultBufSize of memory.
92
boost::scoped_array<T> m_heapBuf;
93
/// Pointer to the buffer in use.
95
/// Size of the buffer.
101
//==============================================================================
102
// Implementation details
103
//==============================================================================
105
template<typename T, int defaultBufSize>
106
inline CqAutoBuffer<T, defaultBufSize>::CqAutoBuffer(TqInt size)
107
: m_heapBuf(size < defaultBufSize ? 0 : new T[size]),
108
m_buf(size < defaultBufSize ? m_defaultBuf : m_heapBuf.get()),
112
template<typename T, int defaultBufSize>
113
inline CqAutoBuffer<T, defaultBufSize>::CqAutoBuffer(TqInt size, const T& defaultVal)
114
: m_heapBuf(size < defaultBufSize ? 0 : new T[size]),
115
m_buf(size < defaultBufSize ? m_defaultBuf : m_heapBuf.get()),
118
for(TqInt i = 0; i < size; ++i)
119
m_buf[i] = defaultVal;
123
template<typename T, int defaultBufSize>
124
inline T& CqAutoBuffer<T, defaultBufSize>::operator[](TqInt i)
128
template<typename T, int defaultBufSize>
129
inline const T& CqAutoBuffer<T, defaultBufSize>::operator[](TqInt i) const
134
/// Get at the underlying buffer.
135
template<typename T, int defaultBufSize>
136
inline T* CqAutoBuffer<T, defaultBufSize>::get()
140
template<typename T, int defaultBufSize>
141
inline const T* CqAutoBuffer<T, defaultBufSize>::get() const
146
template<typename T, int defaultBufSize>
147
inline TqInt CqAutoBuffer<T, defaultBufSize>::size() const
155
#endif // AUTOBUFFER_H_INCLUDED