IT++ Logo
array.h
Go to the documentation of this file.
1
29#ifndef ARRAY_H
30#define ARRAY_H
31
32#include <itpp/base/itassert.h>
33#include <itpp/base/math/misc.h>
34#include <itpp/base/factory.h>
36
37
38namespace itpp
39{
40
41// Forward declarations
42template<class T> class Array;
44template<class T> const Array<T> concat(const Array<T> &a, const T &e);
46template<class T> const Array<T> concat(const T &e, const Array<T> &a);
48template<class T> const Array<T> concat(const Array<T> &a1,
49 const Array<T> &a2);
51template<class T> const Array<T> concat(const Array<T> &a1,
52 const Array<T> &a2,
53 const Array<T> &a3);
54
103template<class T>
104class Array
105{
106public:
108 explicit Array(const Factory &f = DEFAULT_FACTORY);
110 Array(int n, const Factory &f = DEFAULT_FACTORY);
114 Array(const std::string& values, const Factory &f = DEFAULT_FACTORY);
116 Array(const char* values, const Factory &f = DEFAULT_FACTORY);
117
119 virtual ~Array();
120
122 T &operator()(int i);
124 const T &operator()(int i) const;
126 const Array<T> operator()(int i1, int i2) const;
129
131 Array<T> left(int n) const;
133 Array<T> right(int n) const;
135 Array<T> mid(int pos, int n) const;
136
138 Array<T>& operator=(const T &e);
142 Array<T>& operator=(const char* values);
143
145 friend const Array<T> concat <>(const Array<T> &a1, const T &e);
147 friend const Array<T> concat <>(const T &e, const Array<T> &a);
149 friend const Array<T> concat <>(const Array<T> &a1, const Array<T> &a2);
151 friend const Array<T> concat <>(const Array<T> &a1, const Array<T> &a2,
152 const Array<T> &a3);
153
155 int size() const { return ndata; }
157 int length() const { return ndata; }
159 void set_size(int n, bool copy = false);
161 void set_length(int n, bool copy = false) { set_size(n, copy); }
162
164 T shift_right(const T& e);
168 T shift_left(const T& e);
172 void swap(int i, int j);
173
175 void set_subarray(int i1, int i2, const Array<T> &a);
177 void set_subarray(int i1, int i2, const T &t);
178
179protected:
181 void alloc(int n);
183 void free();
185 bool in_range(int i) const { return ((i < ndata) && (i >= 0)); }
187 int ndata;
192};
193
194// -------------------- Implementation starts here --------------------
195
196template<class T> inline
198{
199 if (n > 0) {
201 ndata = n;
202 }
203 else {
204 data = 0;
205 ndata = 0;
206 }
207}
208
209template<class T> inline
211{
213 ndata = 0;
214}
215
216template<class T> inline
217Array<T>::Array(const Factory &f) : ndata(0), data(0), factory(f) {}
218
219template<class T> inline
220Array<T>::Array(const int n, const Factory &f) : ndata(0), data(0), factory(f)
221{
222 alloc(n);
223}
224
225template<class T> inline
227 : ndata(0), data(0), factory(f)
228{
229 alloc(a.ndata);
230 for (int i = 0; i < a.ndata; i++)
231 data[i] = a.data[i];
232}
233
234template<class T> inline
235Array<T>::Array(const std::string& values, const Factory &f)
236 : ndata(0), data(0), factory(f)
237{
238 std::istringstream buffer(values);
239 buffer >> *this;
240}
241
242template<class T> inline
243Array<T>::Array(const char* values, const Factory &f)
244 : ndata(0), data(0), factory(f)
245{
246 std::istringstream buffer(values);
247 buffer >> *this;
248}
249
250template<class T>
252{
253 free();
254}
255
256template<class T>
258{
259 it_assert_debug(size >= 0, "Array::set_size(): New size must not be negative");
260 if (ndata == size)
261 return;
262 if (copy) {
263 // create a temporary pointer to the allocated data
264 T* tmp = data;
265 // store the current number of elements
266 int old_ndata = ndata;
267 // check how many elements we need to copy
268 int min = (ndata < size) ? ndata : size;
269 // allocate new memory
270 alloc(size);
271 // copy old elements into a new memory region
272 for (int i = 0; i < min; ++i) {
273 data[i] = tmp[i];
274 }
275 // initialize the rest of resized array
276 for (int i = min; i < size; ++i) {
277 data[i] = T();
278 }
279 // delete old elements
281 }
282 else {
283 free();
284 alloc(size);
285 }
286}
287
288
289template<class T> inline
291{
292 it_assert_debug(in_range(i), "Array::operator(): Improper index");
293 return data[i];
294}
295
296template<class T> inline
297const T& Array<T>::operator()(int i) const
298{
299 it_assert_debug(in_range(i), "Array::operator(): Improper index");
300 return data[i];
301}
302
303template<class T> inline
304const Array<T> Array<T>::operator()(int i1, int i2) const
305{
307 "Array::operator()(i1, i2): Improper indexes.");
308 Array<T> s(i2 - i1 + 1);
309 for (int i = 0; i < s.ndata; i++)
310 s.data[i] = data[i1+i];
311 return s;
312}
313
314template<class T> inline
316{
318 for (int i = 0; i < a.size(); i++) {
320 "Array::operator()(indices): Improper indices.");
321 a(i) = data[indices(i)];
322 }
323 return a;
324}
325
326template<class T> inline
328{
329 if (this != &a) {
331 for (int i = 0; i < ndata; i++)
332 data[i] = a.data[i];
333 }
334 return *this;
335}
336
337template<class T> inline
339{
340 if (ndata == 0)
341 set_size(1);
342 for (int i = 0; i < ndata; i++)
343 data[i] = e;
344 return *this;
345}
346
347template<class T>
349{
350 std::istringstream buffer(values);
351 buffer >> *this;
352 return *this;
353}
354
355
356template<class T>
358{
359 it_assert_debug(in_range(n), "Array::left(): Index out of range");
360 Array<T> tmp(n);
361 for (int i = 0; i < n; ++i)
362 tmp.data[i] = data[i];
363 return tmp;
364}
365
366template<class T>
368{
369 it_assert_debug(in_range(n), "Array::right(): Index out of range");
370 Array<T> tmp(n);
371 for (int i = 0; i < n; ++i)
372 tmp.data[i] = data[ndata-n+i];
373 return tmp;
374}
375
376template<class T>
377Array<T> Array<T>::mid(int pos, int n) const
378{
379 it_assert_debug((pos >= 0) && (n > 0) && (pos + n <= ndata), "Array::mid(): Indexing out of range");
380 Array<T> tmp(n);
381 for (int i = 0; i < n; ++i)
382 tmp.data[i] = data[pos+i];
383 return tmp;
384}
385
386
387template<class T>
389{
390 it_assert_debug(ndata > 0, "Array::shift_right(x): Array empty!");
391 T ret;
392
393 ret = data[ndata-1];
394 for (int i = ndata - 1; i > 0; i--)
395 data[i] = data[i-1];
396 data[0] = x;
397
398 return ret;
399}
400
401
402template<class T>
404{
405 it_assert_debug(a.ndata <= ndata, "Array::shift_right(): Shift Array too large");
407
408 for (int i = 0; i < a.ndata; i++)
409 out.data[i] = data[ndata-a.ndata+i];
410 for (int i = ndata - 1; i >= a.ndata; i--)
411 data[i] = data[i-a.ndata];
412 for (int i = 0; i < a.ndata; i++)
413 data[i] = a.data[i];
414
415 return out;
416}
417
418template<class T>
420{
421 T temp = data[0];
422
423 for (int i = 0; i < ndata - 1; i++)
424 data[i] = data[i+1];
425 data[ndata-1] = x;
426
427 return temp;
428}
429
430template<class T>
432{
433 it_assert_debug(a.ndata <= ndata, "Array::shift_left(): Shift Array too large");
435
436 for (int i = 0; i < a.ndata; i++)
437 out.data[i] = data[i];
438 for (int i = 0; i < ndata - a.ndata; i++)
439 data[i] = data[i+a.ndata];
440 for (int i = ndata - a.ndata; i < ndata; i++)
441 data[i] = a.data[i-ndata+a.ndata];
442
443 return out;
444}
445
446template<class T>
447void Array<T>::swap(int i, int j)
448{
450 "Array::swap(): Indices out of range.");
451
452 T temp = data[i];
453 data[i] = data[j];
454 data[j] = temp;
455}
456
457template<class T>
458void Array<T>::set_subarray(int i1, int i2, const Array<T> &a)
459{
460 if (i1 == -1) i1 = ndata - 1;
461 if (i2 == -1) i2 = ndata - 1;
462
464 "Array<T>::set_subarray(): Indices out of range.");
465 it_assert_debug(i2 >= i1, "Array<T>::set_subarray(): i2 >= i1 necessary.");
466 it_assert_debug(i2 - i1 + 1 == a.ndata, "Array<T>::set_subarray(): Wrong sizes.");
467
468 copy_vector(a.ndata, a.data, data + i1);
469}
470
471template<class T>
472void Array<T>::set_subarray(int i1, int i2, const T &t)
473{
474 if (i1 == -1) i1 = ndata - 1;
475 if (i2 == -1) i2 = ndata - 1;
476
478 "Array<T>::set_subarray(): Indices out of range");
479 it_assert_debug(i2 >= i1, "Array<T>::set_subarray(): i2 >= i1 necessary");
480
481 for (int i = i1; i <= i2; i++)
482 data[i] = t;
483}
484
485template<class T>
486const Array<T> concat(const Array<T> &a, const T &e)
487{
488 Array<T> temp(a.size() + 1);
489
490 for (int i = 0; i < a.size(); i++)
491 temp(i) = a(i);
492 temp(a.size()) = e;
493
494 return temp;
495}
496
497template<class T>
498const Array<T> concat(const T &e, const Array<T> &a)
499{
500 Array<T> temp(a.size() + 1);
501
502 temp(0) = e;
503
504 for (int i = 0; i < a.size(); i++)
505 temp(i + 1) = a(i);
506
507 return temp;
508}
509
510template<class T>
511const Array<T> concat(const Array<T> &a1, const Array<T> &a2)
512{
513 Array<T> temp(a1.size() + a2.size());
514
515 for (int i = 0; i < a1.size(); i++)
516 temp(i) = a1(i);
517 for (int i = 0; i < a2.size(); i++)
518 temp(a1.size() + i) = a2(i);
519
520 return temp;
521}
522
523template<class T>
524const Array<T> concat(const Array<T> &a1, const Array<T> &a2,
525 const Array<T> &a3)
526{
527 // There should be some error control?
528 Array<T> temp(a1.size() + a2.size() + a3.size());
529
530 for (int i = 0; i < a1.size(); i++)
531 temp(i) = a1(i);
532 for (int i = 0; i < a2.size(); i++)
533 temp(a1.size() + i) = a2(i);
534 for (int i = 0; i < a3.size(); i++)
535 temp(a1.size() + a2.size() + i) = a3(i);
536
537 return temp;
538}
539
544template<class T>
545std::ostream &operator<<(std::ostream &os, const Array<T> &a)
546{
547 os << "{";
548 for (int i = 0; i < a.size() - 1; i++)
549 os << a(i) << " ";
550 if (a.size() > 0)
551 os << a(a.size() - 1);
552 os << "}";
553
554 return os;
555}
556
561template<class T>
562std::istream &operator>>(std::istream &is, Array<T> &a)
563{
564 int nrof_elements = 0;
565 char c;
566 is >> c;
567 if (c == '{') {
568 is >> c;
569 while (c != '}') {
570 if (is.eof()) {
571 is.setstate(std::ios_base::failbit);
572 break;
573 }
574 if (c != ',') { // Discard comma signs between elements
575 is.putback(c);
576 }
577 if (++nrof_elements > a.size()) {
578 a.set_size(nrof_elements, true); // Too slow?
579 }
580 is >> a(nrof_elements - 1);
581 is >> c;
582 }
583 if (a.size() > nrof_elements) {
584 a.set_size(nrof_elements, true);
585 }
586 }
587 else {
588 is.setstate(std::ios_base::failbit);
589 }
590
591 return is;
592}
593
599template<class T>
600void set_array(Array<T> &a, const char *values)
601{
602 std::istringstream buffer(values);
603 buffer >> a;
604}
605
611template<class T>
612void set_array(Array<T> &a, const std::string &str)
613{
614 set_array(a, str.c_str());
615}
616
617} // namespace itpp
618
619#endif // #ifndef ARRAY_H
General array class.
Definition array.h:105
void alloc(int n)
Allocate storage for an array of length n.
Definition array.h:197
Array< T > mid(int pos, int n) const
Get n elements of the array starting from pos.
Definition array.h:377
Array(int n, const Factory &f=DEFAULT_FACTORY)
Create an Array of size n. An element factory f can be specified.
Definition array.h:220
void set_array(Array< T > &a, const char *values)
Assign a C-style string to an Array<T>. T must have istream operator>> defined.
Definition array.h:600
bool in_range(int i) const
Check whether index i is in the allowed range.
Definition array.h:185
void free()
Free the storage space allocated by the array.
Definition array.h:210
void set_length(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:161
int size() const
Returns the number of data elements in the array object.
Definition array.h:155
Array< T > & operator=(const Array< T > &a)
Assignment operator.
Definition array.h:327
Array(const Array< T > &a, const Factory &f=DEFAULT_FACTORY)
Copy constructor. An element factory f can be specified.
Definition array.h:226
void set_array(Array< T > &a, const std::string &str)
Assign a string to an Array<T>. T must have istream operator>> defined.
Definition array.h:612
int ndata
The current number of elements in the Array.
Definition array.h:187
const T & operator()(int i) const
Get the i element.
Definition array.h:297
Array< T > & operator=(const T &e)
Assignment operator.
Definition array.h:338
void swap(int i, int j)
Swap elements i and j.
Definition array.h:447
void set_subarray(int i1, int i2, const Array< T > &a)
Set the subarray defined by indicies i1 to i2 to Array<T> a.
Definition array.h:458
const Factory & factory
Element factory (by default set to DEFAULT_FACTORY)
Definition array.h:191
Array< T > left(int n) const
Get n left elements of the array.
Definition array.h:357
Array(const Factory &f=DEFAULT_FACTORY)
Default constructor. An element factory f can be specified.
Definition array.h:217
T shift_left(const T &e)
Shift in data at the last position. Return data from position 0.
Definition array.h:419
virtual ~Array()
Destructor.
Definition array.h:251
Array(const char *values, const Factory &f=DEFAULT_FACTORY)
Create an Array from char*. An element factory f can be specified.
Definition array.h:243
T shift_right(const T &e)
Shift in data at position 0. Return data from the last position.
Definition array.h:388
const Array< T > shift_right(const Array< T > &a)
Shift in array at position 0. Return data from the last position.
Definition array.h:403
std::istream & operator>>(std::istream &is, Array< T > &a)
Input stream for Array<T>. T must have istream operator>> defined.
Definition array.h:562
const Array< T > operator()(const Array< int > &indices) const
Sub-array with the elements given by the integer Array.
Definition array.h:315
const Array< T > shift_left(const Array< T > &a)
Shift in array at the last position. Return data from position 0.
Definition array.h:431
void set_subarray(int i1, int i2, const T &t)
Set the subarray defined by indicies i1 to i2 the element value t.
Definition array.h:472
const Array< T > operator()(int i1, int i2) const
Sub-array from element i1 to element i2.
Definition array.h:304
T & operator()(int i)
Get the i element.
Definition array.h:290
Array< T > & operator=(const char *values)
Assignment operator.
Definition array.h:348
std::ostream & operator<<(std::ostream &os, const Array< T > &a)
Output stream for Array<T>. T must have ostream operator<< defined.
Definition array.h:545
Array(const std::string &values, const Factory &f=DEFAULT_FACTORY)
Create an Array from string. An element factory f can be specified.
Definition array.h:235
T * data
A pointer to the data area.
Definition array.h:189
void set_size(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:257
int length() const
Returns the number of data elements in the array object.
Definition array.h:157
Array< T > right(int n) const
Get n right elements of the array.
Definition array.h:367
Base class for class factories.
Definition factory.h:130
Vector copy functions for internal use.
Base class for class factories and memory allocation functions.
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition itassert.h:107
int size(const Vec< T > &v)
Length of vector.
Definition matfunc.h:55
T min(const Vec< T > &in)
Minimum value of vector.
Definition min_max.h:125
Error handling functions - header file.
Miscellaneous functions - header file.
itpp namespace
Definition itmex.h:37
const Array< T > concat(const Array< T > &a, const T &e)
Append element e to the end of the Array a.
Definition array.h:486
void destroy_elements(T *&ptr, int n)
Destroy an array of Array, Vec or Mat elements.
Definition factory.h:214
const Factory DEFAULT_FACTORY
Default (dummy) factory.
Definition factory.h:139
void create_elements(T *&ptr, int n, const Factory &)
Create an n-length array of T to be used as Array, Vec or Mat elements.
Definition factory.h:144
SourceForge Logo

Generated on Mon Jun 10 2024 11:49:16 for IT++ by Doxygen 1.9.8