#include <iostream>
#include <string>
#include <memory>
usingnamespacestd;
template <class T>
class Vec
{
public:
typedef T* iterator;
typedefconst T* const_iterator;
typedef size_t size_type;
typedef T value_type;
Vec() { create(); }
Vec(const Vec& v) { create(v.begin, v.end); }
Vec& operator=(const Vec& ref)
{
if(&ref != this)
{
uncreate();
}
create(ref.begin(),ref.end());
return *this;
}
explicit Vec(size_type n, const T& val = T()) { create(n, val); }
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
size_type size() const { return avail - data; }
iterator begin() { return data; }
const_iterator begin() const { return data; }
iterator end() { return avail; }
const_iterator end() const { return avail; }
void push_back(const T& val)
{
if(avail == limit)
grow();
unchecked_append(val);
}
~Vec() { uncreate(); }
private:
iterator data; // Vec의 첫번째 요소
iterator avail; // Vec의 (하나 지난) 마지막 요소
iterator limit; // 할당된 메모의 (하나 지난) 요소
// 메모리 할당 기능
allocator<T> alloc;
// 배열을 할당 및 초기화
void create();
void create(size_type, const T&);
void create(const_iterator, const_iterator);
// 배열의 요소들을 소멸시키고, 메모리를 해제
void uncreate();
// push_back을 지원하는 함수
void grow();
void unchecked_append(const T&);
};
template <class T>
void Vec<T>::create()
{
data = avail = limit = 0;
}
template <class T>
void Vec<T>::create(size_type n, const T& val)
{
data = alloc.allocate(n);
limit = avail = data + n;
uninitialized_fill(data, limit, val);
}
template <class T>
void Vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j-i);
limit = avail = uninitialized_copy(i,j,data);
}
template <class T>
void Vec<T>::uncreate()
{
if(data)
{
iterator it = avail;
// 생성된 요소들을 역순으로 소멸
while(it!=data)
alloc.destroy(--it);
// 할당된 모든 공간을 소멸
alloc.deallocate(data,limit - data);
}
// 포인터를 리셋하여, Vec을 빈 상태로 만듬
data = limit = avail = 0;
}
template <class T>
void Vec<T>::grow()
{
// 현재 사용하는 두 배의 공간을 할당하여 크기를 늘림
size_type new_size = max(2 * (limit - data), ptrdiff_t(1));
// 새 공간을 할당하고, 그곳에 기존의 요소들을 복사
iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data, avail, new_data);
// 예전 공간을 반환
uncreate();
// 새로 할당된 공간을 가리키는 포인터 리셋
data = new_data;
avail = new_avail;
limit = data + new_size;
}
// avail은 할당은 되었지만, 초기화되지 않은 공간을 가리킨다고 가정
template <class T>
void Vec<T>::unchecked_append(const T& val)
{
alloc.construct(avail++, val);
}
'프로그래밍 > STL' 카테고리의 다른 글
C++,STL :: vector 사용하기 (0) | 2010.10.26 |
---|---|
C++,STL :: list 사용하기 (0) | 2010.10.17 |
C++,STL :: 제네릭 함수(generic function) 작성 (0) | 2010.09.05 |
C++,STL :: 연관 컨테이너(associative container) 연산 (0) | 2010.09.04 |
C++,STL :: map을 이용한 문장 생성 (0) | 2010.09.04 |
댓글 로드 중…