blob: 9119683f81433ab2f85b1b3f92a69d9f48c7a181 [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
Alexander Chemerisf0189c42017-03-18 14:08:43 -070095 /** Reduce addressable size of the Vector, keeping content. */
96 void shrink(size_t newSize)
97 {
98 assert(newSize <= mEnd - mStart);
99 mEnd = mStart + newSize;
100 }
101
dburgess82c46ff2011-10-07 02:40:51 +0000102 /** Release memory and clear pointers. */
103 void clear() { resize(0); }
104
105
106 /** Copy data from another vector. */
107 void clone(const Vector<T>& other)
108 {
109 resize(other.size());
Pau Espin Pedrol5e68cde2018-08-30 20:45:14 +0200110 other.copyTo(*this);
dburgess82c46ff2011-10-07 02:40:51 +0000111 }
112
113
114
115
116 //@{
117
118 /** Build an empty Vector of a given size. */
119 Vector(size_t wSize=0):mData(NULL) { resize(wSize); }
120
Tom Tsou87d158c2017-06-16 10:21:16 -0700121 /** Build a Vector by moving another. */
122 Vector(Vector<T>&& other)
dburgess82c46ff2011-10-07 02:40:51 +0000123 :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd)
124 { other.mData=NULL; }
125
126 /** Build a Vector by copying another. */
127 Vector(const Vector<T>& other):mData(NULL) { clone(other); }
128
129 /** Build a Vector with explicit values. */
130 Vector(T* wData, T* wStart, T* wEnd)
131 :mData(wData),mStart(wStart),mEnd(wEnd)
132 { }
133
134 /** Build a vector from an existing block, NOT to be deleted upon destruction. */
135 Vector(T* wStart, size_t span)
136 :mData(NULL),mStart(wStart),mEnd(wStart+span)
137 { }
138
139 /** Build a Vector by concatenation. */
140 Vector(const Vector<T>& other1, const Vector<T>& other2)
141 :mData(NULL)
142 {
143 resize(other1.size()+other2.size());
144 memcpy(mStart, other1.mStart, other1.bytes());
145 memcpy(mStart+other1.size(), other2.mStart, other2.bytes());
146 }
147
148 //@}
149
150 /** Destroy a Vector, deleting held memory. */
151 ~Vector() { clear(); }
152
153
154
155
156 //@{
157
158 /** Assign from another Vector, shifting ownership. */
159 void operator=(Vector<T>& other)
160 {
161 clear();
162 mData=other.mData;
163 mStart=other.mStart;
164 mEnd=other.mEnd;
165 other.mData=NULL;
166 }
167
168 /** Assign from another Vector, copying. */
169 void operator=(const Vector<T>& other) { clone(other); }
170
171 //@}
172
173
174 //@{
175
176 /** Return an alias to a segment of this Vector. */
177 Vector<T> segment(size_t start, size_t span)
178 {
179 T* wStart = mStart + start;
180 T* wEnd = wStart + span;
181 assert(wEnd<=mEnd);
182 return Vector<T>(NULL,wStart,wEnd);
183 }
184
185 /** Return an alias to a segment of this Vector. */
186 const Vector<T> segment(size_t start, size_t span) const
187 {
188 T* wStart = mStart + start;
189 T* wEnd = wStart + span;
190 assert(wEnd<=mEnd);
191 return Vector<T>(NULL,wStart,wEnd);
192 }
193
194 Vector<T> head(size_t span) { return segment(0,span); }
195 const Vector<T> head(size_t span) const { return segment(0,span); }
196 Vector<T> tail(size_t start) { return segment(start,size()-start); }
197 const Vector<T> tail(size_t start) const { return segment(start,size()-start); }
198
199 /**
200 Copy part of this Vector to a segment of another Vector.
201 @param other The other vector.
202 @param start The start point in the other vector.
203 @param span The number of elements to copy.
204 */
205 void copyToSegment(Vector<T>& other, size_t start, size_t span) const
206 {
Pau Espin Pedrole6255532018-08-30 20:55:08 +0200207 unsigned int i;
208 T* dst = other.mStart + start;
209 T* src = mStart;
210 assert(dst+span<=other.mEnd);
dburgess82c46ff2011-10-07 02:40:51 +0000211 assert(mStart+span<=mEnd);
Pau Espin Pedrole6255532018-08-30 20:55:08 +0200212 for (i = 0; i < span; i++, src++, dst++)
213 *dst = *src;
214 /*TODO if not non-trivially copyable type class, optimize:
215 memcpy(dst,mStart,span*sizeof(T)); */
dburgess82c46ff2011-10-07 02:40:51 +0000216 }
217
218 /** Copy all of this Vector to a segment of another Vector. */
219 void copyToSegment(Vector<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
220
221 void copyTo(Vector<T>& other) const { copyToSegment(other,0,size()); }
222
223 /**
224 Copy a segment of this vector into another.
225 @param other The other vector (to copt into starting at 0.)
226 @param start The start point in this vector.
227 @param span The number of elements to copy.
228 */
229 void segmentCopyTo(Vector<T>& other, size_t start, size_t span) const
230 {
231 const T* base = mStart + start;
232 assert(base+span<=mEnd);
233 assert(other.mStart+span<=other.mEnd);
234 memcpy(other.mStart,base,span*sizeof(T));
235 }
236
Alexander Chemerisc7088162017-03-18 13:43:22 -0700237 /**
238 Move (copy) a segment of this vector into a different position in the vector
239 @param from Start point from which to copy.
240 @param to Start point to which to copy.
241 @param span The number of elements to copy.
242 */
243 void segmentMove(size_t from, size_t to, size_t span)
244 {
245 const T* baseFrom = mStart + from;
246 T* baseTo = mStart + to;
247 assert(baseFrom+span<=mEnd);
248 assert(baseTo+span<=mEnd);
249 memmove(baseTo,baseFrom,span*sizeof(T));
250 }
251
dburgess82c46ff2011-10-07 02:40:51 +0000252 void fill(const T& val)
253 {
254 T* dp=mStart;
255 while (dp<mEnd) *dp++=val;
256 }
257
258 void fill(const T& val, unsigned start, unsigned length)
259 {
260 T* dp=mStart+start;
261 T* end=dp+length;
262 assert(end<=mEnd);
263 while (dp<end) *dp++=val;
264 }
265
266
267 //@}
268
269
270 //@{
271
272 T& operator[](size_t index)
273 {
274 assert(mStart+index<mEnd);
275 return mStart[index];
276 }
277
278 const T& operator[](size_t index) const
279 {
280 assert(mStart+index<mEnd);
281 return mStart[index];
282 }
283
284 const T* begin() const { return mStart; }
285 T* begin() { return mStart; }
286 const T* end() const { return mEnd; }
287 T* end() { return mEnd; }
kurtis.heimerl5a872472013-05-31 21:47:25 +0000288 bool isOwner() { return !!mData; } // Do we own any memory ourselves?
dburgess82c46ff2011-10-07 02:40:51 +0000289 //@}
Pau Espin Pedrol21ce05c2018-08-30 20:47:20 +0200290
dburgess82c46ff2011-10-07 02:40:51 +0000291
292};
293
294
295
296
297/** Basic print operator for Vector objects. */
298template <class T>
299std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
300{
301 for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
302 return os;
303}
304
305
306
307#endif
308// vim: ts=4 sw=4