blob: 62cb6fb85a667259a20e58e84f89e83f9d6fe9a5 [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>
35
36
37/**
38 A simplified Vector template with aliases.
39 Unlike std::vector, this class does not support dynamic resizing.
40 Unlike std::vector, this class does support "aliases" and subvectors.
41*/
42template <class T> class Vector {
43
44 // TODO -- Replace memcpy calls with for-loops.
45
46 public:
47
48 /**@name Iterator types. */
49 //@{
50 typedef T* iterator;
51 typedef const T* const_iterator;
52 //@}
53
54 protected:
55
56 T* mData; ///< allocated data block, if any
57 T* mStart; ///< start of useful data
58 T* mEnd; ///< end of useful data + 1
59
60 public:
61
62 /** Return the size of the Vector. */
63 size_t size() const
64 {
65 assert(mStart>=mData);
66 assert(mEnd>=mStart);
67 return mEnd - mStart;
68 }
69
70 /** Return size in bytes. */
71 size_t bytes() const { return size()*sizeof(T); }
72
73 /** Change the size of the Vector, discarding content. */
74 void resize(size_t newSize)
75 {
76 if (mData!=NULL) delete[] mData;
77 if (newSize==0) mData=NULL;
78 else mData = new T[newSize];
79 mStart = mData;
80 mEnd = mStart + newSize;
81 }
82
83 /** Release memory and clear pointers. */
84 void clear() { resize(0); }
85
86
87 /** Copy data from another vector. */
88 void clone(const Vector<T>& other)
89 {
90 resize(other.size());
91 memcpy(mData,other.mStart,other.bytes());
92 }
93
94
95
96
97 //@{
98
99 /** Build an empty Vector of a given size. */
100 Vector(size_t wSize=0):mData(NULL) { resize(wSize); }
101
102 /** Build a Vector by shifting the data block. */
103 Vector(Vector<T>& other)
104 :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd)
105 { other.mData=NULL; }
106
107 /** Build a Vector by copying another. */
108 Vector(const Vector<T>& other):mData(NULL) { clone(other); }
109
110 /** Build a Vector with explicit values. */
111 Vector(T* wData, T* wStart, T* wEnd)
112 :mData(wData),mStart(wStart),mEnd(wEnd)
113 { }
114
115 /** Build a vector from an existing block, NOT to be deleted upon destruction. */
116 Vector(T* wStart, size_t span)
117 :mData(NULL),mStart(wStart),mEnd(wStart+span)
118 { }
119
120 /** Build a Vector by concatenation. */
121 Vector(const Vector<T>& other1, const Vector<T>& other2)
122 :mData(NULL)
123 {
124 resize(other1.size()+other2.size());
125 memcpy(mStart, other1.mStart, other1.bytes());
126 memcpy(mStart+other1.size(), other2.mStart, other2.bytes());
127 }
128
129 //@}
130
131 /** Destroy a Vector, deleting held memory. */
132 ~Vector() { clear(); }
133
134
135
136
137 //@{
138
139 /** Assign from another Vector, shifting ownership. */
140 void operator=(Vector<T>& other)
141 {
142 clear();
143 mData=other.mData;
144 mStart=other.mStart;
145 mEnd=other.mEnd;
146 other.mData=NULL;
147 }
148
149 /** Assign from another Vector, copying. */
150 void operator=(const Vector<T>& other) { clone(other); }
151
152 //@}
153
154
155 //@{
156
157 /** Return an alias to a segment of this Vector. */
158 Vector<T> segment(size_t start, size_t span)
159 {
160 T* wStart = mStart + start;
161 T* wEnd = wStart + span;
162 assert(wEnd<=mEnd);
163 return Vector<T>(NULL,wStart,wEnd);
164 }
165
166 /** Return an alias to a segment of this Vector. */
167 const Vector<T> segment(size_t start, size_t span) const
168 {
169 T* wStart = mStart + start;
170 T* wEnd = wStart + span;
171 assert(wEnd<=mEnd);
172 return Vector<T>(NULL,wStart,wEnd);
173 }
174
175 Vector<T> head(size_t span) { return segment(0,span); }
176 const Vector<T> head(size_t span) const { return segment(0,span); }
177 Vector<T> tail(size_t start) { return segment(start,size()-start); }
178 const Vector<T> tail(size_t start) const { return segment(start,size()-start); }
179
180 /**
181 Copy part of this Vector to a segment of another Vector.
182 @param other The other vector.
183 @param start The start point in the other vector.
184 @param span The number of elements to copy.
185 */
186 void copyToSegment(Vector<T>& other, size_t start, size_t span) const
187 {
188 T* base = other.mStart + start;
189 assert(base+span<=other.mEnd);
190 assert(mStart+span<=mEnd);
191 memcpy(base,mStart,span*sizeof(T));
192 }
193
194 /** Copy all of this Vector to a segment of another Vector. */
195 void copyToSegment(Vector<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
196
197 void copyTo(Vector<T>& other) const { copyToSegment(other,0,size()); }
198
199 /**
200 Copy a segment of this vector into another.
201 @param other The other vector (to copt into starting at 0.)
202 @param start The start point in this vector.
203 @param span The number of elements to copy.
204 */
205 void segmentCopyTo(Vector<T>& other, size_t start, size_t span) const
206 {
207 const T* base = mStart + start;
208 assert(base+span<=mEnd);
209 assert(other.mStart+span<=other.mEnd);
210 memcpy(other.mStart,base,span*sizeof(T));
211 }
212
213 void fill(const T& val)
214 {
215 T* dp=mStart;
216 while (dp<mEnd) *dp++=val;
217 }
218
219 void fill(const T& val, unsigned start, unsigned length)
220 {
221 T* dp=mStart+start;
222 T* end=dp+length;
223 assert(end<=mEnd);
224 while (dp<end) *dp++=val;
225 }
226
227
228 //@}
229
230
231 //@{
232
233 T& operator[](size_t index)
234 {
235 assert(mStart+index<mEnd);
236 return mStart[index];
237 }
238
239 const T& operator[](size_t index) const
240 {
241 assert(mStart+index<mEnd);
242 return mStart[index];
243 }
244
245 const T* begin() const { return mStart; }
246 T* begin() { return mStart; }
247 const T* end() const { return mEnd; }
248 T* end() { return mEnd; }
249 //@}
250
251
252};
253
254
255
256
257/** Basic print operator for Vector objects. */
258template <class T>
259std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
260{
261 for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
262 return os;
263}
264
265
266
267#endif
268// vim: ts=4 sw=4