最近事情太多了,是在没时间更新,刚好最近也在读标准库源码,其实开始已经写过自己的string类,但是发现和标准库相差甚远,所以会重新写一下,这次花了两个小时不到模仿了标准库的vector,可能内部实现方式有点点不一样,因为标准库是把对象构造和析构,空间的配置和销毁是分开的,因为我看的SGI的STL,空间配置器那部分涉及太多内存操作,包括内存池等,这都是需要很深厚的功力才能完成,学生狗一只就不准备模仿了。
这次的代码,主要参考了:cppreference,SGI STL2.9版本,STL源码剖析书。
注:暂时只测试了一部分,后续会慢慢更新
—————————————————————————————————————————
#ifndef __ZSL_Vector_H__
#define __ZSL_Vector_H__
#include <iostream>
#include <algorithm>
using namespace std;
template<typename T>
class ZSL_Vector
{
public:
using value_type = T;
using pointer = value_type*;
using const_pointer = const value_type*;
using iterator = value_type*;
using const_iterator = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using size_type = size_t;
using difference_type = ptrdiff_t;
private:
iterator start;
iterator finish;
iterator end_of_storage;
private:
pointer allocate(size_t n) { return (pointer)malloc(n * sizeof(T)); }
void construct(pointer p, const value_type& value) { new(p)value_type(value); }
void destroy_aux(pointer p) { p->~T(); }
void destroy(pointer first, pointer last) {
while(first != last){
destroy_aux(first);
++first;
}
}
void deallocate() { if(start) free(start); }
iterator uninitialized_copy(iterator first, iterator last, iterator res){
while(first < last){
construct(res, *first);
++first;
++res;
}
return res + (last - first);
}
iterator copy(iterator first, iterator last, iterator res){
while(first < last){
*res = *first;
++first, ++res;
}
return res + (last - first);
}
void uninitialized_fill(size_t n, const T& value){
start = allocate(n);
finish = start + n;
for(int i = 0; i < n; ++i)
construct(start + i, value);
end_of_storage = finish;
}
void fill(iterator first, iterator last, const value_type& value){
while(first != last){
*first = value;
++first;
}
}
void refill(const ZSL_Vector<T>& rhs){
start = allocate(rhs.size());
uninitialized_copy(rhs.start, rhs.finish, start);
finish = start + rhs.size();
end_of_storage = finish;
}
void copy_backward(iterator first, iterator last, iterator it){
while(last != first){
*it = *last;
--last;
--it;
}
}
void insert_aux(iterator pos, const T& value);
void erase_aux1(iterator pos);
void erase_aux2(iterator pos1, iterator pos2){
iterator new_finish = uninitialized_copy(pos2, finish, pos1);
destroy(new_finish, finish);
finish = new_finish;
}
public:
ZSL_Vector() : start(0), finish(0), end_of_storage(0) {}
ZSL_Vector(size_t n, const T& value) { uninitialized_fill(n, value); }
ZSL_Vector(size_t n) { uninitialized_fill(n, T()); }
ZSL_Vector(const T& value) { uninitialized_fill(1, value); }
ZSL_Vector(iterator first, iterator last){
auto ptr = first;
for(; first != last; ++first)
push_back(*first);
}
ZSL_Vector(const ZSL_Vector<T> &rhs){ refill(rhs); }
ZSL_Vector<T>& operator = (const ZSL_Vector<T> &rhs){
if(this != &rhs){
if(rhs.size() > capacity()){
iterator new_start = allocate(rhs.size());
uninitialized_copy(rhs.cbegin(), rhs.cend(), new_start);
destroy(start, finish);
deallocate();
start = new_start;
end_of_storage = finish;
}
else if(size() >= rhs.size()){
iterator tmp = copy(rhs.begin(), rhs.end(), begin());
destroy(tmp, finish);
}
else{
}
finish = start + rhs.size();
}
return *this;
}
~ZSL_Vector(){
destroy(start, finish);
deallocate();
}
void assign( size_type count, const T& value ){
if(count <= size()){
erase(end() - count, end());
finish -= count;
fill(begin(), end(), value);
}
else if(count <= capacity()){
finish += count;
fill(begin(), end(), value);
}
else{
fill(begin(), end(), value);
insert(end(), count, value);
}
}
void assign(initializer_list<T> ilist){
size_type len = ilist.size();
if(len <= size()){
erase(end() - len, end());
finish -= len;
copy(ilist.begin(), ilist.end(), begin());
}
else if(len <= capacity()){
copy(ilist.begin(), ilist.begin() + size(), begin());
finish = uninitialized_copy(ilist.begin() + size(), ilist.end(), finish);
}
else{
copy(ilist.begin(), ilist.begin() + size(), begin());
insert(end(), ilist.begin() + size(), ilist.end());
}
}
reference at(size_type pos){
if(pos >= size())
throw "out_of_range";
return *(start + pos);
}
const_reference at(size_type pos) const {
return const_cast<reference>(static_cast<ZSL_Vector<T>>(*this).start[pos]);
}
reference operator[](size_type pos){ return *(start + pos); }
const_reference operator[](size_type pos) const { return *(start + pos); }
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
iterator begin() { return start; }
const_iterator cbegin() const { return start; }
iterator end() { return finish; }
const_iterator cend() const { return finish; }
bool empty() const { return finish == 0; }
size_type size() const { return finish - start; }
size_type max_size() const { return size_type(-1)/sizeof(value_type); }
pointer data() noexcept { return (pointer)start; }
const_pointer data() const noexcept { return (const_pointer)start; }
void reserve(size_type n){
if (n < size())
erase(begin() + n, end());
else
insert(end(), n, T());
}
size_type capacity() const { return end_of_storage - start; }
void clear(){
erase(begin(), end());
}
iterator insert(iterator pos, const T& value){
size_type n = pos - begin();
if(finish != end_of_storage && pos == end()){
construct(finish, value);
++finish;
}
else
insert_aux(pos, value);
return begin() + n;
}
iterator insert(const_iterator pos, const T& value){
size_type n = pos - begin();
if(finish != end_of_storage && pos == end()){
construct(finish, value);
++finish;
}
else
insert_aux(pos, value);
return begin() + n;
}
iterator insert( const_iterator pos, T&& value ){ insert(pos, value); }
void insert( iterator pos, size_type count, const T& value );
/*
iterator insert( const_iterator pos, size_type count, const T& value );
template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last);
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );
iterator insert( const_iterator pos, std::initializer_list<T> ilist );
*/
iterator erase(iterator pos){
if(pos + 1 != end())
copy(pos + 1, end(), pos);
--finish;
destroy_aux(finish);
return pos;
}
iterator erase(const_iterator pos){
if(pos + 1 != end())
copy(pos + 1, end(), pos);
--finish;
destroy_aux(finish);
return pos;
}
iterator erase(iterator first, iterator last){
iterator tmp = copy(last, finish, first);
destroy(tmp, finish);
finish = finish - (last - first);
return first;
}
iterator erase(const_iterator first, const_iterator last){
iterator tmp = copy(last, finish, first);
destroy(tmp, finish);
finish = finish - (last - first);
return first;
}
void push_back(const T& value) {
if(finish != end_of_storage){
construct(finish, value);
++finish;
}
else
insert_aux(end(), value);
}
void pop_back() {
--finish;
destroy_aux(finish);
}
void swap(ZSL_Vector& other){
using std::swap;
swap(start, other.start);
swap(finish, other.finish);
swap(end_of_storage, other.end_of_storage);
}
};
template<typename T>
bool operator == (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
for(auto i = lhs.cbegin(), j = rhs.cbegin(); i != lhs.cend() && j != rhs.cend(); ++i, ++j)
if(*i != *j)
return false;
return lhs.size() == rhs.size();
}
template<typename T>
bool operator != (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
return !(lhs == rhs);
}
template<typename T>
bool operator < (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
for(auto i = lhs.cbegin(), j = rhs.cbegin(); i != lhs.cend() && j != rhs.cend(); ++i, ++j)
if(*i >= *j)
return false;
return lhs.size() < rhs.size();
}
template<typename T>
bool operator <= (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
for(auto i = lhs.cbegin(), j = rhs.cbegin(); i != lhs.cend() && j != rhs.cend(); ++i, ++j)
if(*i > *j)
return false;
return lhs.size() < rhs.size();
}
template<typename T>
bool operator > (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
return !(lhs <= rhs);
}
template<typename T>
bool operator >= (const ZSL_Vector<T>& lhs, const ZSL_Vector<T>& rhs)
{
return !(lhs < rhs);
}
template<typename T>
void ZSL_Vector<T>::insert_aux(iterator pos, const T& value)
{
if(finish != end_of_storage){
construct(finish, *(finish - 1));
++finish;
copy_backward(pos, finish - 2, finish - 1);
*pos = value;
}
else{
const size_type old_size = size();
const size_type len = old_size == 0 ? 1 : (2 * old_size);
iterator new_start = allocate(len);
iterator new_finish = new_start;
new_finish = uninitialized_copy(begin(), pos, new_finish);
construct(new_finish, value);
++new_finish;
new_finish = uninitialized_copy(pos, end(), new_finish);
destroy(begin(), end());
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = start + len;
}
}
template<typename T>
void ZSL_Vector<T>::insert( iterator pos, size_type count, const T& value ){
if(count != 0){
if(end_of_storage - finish >= count){
const size_type elems_after = finish - pos;
iterator old_finish = finish;
if(elems_after > count){
uninitialized_copy(finish - count, finish, finish);
finish += count;
copy_backward(pos, old_finish - count, old_finish);
fill(pos, pos + count, value);
}
else{
size_type len = count - elems_after;
while(len--){
*finish = value;
++finish;
}
uninitialized_copy(pos, pos + count, finish);
finish += elems_after;
fill(pos, pos + count, value);
}
}
else{
const size_type old_size = size();
const size_type len = old_size + std::max(old_size, count);
iterator new_start = allocate(len);
iterator new_finish = new_start;
new_finish = uninitialized_copy(start, pos, new_start);
while(count--){
*new_finish = value;
++new_finish;
}
new_finish = uninitialized_copy(pos, finish, new_finish);
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
#endif //!__ZSL_Vector_H__