자료구조

[자료구조] C++ Vector (손코딩)

CGNY 2023. 4. 16. 21:35
#include <iostream>
#include <assert.h>
using namespace std;

template <typename T>
class Vector
{
private:
	T*	addr;
	int dataSize;
	int dataMaxSize;
	
public:
	Vector()
		:
		addr(nullptr),
		dataSize(0),
		dataMaxSize(2)
	{
		addr = new T[dataMaxSize];
	}
	virtual ~Vector()
	{
		delete[] addr;
	}

public:
	void push_back(const T& value);
	void resize(const int& resize);
	T& data() const { return addr; }
	const int& size() const { return dataSize; }
	const int& capacity() const { return dataMaxSize; }


	T& operator [] (const int& index)
	{
		if (-1 == index || index >= dataSize || nullptr == addr)
		{
			return assert(nullptr);
		}
		
		return *(addr + index);
	}

	class iterator;
	iterator begin();
	iterator end();
	iterator erase(iterator& iter);
	
	class iterator
	{
	private:
		Vector<T>*	i_vecAddr;
		T*			i_addr;
		int			i_index;
		bool		i_valid;

	public:
		iterator()
			:
			i_vecAddr(nullptr),
			i_addr(nullptr),
			i_index(-1),
			i_valid(false)
		{ }
		iterator(Vector<T>* vec, T* addr, int index)
			:
			i_vecAddr(vec),
			i_addr(addr),
			i_index(index),
			i_valid(false)
		{
			if (nullptr != i_vecAddr && nullptr != i_addr && 0 <= i_index) i_valid = true;
		}
		~iterator() {}

	public:
		T& operator * ()
		{
			if (i_vecAddr->addr != i_addr || -1 == i_index || i_valid == false) assert(nullptr);
			return i_addr[i_index];
		}
		iterator& operator ++ ()
		{
			if (i_vecAddr->addr != i_addr || -1 == i_index || i_index == i_vecAddr->size() - 1)
			{
				i_index = -1;
			}
			else ++i_index;
			
			return *this;
		}
		iterator operator ++ (int)
		{
			if (i_vecAddr->addr != i_addr || -1 == i_index || i_index == i_vecAddr->size() - 1) return assert(nullptr);
			
			iterator copy = *this;
			++(*this);

			return copy;
		}

		iterator& operator -- ()
		{
			if (i_vecAddr->addr != i_addr || -1 == i_index || i_index == 0) assert(nullptr);
			else --i_index;
			return *this;
		}
		iterator operator -- (int)
		{
			iterator copy = *this;
			--(*this);
			return copy;
		}

		bool operator == (const iterator& other)
		{
			if (i_addr == other.i_addr && i_index == other.i_index) return true;
			return false;
		}
		bool operator != (const iterator& other)
		{
			return !(*this == other);
		}
		friend class Vector;
	};
};

template<typename T>
void Vector<T>::push_back(const T& value)
{
	if (dataSize >= dataMaxSize)
	{
		resize(dataSize * 2);
	}
	addr[dataSize++] = value;
}

template<typename T>
void Vector<T>::resize(const int& resizeValue)
{
	if (dataMaxSize >= resizeValue) assert(nullptr);
	T* chunck = new T[resizeValue];
	for (int i = 0; i < dataSize; ++i)
	{
		chunck[i] = addr[i];
	}
	delete[] addr;
	addr = chunck;
	dataMaxSize = resizeValue;
}

template<typename T>
typename Vector<T>::iterator Vector<T>::begin()
{
	if (dataSize == 0) return iterator(this, addr, -1);
	return iterator(this, addr, 0);
}

template<typename T>
typename Vector<T>::iterator Vector<T>::end()
{
	return iterator(this, addr, -1);
}

template<typename T>
typename Vector<T>::iterator Vector<T>::erase(iterator& iter)
{
	if (this != iter.i_vecAddr || end() == iter || dataSize <= iter.i_index)
	{
		assert(nullptr);
	}

	int loop = iter.i_vecAddr->dataSize - (iter.i_index + 1);
	for (int i = 0; i < loop; ++i)
	{
		addr[i + iter.i_index] = addr[i + iter.i_index + 1];
	}

	--dataSize;
	iter.i_valid = false;
	return iterator(this, addr, iter.i_index);
}


int main()
{
	Vector<int> v1;
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);

	Vector<int>::iterator iter = v1.begin();
	for (; iter != v1.end(); ++iter)
	{
		cout << *iter << endl;
	}
	
	iter = v1.begin();
	iter = v1.erase(iter);
	cout << *iter << endl;

	return 0;
}