Array.h
// Array.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2007
#include "Ceda/cxUtils/xvector.h"
#include "Ceda/cxUtils/xostream.h"
#include "Ceda/cxUtils/Archive.h"
// todo: ArchiveCollection.h in turn includes 10 standard library headers like <map>, <list>, <deque> and <set>,
// this can increase compile times
#include "Ceda/cxUtils/ArchiveCollection.h"
// todo: ListToOStream.h in turn includes 8 standard library headers like <map>, <list>, <deque> and <set>,
// this can increase compile times
#include "Ceda/cxUtils/ListToOStream.h"
#include <array>
namespace ceda
{
/*
A std::array<T,N> is a fixed size array of N elements of type T. Use of this template is convenient for two
reasons
1. It allows for implementing serialise functions to an archive
2. When a variable of type std::array<T,N> the name of the variable appears to the right of the
type declaration. This is convenient for the xcpp code generator
*/
///////////////////////////////////////////////////////////////////////////////////////////////////
// MapArrayType
// T --> typename MapArrayType<T>::type
//
// T[N] is mapped to std::array<T,N>, any other type is mapped to itself
template <typename T>
struct MapArrayType
{
typedef T type;
};
template <typename T, size_t N>
struct MapArrayType<T[N]>
{
typedef std::array<T,N> type;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// DynArray<T>
/*
Intended for use in ceda data models where the size of the array grows dynamically according
to what is recorded.
*/
template <typename T>
class DynArray
{
public:
typedef T value_type;
bool operator<(const DynArray& rhs) const
{
ssize_t n1 = m_values.size();
ssize_t n2 = rhs.m_values.size();
ssize_t min, max;
const T* p;
if (n1 < n2) { min=n1; max=n2; p = rhs.m_values.data(); }
else { min=n2; max=n1; p = m_values.data(); }
for (ssize_t i=0 ; i < min ; ++i)
{
if (m_values[i] < rhs.m_values[i]) return true;
if (m_values[i] != rhs.m_values[i]) return false;
}
for (ssize_t i=min ; i < max ; ++i)
{
if (p[i] < T()) return true;
if (p[i] != T()) return false;
}
return false; // equal
}
bool operator==(const DynArray& rhs) const
{
ssize_t n1 = m_values.size();
ssize_t n2 = rhs.m_values.size();
ssize_t min, max;
const T* p;
if (n1 < n2) { min=n1; max=n2; p = rhs.m_values.data(); }
else { min=n2; max=n1; p = m_values.data(); }
for (ssize_t i=0 ; i < min ; ++i)
{
if (m_values[i] != rhs.m_values[i]) return false;
}
for (ssize_t i=min ; i < max ; ++i)
{
if (p[i] != T()) return false;
}
return true;
}
bool operator!=(const DynArray& _rhs) const { return !operator==(_rhs); }
bool operator<=(const DynArray& _rhs) const { return !_rhs.operator<(*this); }
bool operator>(const DynArray& _rhs) const { return _rhs.operator<(*this); }
bool operator>=(const DynArray& _rhs) const { return !operator<(_rhs); }
ssize_t size() const { return m_values.size(); }
const T& operator[](ssize_t i) const
{
cxAssert(0 <= i);
if (i >= m_values.size()) const_cast<DynArray*>(this)->m_values.resize(i+1);
return m_values[i];
}
T& operator[](ssize_t i)
{
cxAssert(0 <= i);
if (i >= m_values.size()) m_values.resize(i+1);
return m_values[i];
}
public:
xvector<T> m_values;
};
template<typename T>
inline xostream& operator<<(xostream& os, const DynArray<T>& x)
{
os << '[';
for (ssize_t i=0 ; i < x.m_values.size() ; ++i)
{
if (i > 0) os << ',';
os << x[i];
}
os << ']';
return os;
}
template <typename Archive, typename T>
inline void Serialise(Archive& ar, const DynArray<T>& x)
{
ar << x.m_values;
}
template <typename Archive, typename T>
inline void Deserialise(Archive& ar, DynArray<T>& x)
{
ar >> x.m_values;
}
} // ceda