자료 저장소

#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);
}


댓글 로드 중…

최근에 게시된 글