// --------
// Array2.h
// --------
#ifndef Array2_h
#define Array2_h
#include <algorithm> // copy, equal, lexicographical_compare
#include <cstddef> // ptrdiff_t, size_t
#include <memory> // allocator
#include <stdexcept> // out_of_range
#include <utility> // !=, <=, >, >=
#include "Memory.h" // my_destroy, my_uninitialized_copy, my_uninitialized_fill
using namespace std::rel_ops;
template <typename T, std::size_t N, typename A = std::allocator<T> >
class Array2 {
public:
typedef A allocator_type;
typedef typename allocator_type::value_type value_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef typename allocator_type::pointer iterator;
typedef typename allocator_type::const_pointer const_iterator;
public:
friend bool operator == (const Array2& lhs, const Array2& rhs) {
return std::equal(lhs.begin(), lhs.end(), rhs.begin());}
friend bool operator < (const Array2& lhs, const Array2& rhs) {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());}
private:
pointer _a;
char _x[N * sizeof(value_type)];
allocator_type _z;
public:
explicit Array2 (const_reference v = value_type(), const allocator_type& z = allocator_type()) :
_a (reinterpret_cast<pointer>(_x)),
_z (z) {
my_uninitialized_fill(_z, begin(), end(), v);}
Array2 (const Array2& that) :
_a (reinterpret_cast<pointer>(_x)),
_z (that._z) {
my_uninitialized_copy(_z, that.begin(), that.end(), begin());}
template <typename II>
Array2 (II b, II e, const allocator_type& z = allocator_type()) :
_a (reinterpret_cast<pointer>(_x)),
_z (z) {
my_uninitialized_copy(_z, b, e, begin());}
~Array2 () {
my_destroy(_z, begin(), end());}
Array2& operator = (const Array2& that) {
if (this != &that)
std::copy(that.begin(), that.end(), begin());
return *this;}
reference operator [] (size_type i) {
return _a[i];}
const_reference operator [] (size_type i) const {
return (*const_cast<Array2*>(this))[i];}
reference at (size_type i) {
if (i >= size())
throw std::out_of_range("Array::at index out of range");
return (*this)[i];}
const_reference at (size_type i) const {
return const_cast<Array2*>(this)->at(i);}
iterator begin () {
return _a;}
const_iterator begin () const {
return _a;}
iterator end () {
return _a + N;}
const_iterator end () const {
return _a + N;}
size_type size () const {
return N;}};
#endif // Array2_h
syntax highlighted by Code2HTML, v. 0.9.1