크기가 고정되어있는 1차원 배열 컨테이너입니다.

일반 배열과 차이점은
따로 크기를 알 필요가 없고
범위를 벗어나는곳에 접근하는걸 막을 수 있으며
복사가 가능하고
STL 알고리즘 적용이 쉽다는 점입니다.

vector를 참고해서 만들었고, 크기가 고정되어 있으므로 인스턴스 생성시 크기를 지정해줘야하며 삽입, 삭제같은 기능은 안됩니다. resize는 가능합니다.
크기가 다른 배열끼리 swap이나 대입역시 안됩니다. 단 copy로는 가능합니다.
범위를 벗어나는곳에 접근하면 assertion fail이 납니다.

reverse_iterator는 안만들었습니다.
버그,수정할 부분,개선되야할점은 알려주세요 꼭.

STL 알고리즘, 컨테이너와 호환됩니다.
(단 크기가 고정되어 있으므로 STL 컨테이너에서 삽입은 불가능.)

구현물:
[code]#include <iostream>

#include <iterator>

#include <algorithm>
#include <numeric>

#include <map>
#include <vector>
#include <list>

#include <cassert>

using namespace std;


// enable this definition if you want 'out of range' test in array1 class
#define ARRAY1_TEST_OUT_OF_RANGE


template <typename Type>
class array1
{

public:

typedef unsigned int size_type;
typedef Type value_type;

typedef unsigned int difference_type;

typedef Type * pointer;
typedef Type & reference;

typedef const Type * const_pointer;
typedef const Type & const_reference;


class const_iterator
{
protected:

pointer m_ptr;

public:
typedef unsigned int difference_type;
typedef Type value_type;

typedef difference_type difference;
typedef value_type value;
typedef value* pointer;
typedef value& reference;
// typedef iterator;
typedef random_access_iterator_tag iterator_category;


const_iterator()
{
m_ptr = 0;
}

const_iterator(pointer ptr)
{
m_ptr = ptr;
}

const_reference operator*() const
{
return (*m_ptr);
}

pointer operator->() const
{ // return pointer to class object
return (&**this);
}


const_iterator& operator++()
{ // preincrement
++m_ptr;
return (*this);
}

const_iterator operator++(int)
{ // postincrement
const_iterator _Tmp = *this;
++*this;
return (_Tmp);
}

const_iterator& operator--()
{ // predecrement
--m_ptr;
return (*this);
}

const_iterator operator--(int)
{ // postdecrement
const_iterator _Tmp = *this;
--*this;
return (_Tmp);
}


const_iterator& operator+=(difference_type _Off)
{ // increment by integer
m_ptr += _Off;
return (*this);
}

const_iterator operator+(difference_type _Off) const
{ // return this + integer
const_iterator _Tmp = *this;
return (_Tmp += _Off);
}

const_iterator& operator-=(difference_type _Off)
{ // decrement by integer
return (*this += -_Off);
}

const_iterator operator-(difference_type _Off) const
{ // return this - integer
const_iterator _Tmp = *this;
return (_Tmp -= _Off);
}

difference_type operator-(const const_iterator& _Right) const
{ // return difference of iterators
return (m_ptr - _Right.m_ptr);
}


const_reference operator[](difference_type _Off) const
{ // subscript
return (*(*this + _Off));
}

bool operator==(const const_iterator& _Right) const
{ // test for iterator equality
return (m_ptr == _Right.m_ptr);
}

bool operator!=(const const_iterator& _Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}

bool operator<(const const_iterator& _Right) const
{ // test if this < _Right
return (m_ptr < _Right.m_ptr);
}

bool operator>(const const_iterator& _Right) const
{ // test if this > _Right
return (_Right < *this);
}

bool operator<=(const const_iterator& _Right) const
{ // test if this <= _Right
return (!(_Right < *this));
}

bool operator>=(const const_iterator& _Right) const
{ // test if this >= _Right
return (!(*this < _Right));
}


friend const_iterator operator+(difference_type _Off,
const const_iterator& _Right)
{ // return iterator + integer
return (_Right + _Off);
}


};



class iterator : public const_iterator
{

public:

iterator()
{ // construct with null vector pointer
}

iterator(pointer _Ptr) : const_iterator(_Ptr)
{ // construct with pointer _Ptr
}

reference operator*() const
{ // return designated object
return ((reference)**(const_iterator *)this);
}

pointer operator->() const
{ // return pointer to class object
return (&**this);
}


iterator& operator++()
{ // preincrement
++this->m_ptr;
return (*this);
}

iterator operator++(int)
{ // postincrement
iterator _Tmp = *this;
++*this;
return (_Tmp);
}

iterator& operator--()
{ // predecrement
--this->m_ptr;
return (*this);
}

iterator operator--(int)
{ // postdecrement
iterator _Tmp = *this;
--*this;
return (_Tmp);
}


iterator& operator+=(difference_type _Off)
{ // increment by integer
this->m_ptr += _Off;
return (*this);
}

iterator operator+(difference_type _Off) const
{ // return this + integer
iterator _Tmp = *this;
return (_Tmp += _Off);
}

iterator& operator-=(difference_type _Off)
{ // decrement by integer
return (*this += -_Off);
}

iterator operator-(difference_type _Off) const
{ // return this - integer
iterator _Tmp = *this;
return (_Tmp -= _Off);
}

difference_type operator-(const const_iterator& _Right) const
{ // return difference of iterators
return ((const_iterator)*this - _Right);
}

reference operator[](difference_type _Off) const
{ // subscript
return (*(*this + _Off));
}

friend iterator operator+(difference_type _Off, const iterator& _Right)
{ // return iterator + integer
return (_Right + _Off);
}

};


private:

value_type *m_begin, *m_end;
size_type m_size;

public:

array1(size_type size = 0, const value_type &val = Type())
{
m_begin = 0;
m_end = 0;
m_size = 0;

assign(size, val);
}

~array1()
{
clear();
}


void assign(size_type size, const value_type &val)
{
clear();

m_size = size;

m_begin = new value_type[m_size];
m_end = &m_begin[size];

for(size_type i = 0; i < m_size; i++)
{
m_begin[i] = val;
}
}

bool test_in_range(size_type pos) const
{
bool in_range = (0 <= pos && pos < size());

assert(in_range && "array1 position is out of range");

return in_range;
}

reference at(size_type pos)
{
#ifdef ARRAY1_TEST_OUT_OF_RANGE
test_in_range(pos);
#endif

return m_begin[pos];
}

const_reference at(size_type pos) const
{
#ifdef ARRAY1_TEST_OUT_OF_RANGE
test_in_range(pos);
#endif

return m_begin[pos];
}


iterator begin()
{
return m_begin;
}

const_iterator begin() const
{
return m_begin;
}

iterator end()
{
return m_end;
}

const_iterator end() const
{
return m_end;
}

void clear()
{
delete []m_begin;

m_begin = 0;
m_end = 0;
m_size = 0;
}

bool empty() const
{
return !m_size;
}

/*
reverse_iterator rbegin()
{
}

reverse_iterator rend()
{
}
*/

void resize(size_type newsize)
{
assign(newsize, value_type());
}

size_type size() const
{
return m_size;
}

bool same_size(const array1 &rhs)
{
return size() == rhs.size();
}


bool swap(array1 &rhs)
{
if(same_size(rhs))
{
swap(*this, rhs);

return true;
}

return false;
}

friend void swap(array1 &lhs, array1 &rhs);


bool operator=(const array1 &rhs)
{
if(same_size(rhs))
{
copy(rhs);
return true;
}

return false;
}


void copy(const array1 &rhs)
{
// realloc
assign(rhs.size(), value_type());

// copy
for(size_type i = 0; i < size(); i++)
{
at(i) = rhs.at(i);
}
}

reference operator[](size_type pos)
{
return at(pos);
}

const_reference operator[](size_type pos) const
{
return at(pos);
}


};

template <typename Type>
bool swap(array1<Type> &lhs, array1<Type> &rhs)
{
if(lhs.same_size(rhs))
{
array1 buf = lhs;
lhs = rhs;
rhs = buf;

return true;
}

return false;
}
[/code]

테스트 코드:
[code]template <typename ContainerTy>
void enumElems(const ContainerTy &ty)
{
for(ContainerTy::const_iterator i = ty.begin(); i != ty.end(); i++)
{
cout << *i << endl;
}
}


int main()
{
typedef array1<int> testar;
typedef list<int> testlst;

testar ar(3, 1), ar2(4), ar3(5);

cout << "ar: " << endl;

enumElems(ar);

// accessor

ar[0] = 1;
ar[1] = 2;
ar[2] = 3;

cout << "enumerate elems: " << endl;
enumElems(ar);


// apply STL algorithm

int sum = accumulate(ar.begin(), ar.end(), 0);
cout << "sum of all elems : " << sum << endl;


// reallocate

ar.resize(4);
cout << "array resized" << endl;

for(testar::iterator i = ar.begin(); i != ar.end(); i++)
{
*i = i - ar.begin() + 1;
}

cout << "enumulate elems again" << endl;
enumElems(ar);


// iterator

testar::iterator beg = ar.begin();
beg++;
cout << "second elem: " << *beg << endl;


// copy

cout << "enum ar2: " << endl;
ar2 = ar;
enumElems(ar2);

cout << "enum ar3 " << endl;
ar3 = ar;
enumElems(ar3);


// compatability with another container

testlst lst;

lst.insert(lst.begin(), ar.begin(), ar.end());

cout << "enum list elems: " << endl;
enumElems(lst);


// 'out of range' test. it occurs 'assertion failed' error
ar[-1];


return 0;
}
[/code]
blog: http://ljh131.tistory.com
email: ljh131@gmail.com