array.h
Go to the documentation of this file.
#ifndef ARRAY_H
#define ARRAY_H
#include <itpp/base/itassert.h>
#include <itpp/base/math/misc.h>
#include <itpp/base/factory.h>
#include <itpp/base/copy_vector.h>
namespace itpp
{
// Forward declarations
template<class T> class Array;
template<class T> const Array<T> concat(const Array<T> &a, const T &e);
template<class T> const Array<T> concat(const T &e, const Array<T> &a);
template<class T> const Array<T> concat(const Array<T> &a1,
const Array<T> &a2);
template<class T> const Array<T> concat(const Array<T> &a1,
const Array<T> &a2,
const Array<T> &a3);
template<class T>
class Array
{
public:
explicit Array(const Factory &f = DEFAULT_FACTORY);
Array(int n, const Factory &f = DEFAULT_FACTORY);
Array(const Array<T> &a, const Factory &f = DEFAULT_FACTORY);
Array(const std::string& values, const Factory &f = DEFAULT_FACTORY);
Array(const char* values, const Factory &f = DEFAULT_FACTORY);
virtual ~Array();
T &operator()(int i);
const T &operator()(int i) const;
const Array<T> operator()(int i1, int i2) const;
const Array<T> operator()(const Array<int> &indices) const;
Array<T> left(int n) const;
Array<T> right(int n) const;
Array<T> mid(int pos, int n) const;
Array<T>& operator=(const T &e);
Array<T>& operator=(const Array<T> &a);
Array<T>& operator=(const char* values);
friend const Array<T> concat <>(const Array<T> &a1, const T &e);
friend const Array<T> concat <>(const T &e, const Array<T> &a);
friend const Array<T> concat <>(const Array<T> &a1, const Array<T> &a2);
friend const Array<T> concat <>(const Array<T> &a1, const Array<T> &a2,
const Array<T> &a3);
int size() const { return ndata; }
int length() const { return ndata; }
void set_size(int n, bool copy = false);
void set_length(int n, bool copy = false) { set_size(n, copy); }
T shift_right(const T& e);
const Array<T> shift_right(const Array<T> &a);
T shift_left(const T& e);
const Array<T> shift_left(const Array<T> &a);
void swap(int i, int j);
void set_subarray(int i1, int i2, const Array<T> &a);
void set_subarray(int i1, int i2, const T &t);
protected:
void alloc(int n);
void free();
bool in_range(int i) const { return ((i < ndata) && (i >= 0)); }
int ndata;
T *data;
const Factory &factory;
};
// -------------------- Implementation starts here --------------------
template<class T> inline
void Array<T>::alloc(int n)
{
if (n > 0) {
create_elements(data, n, factory);
ndata = n;
}
else {
data = 0;
ndata = 0;
}
}
template<class T> inline
void Array<T>::free()
{
destroy_elements(data, ndata);
ndata = 0;
}
template<class T> inline
Array<T>::Array(const Factory &f) : ndata(0), data(0), factory(f) {}
template<class T> inline
Array<T>::Array(const int n, const Factory &f) : ndata(0), data(0), factory(f)
{
alloc(n);
}
template<class T> inline
Array<T>::Array(const Array<T> &a, const Factory &f)
: ndata(0), data(0), factory(f)
{
alloc(a.ndata);
for (int i = 0; i < a.ndata; i++)
data[i] = a.data[i];
}
template<class T> inline
Array<T>::Array(const std::string& values, const Factory &f)
: ndata(0), data(0), factory(f)
{
std::istringstream buffer(values);
buffer >> *this;
}
template<class T> inline
Array<T>::Array(const char* values, const Factory &f)
: ndata(0), data(0), factory(f)
{
std::istringstream buffer(values);
buffer >> *this;
}
template<class T>
Array<T>::~Array()
{
free();
}
template<class T>
void Array<T>::set_size(int size, bool copy)
{
it_assert_debug(size >= 0, "Array::set_size(): New size must not be negative");
if (ndata == size)
return;
if (copy) {
// create a temporary pointer to the allocated data
T* tmp = data;
// store the current number of elements
int old_ndata = ndata;
// check how many elements we need to copy
int min = (ndata < size) ? ndata : size;
// allocate new memory
alloc(size);
// copy old elements into a new memory region
for (int i = 0; i < min; ++i) {
data[i] = tmp[i];
}
// initialize the rest of resized array
for (int i = min; i < size; ++i) {
data[i] = T();
}
// delete old elements
destroy_elements(tmp, old_ndata);
}
else {
free();
alloc(size);
}
}
template<class T> inline
T& Array<T>::operator()(int i)
{
it_assert_debug(in_range(i), "Array::operator(): Improper index");
return data[i];
}
template<class T> inline
const T& Array<T>::operator()(int i) const
{
it_assert_debug(in_range(i), "Array::operator(): Improper index");
return data[i];
}
template<class T> inline
const Array<T> Array<T>::operator()(int i1, int i2) const
{
it_assert_debug(in_range(i1) && in_range(i2) && (i2 >= i1),
"Array::operator()(i1, i2): Improper indexes.");
Array<T> s(i2 - i1 + 1);
for (int i = 0; i < s.ndata; i++)
s.data[i] = data[i1+i];
return s;
}
template<class T> inline
const Array<T> Array<T>::operator()(const Array<int> &indices) const
{
Array<T> a(indices.size());
for (int i = 0; i < a.size(); i++) {
it_assert_debug(in_range(indices(i)),
"Array::operator()(indices): Improper indices.");
a(i) = data[indices(i)];
}
return a;
}
template<class T> inline
Array<T>& Array<T>::operator=(const Array<T> &a)
{
if (this != &a) {
set_size(a.ndata);
for (int i = 0; i < ndata; i++)
data[i] = a.data[i];
}
return *this;
}
template<class T> inline
Array<T>& Array<T>::operator=(const T &e)
{
if (ndata == 0)
set_size(1);
for (int i = 0; i < ndata; i++)
data[i] = e;
return *this;
}
template<class T>
Array<T>& Array<T>::operator=(const char* values)
{
std::istringstream buffer(values);
buffer >> *this;
return *this;
}
template<class T>
Array<T> Array<T>::left(int n) const
{
it_assert_debug(in_range(n), "Array::left(): Index out of range");
Array<T> tmp(n);
for (int i = 0; i < n; ++i)
tmp.data[i] = data[i];
return tmp;
}
template<class T>
Array<T> Array<T>::right(int n) const
{
it_assert_debug(in_range(n), "Array::right(): Index out of range");
Array<T> tmp(n);
for (int i = 0; i < n; ++i)
tmp.data[i] = data[ndata-n+i];
return tmp;
}
template<class T>
Array<T> Array<T>::mid(int pos, int n) const
{
it_assert_debug((pos >= 0) && (n > 0) && (pos + n <= ndata), "Array::mid(): Indexing out of range");
Array<T> tmp(n);
for (int i = 0; i < n; ++i)
tmp.data[i] = data[pos+i];
return tmp;
}
template<class T>
T Array<T>::shift_right(const T& x)
{
it_assert_debug(ndata > 0, "Array::shift_right(x): Array empty!");
T ret;
ret = data[ndata-1];
for (int i = ndata - 1; i > 0; i--)
data[i] = data[i-1];
data[0] = x;
return ret;
}
template<class T>
const Array<T> Array<T>::shift_right(const Array<T> &a)
{
it_assert_debug(a.ndata <= ndata, "Array::shift_right(): Shift Array too large");
Array<T> out(a.ndata);
for (int i = 0; i < a.ndata; i++)
out.data[i] = data[ndata-a.ndata+i];
for (int i = ndata - 1; i >= a.ndata; i--)
data[i] = data[i-a.ndata];
for (int i = 0; i < a.ndata; i++)
data[i] = a.data[i];
return out;
}
template<class T>
T Array<T>::shift_left(const T& x)
{
T temp = data[0];
for (int i = 0; i < ndata - 1; i++)
data[i] = data[i+1];
data[ndata-1] = x;
return temp;
}
template<class T>
const Array<T> Array<T>::shift_left(const Array<T> &a)
{
it_assert_debug(a.ndata <= ndata, "Array::shift_left(): Shift Array too large");
Array<T> out(a.ndata);
for (int i = 0; i < a.ndata; i++)
out.data[i] = data[i];
for (int i = 0; i < ndata - a.ndata; i++)
data[i] = data[i+a.ndata];
for (int i = ndata - a.ndata; i < ndata; i++)
data[i] = a.data[i-ndata+a.ndata];
return out;
}
template<class T>
void Array<T>::swap(int i, int j)
{
it_assert_debug(in_range(i) && in_range(j),
"Array::swap(): Indices out of range.");
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
template<class T>
void Array<T>::set_subarray(int i1, int i2, const Array<T> &a)
{
if (i1 == -1) i1 = ndata - 1;
if (i2 == -1) i2 = ndata - 1;
it_assert_debug(in_range(i1) && in_range(i2),
"Array<T>::set_subarray(): Indices out of range.");
it_assert_debug(i2 >= i1, "Array<T>::set_subarray(): i2 >= i1 necessary.");
it_assert_debug(i2 - i1 + 1 == a.ndata, "Array<T>::set_subarray(): Wrong sizes.");
copy_vector(a.ndata, a.data, data + i1);
}
template<class T>
void Array<T>::set_subarray(int i1, int i2, const T &t)
{
if (i1 == -1) i1 = ndata - 1;
if (i2 == -1) i2 = ndata - 1;
it_assert_debug(in_range(i1) && in_range(i2),
"Array<T>::set_subarray(): Indices out of range");
it_assert_debug(i2 >= i1, "Array<T>::set_subarray(): i2 >= i1 necessary");
for (int i = i1; i <= i2; i++)
data[i] = t;
}
template<class T>
const Array<T> concat(const Array<T> &a, const T &e)
{
Array<T> temp(a.size() + 1);
for (int i = 0; i < a.size(); i++)
temp(i) = a(i);
temp(a.size()) = e;
return temp;
}
template<class T>
const Array<T> concat(const T &e, const Array<T> &a)
{
Array<T> temp(a.size() + 1);
temp(0) = e;
for (int i = 0; i < a.size(); i++)
temp(i + 1) = a(i);
return temp;
}
template<class T>
const Array<T> concat(const Array<T> &a1, const Array<T> &a2)
{
Array<T> temp(a1.size() + a2.size());
for (int i = 0; i < a1.size(); i++)
temp(i) = a1(i);
for (int i = 0; i < a2.size(); i++)
temp(a1.size() + i) = a2(i);
return temp;
}
template<class T>
const Array<T> concat(const Array<T> &a1, const Array<T> &a2,
const Array<T> &a3)
{
// There should be some error control?
Array<T> temp(a1.size() + a2.size() + a3.size());
for (int i = 0; i < a1.size(); i++)
temp(i) = a1(i);
for (int i = 0; i < a2.size(); i++)
temp(a1.size() + i) = a2(i);
for (int i = 0; i < a3.size(); i++)
temp(a1.size() + a2.size() + i) = a3(i);
return temp;
}
template<class T>
std::ostream &operator<<(std::ostream &os, const Array<T> &a)
{
os << "{";
for (int i = 0; i < a.size() - 1; i++)
os << a(i) << " ";
if (a.size() > 0)
os << a(a.size() - 1);
os << "}";
return os;
}
template<class T>
std::istream &operator>>(std::istream &is, Array<T> &a)
{
int nrof_elements = 0;
char c;
is >> c;
if (c == '{') {
is >> c;
while (c != '}') {
if (is.eof()) {
is.setstate(std::ios_base::failbit);
break;
}
if (c != ',') { // Discard comma signs between elements
is.putback(c);
}
if (++nrof_elements > a.size()) {
a.set_size(nrof_elements, true); // Too slow?
}
is >> a(nrof_elements - 1);
is >> c;
}
if (a.size() > nrof_elements) {
a.set_size(nrof_elements, true);
}
}
else {
is.setstate(std::ios_base::failbit);
}
return is;
}
template<class T>
void set_array(Array<T> &a, const char *values)
{
std::istringstream buffer(values);
buffer >> a;
}
template<class T>
void set_array(Array<T> &a, const std::string &str)
{
set_array(a, str.c_str());
}
} // namespace itpp
#endif // #ifndef ARRAY_H
itpp::Array
General array class.
Definition array.h:105
itpp::Array::alloc
void alloc(int n)
Allocate storage for an array of length n.
Definition array.h:197
itpp::Array::mid
Array< T > mid(int pos, int n) const
Get n elements of the array starting from pos.
Definition array.h:377
itpp::Array::Array
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
itpp::Array::set_array
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
itpp::Array::in_range
bool in_range(int i) const
Check whether index i is in the allowed range.
Definition array.h:185
itpp::Array::free
void free()
Free the storage space allocated by the array.
Definition array.h:210
itpp::Array::set_length
void set_length(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:161
itpp::Array::size
int size() const
Returns the number of data elements in the array object.
Definition array.h:155
itpp::Array::operator=
Array< T > & operator=(const Array< T > &a)
Assignment operator.
Definition array.h:327
itpp::Array::Array
Array(const Array< T > &a, const Factory &f=DEFAULT_FACTORY)
Copy constructor. An element factory f can be specified.
Definition array.h:226
itpp::Array::set_array
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
itpp::Array::ndata
int ndata
The current number of elements in the Array.
Definition array.h:187
itpp::Array::operator()
const T & operator()(int i) const
Get the i element.
Definition array.h:297
itpp::Array::operator=
Array< T > & operator=(const T &e)
Assignment operator.
Definition array.h:338
itpp::Array::swap
void swap(int i, int j)
Swap elements i and j.
Definition array.h:447
itpp::Array::set_subarray
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
itpp::Array::factory
const Factory & factory
Element factory (by default set to DEFAULT_FACTORY)
Definition array.h:191
itpp::Array::left
Array< T > left(int n) const
Get n left elements of the array.
Definition array.h:357
itpp::Array::Array
Array(const Factory &f=DEFAULT_FACTORY)
Default constructor. An element factory f can be specified.
Definition array.h:217
itpp::Array::shift_left
T shift_left(const T &e)
Shift in data at the last position. Return data from position 0.
Definition array.h:419
itpp::Array::~Array
virtual ~Array()
Destructor.
Definition array.h:251
itpp::Array::Array
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
itpp::Array::shift_right
T shift_right(const T &e)
Shift in data at position 0. Return data from the last position.
Definition array.h:388
itpp::Array::shift_right
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
itpp::Array::operator>>
std::istream & operator>>(std::istream &is, Array< T > &a)
Input stream for Array<T>. T must have istream operator>> defined.
Definition array.h:562
itpp::Array::operator()
const Array< T > operator()(const Array< int > &indices) const
Sub-array with the elements given by the integer Array.
Definition array.h:315
itpp::Array::shift_left
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
itpp::Array::set_subarray
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
itpp::Array::operator()
const Array< T > operator()(int i1, int i2) const
Sub-array from element i1 to element i2.
Definition array.h:304
itpp::Array::operator()
T & operator()(int i)
Get the i element.
Definition array.h:290
itpp::Array::operator=
Array< T > & operator=(const char *values)
Assignment operator.
Definition array.h:348
itpp::Array::operator<<
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
itpp::Array::Array
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
itpp::Array::data
T * data
A pointer to the data area.
Definition array.h:189
itpp::Array::set_size
void set_size(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:257
itpp::Array::length
int length() const
Returns the number of data elements in the array object.
Definition array.h:157
itpp::Array::right
Array< T > right(int n) const
Get n right elements of the array.
Definition array.h:367
itpp::Factory
Base class for class factories.
Definition factory.h:130
copy_vector.h
Vector copy functions for internal use.
factory.h
Base class for class factories and memory allocation functions.
it_assert_debug
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition itassert.h:107
itpp::size
int size(const Vec< T > &v)
Length of vector.
Definition matfunc.h:55
itpp::min
T min(const Vec< T > &in)
Minimum value of vector.
Definition min_max.h:125
itassert.h
Error handling functions - header file.
misc.h
Miscellaneous functions - header file.
itpp
itpp namespace
Definition itmex.h:37
itpp::concat
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
itpp::destroy_elements
void destroy_elements(T *&ptr, int n)
Destroy an array of Array, Vec or Mat elements.
Definition factory.h:214
itpp::DEFAULT_FACTORY
const Factory DEFAULT_FACTORY
Default (dummy) factory.
Definition factory.h:139
itpp::create_elements
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

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