ZSL_Vector

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZSL_Vector相关的知识,希望对你有一定的参考价值。

最近事情太多了,是在没时间更新,刚好最近也在读标准库源码,其实开始已经写过自己的string类,但是发现和标准库相差甚远,所以会重新写一下,这次花了两个小时不到模仿了标准库的vector,可能内部实现方式有点点不一样,因为标准库是把对象构造和析构,空间的配置和销毁是分开的,因为我看的SGI的STL,空间配置器那部分涉及太多内存操作,包括内存池等,这都是需要很深厚的功力才能完成,学生狗一只就不准备模仿了。

这次的代码,主要参考了:cppreference,SGI STL2.9版本,STL源码剖析书。

注:暂时只测试了一部分,后续会慢慢更新

—————————————————————————————————————————

#ifndef __ZSL_Vector__
#define __ZSL_Vector__

#include <iostream>
#include <algorithm>
#include <exception>
using namespace std;

template<typename T>
class ZSL_Vector
{
public:
    typedef T value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type* iterator;
    typedef const value_type* const_iterator;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

private:
    iterator start;
    iterator finish;
    iterator end_of_storage;

    void fill(size_t n, const T& value)
    {
        start = new T[n];
        for(int i = 0; i < n; ++i)
            start[i] = value;
        finish = start + n;
        end_of_storage = finish;
    }

    void refill(const ZSL_Vector<T>& rhs)
    {
        start = new T[rhs.capacity()];
        for(auto i = rhs.cbegin(), j = 0; i != rhs.cend(); ++i, ++j)
            start[j] = *i;
        finish = start + rhs.size();
        end_of_storage = rhs.capacity();
    }

    void destroy(){ delete []start; }
    void insert_aux(iterator pos, const T& value);
    void erase_aux1(iterator pos)
    {
        if(pos + 1 != end())
        {
            iterator tmp = pos;
            iterator ptr = pos + 1;
            for(; ptr != end(); ++ptr, ++pos)
                *pos = *ptr;
            finish->~T();
            --finish;
        }
    }
    void erase_aux2(iterator pos1, iterator pos2);

public:
    //构造函数
    ZSL_Vector() : start(0), finish(0), end_of_storage(0) {}
    ZSL_Vector(size_t n, const T& value) { fill(n, value); }
    ZSL_Vector(size_t n) { fill(n, T()); }
    ZSL_Vector(const T& value) { fill(1, value); }
    ZSL_Vector(iterator first, iterator last)
    {
        auto ptr = first;
        for(; first != last; ++first)
            push_back(*first);
    }
    ZSL_Vector(initializer_list<T> ilist)
    {
        start = new T[ilist.size()];
        size_type j = 0;
        for(auto i = ilist.begin(); i != ilist.end(); ++i)
            start[j++] = *i;
        finish = start + ilist.size();
        end_of_storage = finish;
    }
    //拷贝构造函数
    ZSL_Vector(const ZSL_Vector<T> &rhs){ refill(rhs); }
    //拷贝赋值
    ZSL_Vector& operator = (const ZSL_Vector<T> &rhs)
    {
        if(*this != rhs)
        {
            destroy();
            refill(rhs);
        }
        return *this;
    }
    //析构函数
    ~ZSL_Vector(){ destroy(); }

    //需要抛出异常
    reference at(size_type pos)
    {
        try{
            if(pos >= (finish - start))
                throw "out_of_range";
        }
        catch(out_of_range &e){
            destroy();
            cout << e.what() << endl;
        }
        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); }

    void reserve(size_type n);

    size_type capacity() const { return end_of_storage - start; }

    void clear() { destroy(); }

    iterator insert(iterator pos, const T& value)
    {
        insert_aux(pos, value);
        return pos;
    }
    iterator insert(const_iterator pos, const T& value)
    {
        insert_aux(pos, value);
        return pos;
    }

    iterator erase(iterator pos)
    {
        erase_aux1(pos);
        return pos;
    }
    iterator erase(const_iterator pos)
    {
        erase_aux1(pos);
        return pos;
    }
    iterator erase(iterator first, iterator last)
    {
        erase_aux2(first, last);
        return first;
    }
    iterator erase(const_iterator first, const_iterator last)
    {
        erase_aux2(first, last);
        return first;
    }

    void push_back(const T& value) { insert_aux(finish, value); }

    void pop_back() { erase_aux(finish, 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)
    {
        new(finish)T();
        ++finish;
        auto tmp = finish - 1;
        for(; tmp != pos - 1; --tmp)
            *tmp = *(tmp - 1);
        *pos = value;
    }
    else
    {
        const size_type old_size = size();
        const size_type len = old_size == 0 ? 1 : (2 * old_size);
        iterator new_start = new T[len];
        iterator new_finish = new_start + old_size + 1;
        iterator ptr = new_start;
        iterator tmp = begin();
        for(; tmp != pos; ++ptr, ++tmp)
            *ptr = *tmp;
        *pos = *ptr = value;
        for(auto ptr = pos + 1; tmp != finish; ++ptr, ++tmp)
            *ptr = *tmp;
        destroy();
        start = new_start;
        finish = new_finish;
        end_of_storage = start + len;
    }
}

template<typename T>
void ZSL_Vector<T>::erase_aux2(iterator pos1, iterator pos2)
{
    iterator new_pos = pos1;
    iterator ptr = pos1 + 1;
    for(; ptr != end(); ++ptr, ++pos1, ++pos2)
        *pos1 = *ptr;
    for(; pos1 != pos2; ++ptr)
    {
        delete ptr;
        --finish;
    }
    pos1 = new_pos;
}

template<typename T>
void ZSL_Vector<T>::reserve(size_type n)
{
    if (n <= capacity())
        return;
    iterator new_start = new T[n];
    iterator new_finsh = new_start;

    int flag = 0;
    while (start != finish)
    {
        new_start[flag++] = *start;
        ++start;
        ++new_finsh;
    }
    destroy();
    start = new_start;
    finish = new_finsh;
    end_of_storage = new_start + n;
}
#endif //__ZSL_Vector__

 

以上是关于ZSL_Vector的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数