PHengLEI-NCCR/API/DataStruct/include/PHSimpleArray.h

234 lines
6.0 KiB
C++

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PPPPP H H EEEEE N N GGGGG L EEEEE III +
// P P H H E NN N G L E I +
// PPPPP HHHHH EEEEE N N N G GG L EEEEE I +
// P H H E N N N G G L E I +
// P H H EEEEE N N GGGGG LLLLL EEEEE III +
//------------------------------------------------------------------------+
// Platform for Hybrid Engineering Simulation of Flows +
// China Aerodynamics Research and Development Center +
// (C) Copyright, Since 2010 +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//! @file PHSimpleArray.h
//! @brief Explain this file briefly.
//! @author xxx.
#pragma once
#include <cstddef>
#include <stdexcept>
#include "DataStruct_Range.h"
namespace PHSPACE
{
template < typename T, int N >
class SimpleArray
{
public:
T elems[N]; //! Fixed-size array of elements of type T.
public:
//! Type definitions.
typedef T value_type;
typedef T *iterator;
typedef const T *const_iterator;
typedef T &reference;
typedef const T &const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//! iterator support.
iterator begin() { return elems; }
const_iterator begin() const { return elems; }
iterator end() { return elems+N; }
const_iterator end() const { return elems+N; }
//! reverse iterator support.
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
//! operator[].
reference operator[](size_type i)
{
return elems[i];
}
const_reference operator[](size_type i) const
{
return elems[i];
}
//! at() with range check.
reference at(size_type i) { rangecheck(i); return elems[i]; }
const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
//! front() and back().
reference front()
{
return elems[0];
}
const_reference front() const
{
return elems[0];
}
reference back()
{
return elems[N-1];
}
const_reference back() const
{
return elems[N-1];
}
//! Size is constant.
static size_type size() { return N; }
static bool empty() { return false; }
static size_type max_size() { return N; }
enum { static_size = N };
//! Swap (note: linear complexity).
void swap (SimpleArray<T, N> &y)
{
std::swap_ranges(begin(), end(), y.begin());
}
//! Direct access to data (read-only).
const T * data() const { return elems; }
//! Use array as C array (direct read/write access to data).
T * c_array() { return elems; }
//! Assignment with type conversion.
template <typename T2>
SimpleArray<T, N> & operator = (const SimpleArray<T2, N> &rhs)
{
std::copy(rhs.begin(), rhs.end(), begin());
return *this;
}
SimpleArray<T, N> & operator = (const T &value)
{
std::fill_n(begin(), size(), value);
return *this;
}
SimpleArray<T, N> &operator += (const T &value)
{
for (int i = 0; i < N; ++ i)
{
elems[i] += value;
}
return *this;
}
SimpleArray<T, N> &operator += (const SimpleArray<T, N> &x)
{
const T *tmp = x.data();
for (int i = 0; i < N; ++ i)
{
elems[i] += tmp[i];
}
return *this;
}
SimpleArray<T, N> &operator -= (const T &value)
{
for (int i = 0; i < N; ++ i)
{
elems[i] -= value;
}
return *this;
}
SimpleArray<T, N> &operator -= (const SimpleArray<T, N> &x)
{
const T *tmp = x.data();
for (int i = 0; i < N; ++ i)
{
elems[i] -= tmp[i];
}
return *this;
}
//! Assign one value to all elements.
void assign (const T &value)
{
std::fill_n(begin(), size(), value);
}
//! Check range (may be private because it is static).
static void rangecheck (size_type i)
{
if (i >= size())
{
throw std::range_error("SimpleArray<>: index out of range");
}
}
};
//! Comparisons.
template < typename T, int N >
bool operator == (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return std::equal(x.begin(), x.end(), y.begin());
}
template < typename T, int N >
bool operator < (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template < typename T, int N >
bool operator != (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return ! (x == y);
}
template < typename T, int N >
bool operator > (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return y < x;
}
template < typename T, int N >
bool operator <= (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return ! (y < x);
}
template < typename T, int N >
bool operator >= (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
return ! (x < y);
}
//! Global swap().
template < typename T, int N >
inline void swap (SimpleArray<T, N> &x, SimpleArray<T, N> &y)
{
x.swap(y);
}
template < typename T, int N >
inline T dot (const SimpleArray<T, N> &x, const SimpleArray<T, N> &y)
{
T sum = 0;
for (int i = 0; i < N; ++ i)
{
sum += x[i] * y[i];
}
return sum;
}
}