线性表 Vector
#ifndef SJTU_VECTOR_HPP
#define SJTU_VECTOR_HPP
#include <cstddef>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <climits>
#include <cstddef>
namespace sjtu {
class exception
{
protected:
const std::string variant = "";
std::string detail = "";
public:
exception() {}
exception(const exception &ec) : variant(ec.variant), detail(ec.detail) {}
virtual std::string what() {
return variant + " " + detail;
}
};
class index_out_of_bound : public exception {};
class runtime_error : public exception {};
class invalid_iterator : public exception {};
class container_is_empty : public exception {};
template<typename T>
class vector {
private:
T* data;
size_t currentsize;
size_t maxsize;
void delete00()
{
for (size_t i = 0; i != maxsize; ++i)
{
data[i].~T();
}
free(data);
}
public:
class const_iterator;
class iterator;
void doublespace();
vector(int inputsize = 10);
vector(const vector<T> &other);
vector(const std::vector<T> &other);
~vector() {delete00();}
vector<T>& operator=(const vector<T> &other);
T & at(const size_t &pos);
const T & at(const size_t &pos) const;
T & operator[](const size_t &pos);
const T & operator[](const size_t &pos) const;
const T & front() const;
const T & back() const;
bool empty() const;
size_t size() const;
size_t capacity() const;
void clear();
void push_back(const T &value);
void pop_back();
iterator begin()
{
return iterator(this,0);
}
const_iterator cbegin() const {
return const_iterator(this,0);
}
iterator end()
{
return iterator(this,currentsize);
}
const_iterator cend() const
{
return const_iterator(this,currentsize);
}
iterator insert(iterator it, const T &value)
{
if(currentsize>=maxsize)
{
doublespace();
}
size_t inipos = it.thepos();
iterator right=iterator(this,currentsize);
while(right.thepos()>it.thepos())
{
*right=*(right-1);
right --;
}
data[inipos] = value;
currentsize ++;
return it;
}
iterator insert(const size_t &ind, const T &value)
{
if(currentsize>=maxsize)
{
doublespace();
}
if(ind>currentsize)
{
throw index_out_of_bound();
}
size_t right = currentsize;
while(right>ind)
{
data[right]=data[right-1];
right--;
}
data[right-1]=value;
iterator tmp=iterator(this,right-1);
currentsize ++;
return tmp;
}
iterator erase(iterator it)
{
size_t tmp = it.thepos();
size_t theend = currentsize-1;
while(tmp<theend)
{
data[tmp]=data[tmp+1];
tmp++;
}
currentsize--;
return iterator(this,it.thepos());
}
iterator erase(const size_t &ind)
{
size_t k = ind;
while(k<currentsize-1)
{
data[k]=data[k+1];
}
currentsize--;
return iterator(this,ind);
}
};
template <typename T>
class vector<T>::const_iterator
{
private:
vector* vec;
size_t pos;
public:
vector* thevec()
{
return vec;
}
size_t thepos()
{
return pos;
}
const_iterator(vector* inputvec, size_t inputpos)
{
vec = inputvec;
pos = inputpos;
}
const_iterator(const vector* ptrvec, size_t ptrpos) : vec(const_cast<vector *>(ptrvec)), pos(ptrpos) {}
const_iterator operator+(const int &n) const
{
return const_iterator(vec, pos + n);
}
const_iterator operator-(const int &n) const
{
pos -= n;
return *this;
}
int operator-(const iterator &rhs) const
{
if (vec != rhs.vec)
{
throw invaild_iterator();
}
return rhs.pos - pos;
}
const_iterator operator+=(const int &n)
{
pos += n;
return *this;
}
const_iterator operator-=(const int &n)
{
pos -= n;
return *this;
}
const_iterator operator++(int)
{
size_t ii = pos;
++pos;
return const_iterator(vec, ii);
}
const_iterator& operator++()
{
pos++;
return *this;
}
const_iterator operator--(int)
{
const_iterator it(vec, pos);
pos--;
return it;;
}
const_iterator& operator--()
{
pos--;
return *this;
}
const T& operator*() const
{
return vec->data[pos];
}
bool operator==(const iterator &rhs) const
{
return rhs.vec == vec&&rhs.pos == pos;
}
bool operator==(const const_iterator &rhs) const
{
return rhs.vec == vec&&rhs.pos == pos;
}
bool operator!=(const iterator &rhs) const
{
return !(*this == rhs);
}
bool operator!=(const const_iterator &rhs) const
{
return !(*this == rhs);
}
};
template <typename T>
class vector<T>::iterator
{
private:
vector* vec;
size_t pos;
public:
vector* thevec()
{
return vec;
}
size_t thepos()
{
return pos;
}
iterator(vector* inputvec, size_t inputpos)
{
vec = inputvec;
pos = inputpos;
}
iterator operator+(const int &n) const
{
return iterator(vec, pos + n);
}
iterator operator-(const int &n) const
{
return iterator(vec, pos - n);
}
int operator-(const iterator &rhs) const
{
if (vec != rhs.vec)
{
throw invaild_iterator();
}
return rhs.pos - pos;
}
iterator operator+=(const int &n)
{
pos += n;
return *this;
}
iterator operator-=(const int &n)
{
pos -= n;
return *this;
}
iterator operator++(int)
{
iterator it = iterator(vec, pos);
pos++;
return it;
}
iterator& operator++()
{
pos++;
return *this;
}
iterator operator--(int)
{
iterator it(vec, pos);
pos--;
return it;
}
iterator& operator--()
{
pos--;
return *this;
}
T& operator*() const
{
return vec->data[pos];
}
bool operator==(const iterator &rhs)
{
return (vec == rhs.vec && pos == rhs.pos);
}
bool operator==(const const_iterator &rhs)
{
return (vec == rhs.vec && pos == rhs.pos);
}
bool operator!=(const iterator &rhs) const
{
return !(vec == rhs.vec && pos == rhs.pos);
}
bool operator!=(const const_iterator &rhs) const
{
return !(vec == rhs.vec && pos == rhs.pos);
}
};
template <class T>
void vector<T>::doublespace()
{
T*p = (T*)malloc(maxsize * 2 * sizeof(T));
memset(p, 0, maxsize * 2 * sizeof(T));
for (int i = 0; i < currentsize; i++)
{
p[i] = data[i];
}
delete00();
data = p;
maxsize *= 2;
}
template<class T>
vector<T>::vector(int inputsize = 10)
{
currentsize = 0;
maxsize = inputsize;
data = (T *)malloc(maxsize * sizeof(T));
memset(data, 0, maxsize * sizeof(T));
}
template <class T>
vector<T>::vector(const vector<T> &other)
{
currentsize = other.currentsize;
maxsize = other.maxsize;
data = (T *)malloc(maxsize * sizeof(T));
memset(data, 0, maxsize * sizeof(T));
for (size_t i = 0; i < other.currentsize; i++)
{
data[i] = other[i];
}
}
template <class T>
vector<T>::vector(const std::vector<T> &other)
{
currentsize = other.size();
maxsize = other.size();
data = (T *)malloc(maxsize * sizeof(T));
memset(data, 0, maxsize * sizeof(T));
for (size_t i = 0; i < other.size(); i++)
{
data[i] = other[i];
}
}
template <class T>
vector<T>& vector<T>::operator=(const vector<T> &other)
{
if (&other == this) return*this;
T*p = (T*)malloc(maxsize * sizeof(T));
memset(p, 0, maxsize * sizeof(T));
for (int i = 0; i < other.currentsize; i++)
{
p[i] = other.data[i];
}
delete00();
currentsize = other.currentsize;
maxsize = other.maxsize;
data = p;
return *this;
}
template <class T>
T & vector<T>::at(const size_t &pos)
{
if (!(pos >= 0 && pos<currentsize))
{
throw index_out_of_bound();
}
else
{
return data[pos];
}
}
template <class T>
const T & vector<T>::at(const size_t &pos) const
{
if (!(pos >= 0 && pos<currentsize))
{
throw index_out_of_bound();
}
else
{
return data[pos];
}
}
template <class T>
T & vector<T>::operator[](const size_t &pos)
{
if (!(pos >= 0 && pos<currentsize))
{
throw index_out_of_bound();
}
else
{
return data[pos];
}
}
template <class T>
const T & vector<T>::operator[](const size_t &pos) const
{
if (!(pos >= 0 && pos<currentsize))
{
throw index_out_of_bound();
}
else
{
return data[pos];
}
}
template <class T>
const T & vector<T>::front() const
{
if (!currentsize)
{
throw container_is_empty();
}
else
{
return data[0];
}
}
template <class T>
const T & vector<T>::back() const
{
if (!currentsize)
{
throw container_is_empty();
}
else
{
return data[currentsize - 1];
}
}
template <class T>
bool vector<T>::empty() const
{
return currentsize == 0;
}
template <class T>
size_t vector<T>::size() const
{
return currentsize;
}
template <class T>
size_t vector<T>::capacity() const
{
return maxsize;
}
template <class T>
void vector<T>::clear()
{
currentsize = 0;
}
template <class T>
void vector<T>::push_back(const T &value)
{
if (currentsize == maxsize)
{
doublespace();
}
data[currentsize++] = value;
}
template <class T>
void vector<T>::pop_back()
{
currentsize--;
}
}
#endif