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