#ifndef SMALL_BOOST_ARRAY_HPP
#define SMALL_BOOST_ARRAY_HPP
#include <cstddef>
#include <stdexcept>
#include <algorithm>
namespace s_boost {
template<class T, std::size_t N>
class array {
public:
T elems[N];
public:
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 begin() { return elems; }
const_iterator begin() const { return elems; }
iterator end() { return elems+N; }
const_iterator end() const { return elems+N; }
reference operator[](size_type i)
{
return elems[i];
}
const_reference operator[](size_type i) const
{
return elems[i];
}
reference at(size_type i) { rangecheck(i); return elems[i]; }
const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
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];
}
static size_type size() { return N; }
static bool empty() { return false; }
static size_type max_size() { return N; }
enum { static_size = N };
void swap (array<T,N>& y) {
for (size_type i = 0; i < N; ++i)
swap(elems[i],y.elems[i]);
}
const T* data() const { return elems; }
T* data() { return elems; }
T* c_array() { return elems; }
template <typename T2>
array<T,N>& operator= (const array<T2,N>& rhs) {
std::copy(rhs.begin(),rhs.end(), begin());
return *this;
}
void assign (const T& value)
{
std::fill_n(begin(),size(),value);
}
static void rangecheck (size_type i) {
if (i >= size()) {
throw std::out_of_range("array<>: index out of range");
}
}
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template< class T >
class array< T, 0 > {
public:
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 begin() { return iterator( reinterpret_cast< T * >( this ) ); }
const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
iterator end() { return begin(); }
const_iterator end() const { return begin(); }
reference operator[](size_type )
{
return failed_rangecheck();
}
const_reference operator[](size_type ) const
{
return failed_rangecheck();
}
reference at(size_type ) { return failed_rangecheck(); }
const_reference at(size_type ) const { return failed_rangecheck(); }
reference front()
{
return failed_rangecheck();
}
const_reference front() const
{
return failed_rangecheck();
}
reference back()
{
return failed_rangecheck();
}
const_reference back() const
{
return failed_rangecheck();
}
static size_type size() { return 0; }
static bool empty() { return true; }
static size_type max_size() { return 0; }
enum { static_size = 0 };
void swap (array<T,0>& ) {
}
const T* data() const { return 0; }
T* data() { return 0; }
T* c_array() { return 0; }
template <typename T2>
array<T,0>& operator= (const array<T2,0>& ) {
return *this;
}
void assign (const T& ) { }
static reference failed_rangecheck () {
std::out_of_range e("attempt to access element of an empty array");
throw e;
static T placeholder;
return placeholder;
}
};
#endif
template<class T, std::size_t N>
bool operator== (const array<T,N>& x, const array<T,N>& y) {
return std::equal(x.begin(), x.end(), y.begin());
}
template<class T, std::size_t N>
bool operator< (const array<T,N>& x, const array<T,N>& y) {
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
}
template<class T, std::size_t N>
bool operator!= (const array<T,N>& x, const array<T,N>& y) {
return !(x==y);
}
template<class T, std::size_t N>
bool operator> (const array<T,N>& x, const array<T,N>& y) {
return y<x;
}
template<class T, std::size_t N>
bool operator<= (const array<T,N>& x, const array<T,N>& y) {
return !(y<x);
}
template<class T, std::size_t N>
bool operator>= (const array<T,N>& x, const array<T,N>& y) {
return !(x<y);
}
template<class T, std::size_t N>
inline void swap (array<T,N>& x, array<T,N>& y) {
x.swap(y);
}
}
#endif