blob: 38dc8d571ce11a2fdf84cae41ee208bc95252420 [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/**@file Simplified Vector template with aliases. */
2/*
3* Copyright 2008 Free Software Foundation, Inc.
4*
5* This software is distributed under the terms of the GNU Affero Public License.
6* See the COPYING file in the main directory for details.
7*
8* This use of this software may be subject to additional restrictions.
9* See the LEGAL file in the main directory for details.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Affero General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Affero General Public License for more details.
20
21 You should have received a copy of the GNU Affero General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24*/
25
26
27
28
29#ifndef VECTOR_H
30#define VECTOR_H
31
32#include <string.h>
33#include <iostream>
34#include <assert.h>
kurtis.heimerl5a872472013-05-31 21:47:25 +000035// We cant use Logger.h in this file...
36extern int gVectorDebug;
37#define BVDEBUG(msg) if (gVectorDebug) {std::cout << msg;}
38
dburgess82c46ff2011-10-07 02:40:51 +000039
40
41/**
42 A simplified Vector template with aliases.
43 Unlike std::vector, this class does not support dynamic resizing.
44 Unlike std::vector, this class does support "aliases" and subvectors.
45*/
46template <class T> class Vector {
47
48 // TODO -- Replace memcpy calls with for-loops.
49
50 public:
51
52 /**@name Iterator types. */
53 //@{
54 typedef T* iterator;
55 typedef const T* const_iterator;
56 //@}
57
58 protected:
59
60 T* mData; ///< allocated data block, if any
61 T* mStart; ///< start of useful data
62 T* mEnd; ///< end of useful data + 1
63
64 public:
65
kurtis.heimerl5a872472013-05-31 21:47:25 +000066 /****
67 char *inspect() {
68 static char buf[100];
69 sprintf(buf," mData=%p mStart=%p mEnd=%p ",mData,mStart,mEnd);
70 return buf;
71 }
72 ***/
73
dburgess82c46ff2011-10-07 02:40:51 +000074 /** Return the size of the Vector. */
75 size_t size() const
76 {
77 assert(mStart>=mData);
78 assert(mEnd>=mStart);
79 return mEnd - mStart;
80 }
81
82 /** Return size in bytes. */
83 size_t bytes() const { return size()*sizeof(T); }
84
85 /** Change the size of the Vector, discarding content. */
86 void resize(size_t newSize)
87 {
88 if (mData!=NULL) delete[] mData;
89 if (newSize==0) mData=NULL;
90 else mData = new T[newSize];
91 mStart = mData;
92 mEnd = mStart + newSize;
93 }
94
95 /** Release memory and clear pointers. */
96 void clear() { resize(0); }
97
98
99 /** Copy data from another vector. */
100 void clone(const Vector<T>& other)
101 {
102 resize(other.size());
103 memcpy(mData,other.mStart,other.bytes());
104 }
105
106
107
108
109 //@{
110
111 /** Build an empty Vector of a given size. */
112 Vector(size_t wSize=0):mData(NULL) { resize(wSize); }
113
114 /** Build a Vector by shifting the data block. */
115 Vector(Vector<T>& other)
116 :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd)
117 { other.mData=NULL; }
118
119 /** Build a Vector by copying another. */
120 Vector(const Vector<T>& other):mData(NULL) { clone(other); }
121
122 /** Build a Vector with explicit values. */
123 Vector(T* wData, T* wStart, T* wEnd)
124 :mData(wData),mStart(wStart),mEnd(wEnd)
125 { }
126
127 /** Build a vector from an existing block, NOT to be deleted upon destruction. */
128 Vector(T* wStart, size_t span)
129 :mData(NULL),mStart(wStart),mEnd(wStart+span)
130 { }
131
132 /** Build a Vector by concatenation. */
133 Vector(const Vector<T>& other1, const Vector<T>& other2)
134 :mData(NULL)
135 {
136 resize(other1.size()+other2.size());
137 memcpy(mStart, other1.mStart, other1.bytes());
138 memcpy(mStart+other1.size(), other2.mStart, other2.bytes());
139 }
140
141 //@}
142
143 /** Destroy a Vector, deleting held memory. */
144 ~Vector() { clear(); }
145
146
147
148
149 //@{
150
151 /** Assign from another Vector, shifting ownership. */
152 void operator=(Vector<T>& other)
153 {
154 clear();
155 mData=other.mData;
156 mStart=other.mStart;
157 mEnd=other.mEnd;
158 other.mData=NULL;
159 }
160
161 /** Assign from another Vector, copying. */
162 void operator=(const Vector<T>& other) { clone(other); }
163
164 //@}
165
166
167 //@{
168
169 /** Return an alias to a segment of this Vector. */
170 Vector<T> segment(size_t start, size_t span)
171 {
172 T* wStart = mStart + start;
173 T* wEnd = wStart + span;
174 assert(wEnd<=mEnd);
175 return Vector<T>(NULL,wStart,wEnd);
176 }
177
178 /** Return an alias to a segment of this Vector. */
179 const Vector<T> segment(size_t start, size_t span) const
180 {
181 T* wStart = mStart + start;
182 T* wEnd = wStart + span;
183 assert(wEnd<=mEnd);
184 return Vector<T>(NULL,wStart,wEnd);
185 }
186
187 Vector<T> head(size_t span) { return segment(0,span); }
188 const Vector<T> head(size_t span) const { return segment(0,span); }
189 Vector<T> tail(size_t start) { return segment(start,size()-start); }
190 const Vector<T> tail(size_t start) const { return segment(start,size()-start); }
191
192 /**
193 Copy part of this Vector to a segment of another Vector.
194 @param other The other vector.
195 @param start The start point in the other vector.
196 @param span The number of elements to copy.
197 */
198 void copyToSegment(Vector<T>& other, size_t start, size_t span) const
199 {
200 T* base = other.mStart + start;
201 assert(base+span<=other.mEnd);
202 assert(mStart+span<=mEnd);
203 memcpy(base,mStart,span*sizeof(T));
204 }
205
206 /** Copy all of this Vector to a segment of another Vector. */
207 void copyToSegment(Vector<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
208
209 void copyTo(Vector<T>& other) const { copyToSegment(other,0,size()); }
210
211 /**
212 Copy a segment of this vector into another.
213 @param other The other vector (to copt into starting at 0.)
214 @param start The start point in this vector.
215 @param span The number of elements to copy.
216 */
217 void segmentCopyTo(Vector<T>& other, size_t start, size_t span) const
218 {
219 const T* base = mStart + start;
220 assert(base+span<=mEnd);
221 assert(other.mStart+span<=other.mEnd);
222 memcpy(other.mStart,base,span*sizeof(T));
223 }
224
225 void fill(const T& val)
226 {
227 T* dp=mStart;
228 while (dp<mEnd) *dp++=val;
229 }
230
231 void fill(const T& val, unsigned start, unsigned length)
232 {
233 T* dp=mStart+start;
234 T* end=dp+length;
235 assert(end<=mEnd);
236 while (dp<end) *dp++=val;
237 }
238
239
240 //@}
241
242
243 //@{
244
245 T& operator[](size_t index)
246 {
247 assert(mStart+index<mEnd);
248 return mStart[index];
249 }
250
251 const T& operator[](size_t index) const
252 {
253 assert(mStart+index<mEnd);
254 return mStart[index];
255 }
256
257 const T* begin() const { return mStart; }
258 T* begin() { return mStart; }
259 const T* end() const { return mEnd; }
260 T* end() { return mEnd; }
kurtis.heimerl5a872472013-05-31 21:47:25 +0000261 bool isOwner() { return !!mData; } // Do we own any memory ourselves?
dburgess82c46ff2011-10-07 02:40:51 +0000262 //@}
263
264
265};
266
267
268
269
270/** Basic print operator for Vector objects. */
271template <class T>
272std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
273{
274 for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
275 return os;
276}
277
278
279
280#endif
281// vim: ts=4 sw=4