300 lines
4.9 KiB
C++
300 lines
4.9 KiB
C++
|
#pragma once
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
#include <assert.h>
|
|||
|
|
|||
|
using namespace std;
|
|||
|
|
|||
|
namespace Lenyiin
|
|||
|
{
|
|||
|
template <class T>
|
|||
|
class Vector
|
|||
|
{
|
|||
|
public:
|
|||
|
typedef T* iterator;
|
|||
|
typedef const T* const_iterator;
|
|||
|
|
|||
|
iterator begin()
|
|||
|
{
|
|||
|
return _start;
|
|||
|
}
|
|||
|
|
|||
|
iterator end()
|
|||
|
{
|
|||
|
return _finish;
|
|||
|
}
|
|||
|
|
|||
|
const_iterator begin() const
|
|||
|
{
|
|||
|
return _start;
|
|||
|
}
|
|||
|
|
|||
|
const_iterator end() const
|
|||
|
{
|
|||
|
return _finish;
|
|||
|
}
|
|||
|
|
|||
|
size_t size() const
|
|||
|
{
|
|||
|
return _finish - _start;
|
|||
|
}
|
|||
|
|
|||
|
size_t capacity() const
|
|||
|
{
|
|||
|
return _endofstorage - _start;
|
|||
|
}
|
|||
|
|
|||
|
// Ĭ<>Ϲ<EFBFBD><CFB9><EFBFBD>
|
|||
|
Vector()
|
|||
|
: _start(nullptr), _finish(nullptr), _endofstorage(nullptr)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//Vector(const Vector<T>& v)
|
|||
|
//{
|
|||
|
// _start = new T[v.capacity()];
|
|||
|
// _finish = _start;
|
|||
|
// _endofstorage = _start + v.capacity();
|
|||
|
|
|||
|
// for (size_t i = 0; i < v.size(); i++)
|
|||
|
// {
|
|||
|
// *_finish = v[i];
|
|||
|
// ++_finish;
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
|
|||
|
Vector(const Vector<T>& v)
|
|||
|
: _start(nullptr), _finish(nullptr), _endofstorage(nullptr)
|
|||
|
{
|
|||
|
reserve(v.capacity());
|
|||
|
for (const auto& e : v)
|
|||
|
{
|
|||
|
push_back(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//Vector<T>& operator=(const Vector<T>& v)
|
|||
|
//{
|
|||
|
// if (this != &v)
|
|||
|
// {
|
|||
|
// delete[] _start;
|
|||
|
// _start = new T[v.capacity()];
|
|||
|
|
|||
|
// //memcpy(_start, v._start, sizeof(T) * v.size()); <09><><EFBFBD>ֽڿ<D6BD><DABF><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD><C7B3><EFBFBD><EFBFBD>
|
|||
|
// for (size_t i = 0; i < v.size(); i++)
|
|||
|
// {
|
|||
|
// _start[i] = v._start[i]; // <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> operator= <20><EFBFBD><EEBFBD>
|
|||
|
// }
|
|||
|
|
|||
|
// _finish = _start + v.size();
|
|||
|
// _endofstorage = _start + v.capacity();
|
|||
|
// }
|
|||
|
// return *this;
|
|||
|
//}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
|
|||
|
void swap(Vector<T>& v) // <20>Լ<EFBFBD>д<EFBFBD><D0B4>swap<61><70>dz<EFBFBD><C7B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|||
|
{
|
|||
|
std::swap(_start, v._start);
|
|||
|
std::swap(_finish, v._finish);
|
|||
|
std::swap(_endofstorage, v._endofstorage);
|
|||
|
}
|
|||
|
|
|||
|
Vector<T>& operator=(Vector<T> v)
|
|||
|
{
|
|||
|
swap(v); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>swap<61><70><EFBFBD><EFBFBD><EEBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD><DBBC><EFBFBD>
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
// <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>캯<EFBFBD><ECBAAF>
|
|||
|
Vector(Vector&& v) noexcept
|
|||
|
: _start(v._start), _finish(v._finish), _endofstorage(v._endofstorage)
|
|||
|
{
|
|||
|
v._start = nullptr;
|
|||
|
v._finish = nullptr;
|
|||
|
v._endofstorage = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
// <20>ƶ<EFBFBD><C6B6><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector& operator=(Vector&& v) noexcept
|
|||
|
{
|
|||
|
if (this != &v) {
|
|||
|
delete[] _start;
|
|||
|
_start = v._start;
|
|||
|
_finish = v._start + v.size();
|
|||
|
_endofstorage = v._start + v.capacity();
|
|||
|
v._start = nullptr;
|
|||
|
v._finish = nullptr;
|
|||
|
v._endofstorage = nullptr;
|
|||
|
}
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
~Vector()
|
|||
|
{
|
|||
|
if (_start)
|
|||
|
{
|
|||
|
delete[] _start;
|
|||
|
}
|
|||
|
_start = _finish = _endofstorage = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
// <20>±<EFBFBD><C2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
T& operator[](size_t index)
|
|||
|
{
|
|||
|
if (index >= size())
|
|||
|
{
|
|||
|
throw std::out_of_range("Index out of range");
|
|||
|
}
|
|||
|
return _start[index];
|
|||
|
}
|
|||
|
|
|||
|
const T& operator[](size_t index) const
|
|||
|
{
|
|||
|
if (index >= size())
|
|||
|
{
|
|||
|
throw std::out_of_range("Index out of range");
|
|||
|
}
|
|||
|
return _start[index];
|
|||
|
}
|
|||
|
|
|||
|
// <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>
|
|||
|
void reserve(size_t newcapacity)
|
|||
|
{
|
|||
|
if (newcapacity > capacity())
|
|||
|
{
|
|||
|
T* tmp = new T[newcapacity]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|||
|
size_t len = size();
|
|||
|
if (_start)
|
|||
|
{
|
|||
|
for (size_t i = 0; i < len; i++)
|
|||
|
{
|
|||
|
tmp[i] = std::move(_start[i]); // <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
delete[] _start; // <20>ͷžɵ<C5BE><C9B5>ڴ<EFBFBD>
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
_start = tmp;
|
|||
|
_finish = tmp + len;
|
|||
|
_endofstorage = tmp + newcapacity;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// resize <20><><EFBFBD><EFBFBD><EFBFBD>Ὺ<EFBFBD>ռ䣬<D5BC><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
|
|||
|
void resize(size_t newsize, const T& val = T())
|
|||
|
{
|
|||
|
if (newsize < size())
|
|||
|
{
|
|||
|
_finish = _start + newsize;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (newsize > capacity())
|
|||
|
{
|
|||
|
reserve(newsize);
|
|||
|
}
|
|||
|
|
|||
|
while (_finish < _start + newsize)
|
|||
|
{
|
|||
|
*_finish = val;
|
|||
|
++_finish;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void push_back(const T& data)
|
|||
|
{
|
|||
|
if (_finish == _endofstorage)
|
|||
|
{
|
|||
|
size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
|
|||
|
reserve(newcapacity);
|
|||
|
}
|
|||
|
|
|||
|
*_finish = data;
|
|||
|
++_finish;
|
|||
|
}
|
|||
|
|
|||
|
// <20>ƶ<EFBFBD><C6B6>汾
|
|||
|
void push_back(T&& data)
|
|||
|
{
|
|||
|
if (_finish == _endofstorage)
|
|||
|
{
|
|||
|
reserve(capacity() == 0 ? 4 : capacity() * 2);
|
|||
|
}
|
|||
|
*_finish = std::move(data); // ʹ<><CAB9> move <20><><EFBFBD><EFBFBD>
|
|||
|
++_finish;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>ȫ<EFBFBD>ķ<EFBFBD><C4B7>ʷ<EFBFBD>ʽ
|
|||
|
T& at(size_t index)
|
|||
|
{
|
|||
|
if (index >= size()) {
|
|||
|
throw std::out_of_range("Index out of bounds");
|
|||
|
}
|
|||
|
return _start[index];
|
|||
|
}
|
|||
|
|
|||
|
void pop_back()
|
|||
|
{
|
|||
|
assert(_start < _finish);
|
|||
|
|
|||
|
--_finish;
|
|||
|
}
|
|||
|
|
|||
|
void clear()
|
|||
|
{
|
|||
|
_finish = _start;
|
|||
|
}
|
|||
|
|
|||
|
iterator insert(iterator pos, const T& data)
|
|||
|
{
|
|||
|
assert(pos <= _finish);
|
|||
|
|
|||
|
if (_finish == _endofstorage)
|
|||
|
{
|
|||
|
size_t len = pos - _start;
|
|||
|
size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
|
|||
|
reserve(newcapacity);
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>pos<6F><73>ʧЧ<CAA7>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>λ<EFBFBD><CEBB>
|
|||
|
pos = _start + len;
|
|||
|
}
|
|||
|
|
|||
|
iterator end = _finish - 1;
|
|||
|
while (end >= pos)
|
|||
|
{
|
|||
|
*(end + 1) = *end;
|
|||
|
--end;
|
|||
|
}
|
|||
|
|
|||
|
*pos = data;
|
|||
|
++_finish;
|
|||
|
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
iterator erase(iterator pos)
|
|||
|
{
|
|||
|
assert(pos < _finish);
|
|||
|
|
|||
|
iterator it = pos;
|
|||
|
while (it < _finish)
|
|||
|
{
|
|||
|
*it = *(it + 1);
|
|||
|
++it;
|
|||
|
}
|
|||
|
--_finish;
|
|||
|
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
iterator _start;
|
|||
|
iterator _finish;
|
|||
|
iterator _endofstorage;
|
|||
|
};
|
|||
|
}
|