//********************* AIM **********************
//To create a wrapper for a standard C++ Static array type. This
//wrapper will provide the standard [] elemental access, and as an
//addition, will provide the size of the array created, and checked
//access in the form of the at() function.
// Author: Dhruv Matani.
// Date: May 24, 2003.
// email: [email protected]
// Mail me if you find this useful.
#include <stdexcept>
#if !defined __ARRAY__
#define __ARRAY__
namespace nstd {
template <class t, unsigned int __size>
class array {
public:
typedef t value_type;
typedef t& reference;
typedef const t& const_reference;
typedef t* pointer;
typedef const t* const_pointer;
typedef unsigned int size_type;
typedef t* iterator;
typedef const t* const_iterator;
private:
size_type size;
value_type data[__size+1];
void _init_array_with_data (size_type, const_pointer);
public:
//Cheap hack, because member templates cannot access the private and
//protected parts of its own class type.
const_pointer __get_data_address (void) const { return data; }
array (void) { }
array (const_reference);
array (size_type n, const_reference);
array (const array&);
template <size_type __sz>
array (const array<t, __sz>& __array)
{
_init_array_with_data (__sz, __array.__get_data_address ());
}
array& operator= (const array& __array)
{
if (this == &__array) return *this;
_init_array_with_data (__size, __array.__get_data_address ());
return *this;
}
template <size_type __sz>
array& operator= (const array<t, __sz>& __array)
{
_init_array_with_data (__sz, __array.__get_data_address ());
return *this;
}
iterator begin (void) { return data; }
iterator end (void) { return data+__size; }
const_iterator begin (void) const { return data; }
const_iterator end (void) const { return data+__size; }
reference front (void) { return data[0]; }
reference back (void) { return data[__size-1]; }
const_reference front (void) const { return data[0]; }
const_reference back (void) const { return data[__size-1]; }
reference operator[] (size_type pos) { return data[pos]; }
reference at (size_type pos)
{
if ((pos+1) > __size || pos == static_cast<size_type>(-1))
throw std::length_error("Out of Range");
return data[pos];
}
};
template <class t, unsigned int __size>
array<t, __size>::array (const_reference __value)
{
size = __size;
size_type sz = 0;
while (sz < __size)
{
data[sz] = __value;
++sz;
}
}
template <class t, unsigned int __size>
array<t, __size>::array (const array& __array)
{
size_type sz = 0;
while (sz < __size)
{
data[sz] = __array.data[sz];
++sz;
}
}
template <class t, unsigned int __size>
array<t, __size>::array (size_type n, const_reference __value)
{
if (n > __size)
throw length_error ("Size of Array is less than argument value");
size_type sz = 0;
while (sz < n)
{
data[sz] = __value;
++sz;
}
while (sz < __size)
{
data[sz] = value_type();
++sz;
}
}
template <class t, unsigned int __size>
void array<t, __size>::_init_array_with_data (size_type __other_size, const_pointer ptr)
{
if (__other_size > __size)
throw std::length_error ("Destination Array is Smaller than Source Array");
size_type sz = 0;
while (sz < __other_size)
{
data[sz] = ptr[sz];
++sz;
}
while (sz < __size)
{
data[sz] = value_type();
++sz;
}
}
}
#endif //__ARRAY__