码迷,mamicode.com
首页 > 其他好文 > 详细

ZSL_String

时间:2017-11-12 23:02:06      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:inter   continue   push   函数   eal   sizeof   构造函数   locate   size_type   

模仿STL标准库,无单独空间配置器alloc,无萃取机traits,无反向迭代器,end_of_storage配置不同于标准库,用了placement newnewdelete,部分函数还没写,还未测试完全,后面会慢慢修改

#ifndef __ZSL_String__
#define __ZSL_String__

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

template<typename CharT> class ZSL_String;
using String = ZSL_String<char>;

//无alloctor,用的是new,无反向迭代器,对于end_of_storage并未像标准库那样分配
template<typename CharT>
class ZSL_String
{
public:
    using value_type       = CharT;
    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 difference_type  = ptrdiff_t;
    using size_type        = size_t;
private:
    iterator start;
    iterator finish;
    iterator end_of_storage;
    static size_type nops;
private:
    void destroy(pointer p) { p->~CharT(); }
    void construct(pointer p, value_type value) { new(p)CharT(value); }
    void deallocate() { delete []start; }
    void insert_aux(size_type pos, size_type count, iterator it);
    int compare_aux(iterator first1, iterator last1, iterator first2, iterator last2);
public:
    //************三大拷贝操作************//
    //构造函数,暂时不考虑allocator
    ZSL_String() : start(0), finish(0), end_of_storage(0) {}
    ZSL_String(const CharT* s)
    {
        start = new value_type[strlen(s)];
        for(int i = 0; i < strlen(s); ++i)
            start[i] = s[i];
        finish = start + strlen(s);
        end_of_storage = finish;
    }
    ZSL_String(size_type count, const CharT& c)
    {
        start = new value_type[count];
        for(int i = 0; i < count; ++i)
            start[i] = c;
        finish = start + count;
        end_of_storage = finish;
    }
    ZSL_String(iterator first, iterator last)
    {
        start = new value_type[last - first];
        finish = start + (last - first);
        end_of_storage = finish;
        iterator tmp = start;
        while(first != last)
        {
            *tmp = *first;
            ++first, ++tmp;
        }
    }
    ZSL_String(const ZSL_String& str)
    {
        start = new value_type[str.size()];
        finish = start + str.size();
        end_of_storage = finish;
        for(int i = 0; i < str.size(); ++i)
            start[i] = str.start[i];
    }
    ZSL_String<CharT>& operator= (const ZSL_String& str)
    {
        if(*this == str)
            return *this;
        deallocate();
        start = new value_type[str.size()];
        finish = start + str.size();
        end_of_storage = finish;
        for(int i = 0; i < str.size(); ++i)
            start[i] = str.start[i];
        return *this;
    }
    ZSL_String<CharT>& operator= (const CharT* s)
    {
        if(start == s)
            return *this;
        delete[] start;
        start = new value_type[strlen(s)];
        finish = start + strlen(s);
        end_of_storage = finish;
        for (int i = 0; i < strlen(s); ++i)
            start[i] = s[i];
        return *this;
    }
    ~ZSL_String(){ deallocate(); }

    const_reference operator[] (size_type pos) const { return *(start + pos); }
    reference operator[] (size_type pos) { return *(start + pos); }

    const_reference at(size_type pos) const
    {
        try{
            if(pos > size())
                throw "out_of_range";
        }
        catch(out_of_range &e)
        {
            deallocate();
            cout << e.what() << endl;
        }
        return *(start + pos);
    }
    reference at(size_type pos){ return const_cast<CharT&>(static_cast<const ZSL_String&>(*this).at(pos)); }

    reference front() { return *start; }
    const_reference front() const { return *start; }

    const_reference back() const
    {
        if(size() == 0)
            return *finish;
        return *(finish - 1);
    }
    reference back() { return const_cast<CharT&>(static_cast<const ZSL_String&>(*this).back()); }

    const_iterator cbegin() const { return start; }
    iterator begin() { return start; }
    const_iterator cend() const
    {
        if(size() == 0)
            return finish;
        return finish;
    }
    iterator end(){ return const_cast<CharT*>(static_cast<const ZSL_String&>(*this).cend()); }

    pointer data() { return start; }
    const_pointer data() const { return start; }
    const_pointer c_str() const { return start; }

    bool empty() const { return finish == start; }
    size_type size() const { return finish - start; }
    size_type length() const { return finish - start; }
    size_type capacity() const { return end_of_storage - start; }
    size_type max_size() const { return size_type(-1)/sizeof(CharT); }

    void clear()
    {
        while(finish != start)
        {
            --finish;
            destroy(finish);
        }
    }

    ZSL_String<CharT>& insert(size_type index, size_type count, const CharT& c)
    {
        iterator it = &c;
        insert_aux(index, count, it);
        return *this;
    }
    ZSL_String<CharT>& insert(size_type index, const CharT* str)
    {
        insert_aux(index, strlen(str), str);
        return *this;
    }
    ZSL_String<CharT>& insert(size_type index, const ZSL_String<CharT>& str)
    {
        insert_aux(index, str.size(), str.start);
        return *this;
    }

    ZSL_String<CharT>& erase(size_type pos, size_type count)
    {
        if(pos + count >= size())
            throw "out of range";
        else
        {
            for(int i = pos; i < pos + count; ++i)
                *(start + i) = *(start  + i + count);
            for(int i = pos + count; i < size(); ++i)
            {
                --finish;
                destroy(finish);
            }
            while(--count)
            {
                --end_of_storage;
                iterator tmp = end_of_storage;
                --tmp;
                delete end_of_storage;
                end_of_storage = tmp;
            }
        }
        return *this;
    }

    iterator erase(iterator pos)
    {
        for(int i = pos; i < size() - 1; ++i)
            start[i] = start[i + 1];
        --finish;
        destroy(finish);
        return pos;
    }
    iterator erase(const_iterator pos) { return static_cast<ZSL_String<CharT>&>(*this).erase(pos); }
    iterator erase(iterator first, iterator last)
    {
        if((last - first) > size())
            throw "out of range";
        size_type len = last - first;
        while(first != last)
        {
            *first = *(first + len);
            ++first;
        }
        while(len--)
        {
            --finish;
            destroy(finish);
        }
        return first;
    }
    iterator erase(const_iterator first, const_iterator last)
    {
        return static_cast<ZSL_String<CharT>&>(*this).erase(first, last);
    }

    void push_back(const CharT& c)
    {
        ZSL_String<CharT> tmp(1, c);
        insert_aux(size(), 1, tmp.start);
    }
    void pop_back()
    {
        --finish;
        destroy(finish);
    }

    ZSL_String<CharT>& append(size_type count, const CharT& c)
    {
        insert(size(), count, c);
        return *this;
    }
    ZSL_String<CharT>& append(const ZSL_String<CharT>& str)
    {
        insert(size(), str.size(), str.start);
        return *this;
    }
    ZSL_String<CharT>& append(const ZSL_String& str, size_type pos, size_type count)
    {
        try{
            if(pos + count >= str.size())
                throw "out of range";
        }
        catch(out_of_range& e)
        {
            deallocate();
            cout << e.what() << endl;
        }
        insert(size(), count, str.start + pos);
        return *this;
    }
    ZSL_String<CharT>& append(const CharT* str, size_type count)
    {
        ZSL_String<CharT> tmp(str);
        insert(tmp, 0, count);
        return *this;
    }
    ZSL_String<CharT>& append(const CharT* str)
    {
        append(str, strlen(str));
        return *this;
    }

    ZSL_String<CharT>& operator+= (const ZSL_String<CharT>& str)
    {
        append(str);
        return *this;
    }
    ZSL_String<CharT>& operator+= (const CharT& c)
    {
        push_back(c);
        return *this;
    }
    ZSL_String<CharT>& operator+= (const CharT* str)
    {
        append(str);
        return *this;
    }

    int compare(const ZSL_String<CharT>& str) const
    {
        return compare_aux(start, finish, str.start, str.finish);
    }
    int compare(size_type pos, size_type count, const ZSL_String<CharT>& str) const
    {
        if(count + pos >= size())
            throw "out_of_range";
        return compare_aux(start + pos, start + pos + count, str.start, str.finish);
    }
    int compare(size_type pos1, size_type count1, const ZSL_String<CharT>& str, size_type pos2, size_type count2)
    {
        if(pos1 + count1 >= size())
            throw "out_of_range";
        if(pos2 + count2 >= str.size())
            throw "out_of_range";
        return compare_aux(start + pos1, start + pos1 + count1, str.start + pos2, str.start + pos2 + count2);
    }
    int compare(const CharT* str) const
    {
        ZSL_String<CharT> tmp(str);
        return compare_aux(start, finish, tmp.start, tmp.finish);
    }
    int compare(size_type pos, size_type count, const CharT* str) const
    {
        ZSL_String<CharT> tmp(str);
        return compare_aux(start + pos, start + pos + count, tmp.start, tmp.finish);
    }
    int compare(size_type pos1, size_type count1, const CharT* str, size_type count2) const
    {
        ZSL_String<CharT> tmp(str);
        return compare_aux(start + pos1, start + pos1 + count1, tmp.start, tmp.start + count2);
    }

    ZSL_String<CharT>& replace(size_type pos, size_type count, const ZSL_String<CharT>& str)
    {
        return replace(pos, count, str, 0, str.size());
    }
    ZSL_String<CharT>& replace(size_type pos1, size_type count1, const ZSL_String<CharT>& str, size_type pos2, size_type count2)
    {
        size_type len = size();
        if((pos1 + count1 > len) || (pos2 + count2) >= str.size())
            throw "out of range";
        size_type pos = pos1 + count1;
        iterator new_start = new value_type[len + count2 - count1];
        for(int i = 0; i < pos1; ++i)
            new_start[i] = start[i];
        for(int i = pos1; i < pos1 + count2; ++i)
            new_start[i] = str[pos2++];
        for(int i = pos1 + count2; i < len + count2 - count1; ++i)
            new_start[i] = start[pos++];
        deallocate();
        start = new_start;
        finish = start + len + count2 - count1;
        end_of_storage = finish;
        return *this;
    }

    ZSL_String<CharT> substr(size_type pos, size_type count) const
    {
        if(pos + count >= size())
            throw "out of range";
        return new ZSL_String<CharT>(start + pos, start + pos + count);
    }

    size_type copy(CharT* dest, size_type pos, size_type count) const
    {
        if(pos + count >= size())
            throw "out of range";
        for(int i = pos; i < pos + count; ++i)
            *dest++ = start[i];
        return count;
    }

    void resize(size_type count);
    void resize(size_type count, const CharT& c);

    void swap(ZSL_String& other)
    {
        using std::swap;
        swap(start, other.start);
        swap(finish, other.finish);
    }

    size_type find(const ZSL_String& str, size_type pos = 0) const
    {
        if(pos >= size())
            throw "out of range";
        while((start + pos) != finish)
        {
            if(compare_aux(start + pos, start + pos + str.size(), str.start, str.finish) == 0)
                return pos;
            ++pos;
        }
        return -1;
    }
    size_type find(const CharT* str, size_type pos, size_type count) const
    {
        if(pos + count >= size())
            throw "out of range";
        while((start + pos + count) != finish)
        {
            if(compare(start + pos, start + pos + count, str) == 0)
                return pos;
            ++pos;
        }
        return -1;
    }
    size_type find(const CharT* str, size_type pos = 0) const
    {
        if(pos >= size())
            throw "out of range";
        while((start + pos) != finish)
        {
            if(compare(start + pos, start + pos + strlen(str), str) == 0)
                return pos;
            ++pos;
        }
        return -1;
    }
    size_type find(const CharT& c, size_type pos = 0) const
    {
        if(pos >= size())
            throw "out of range";
        while(*(start + pos) != c)
            ++pos;
        return pos;
    }
};

template<typename CharT>
size_t ZSL_String<CharT>::nops = -1;

template<typename CharT>
void ZSL_String<CharT>::insert_aux(size_type pos, size_type count, iterator it)
{
    if(pos + count < capacity())
    {
        iterator new_finish = start + pos + count;
        while(count)
        {
            --new_finish;
            construct(new_finish, *(--finish));
        }
        while((start + pos) != new_finish)
            *(start + pos) = *it++;
        finish = start + pos + count;
    }
    else
    {
        iterator new_start = new CharT[size() + count];
        for (int i = 0; i < pos; ++i, ++start)
            new_start[i] = *start;
        for (int i = pos; i < pos + count; ++i, ++it)
            new_start[i] = *it;
        for (int i = pos + count; i < size() + count; ++i, ++start)
            new_start[i] = *start;
        deallocate();
        start = new_start;
        finish = start + size() + count;
        end_of_storage = finish;
    }
}

template<typename CharT>
int ZSL_String<CharT>::compare_aux(iterator first1, iterator last1, iterator first2, iterator last2)
{
    int comp;
    while(first1 != last1 && first2 != last2)
    {
        if(strcmp(*first1, *first2) == 0)
        {
            comp = 0;
            continue;
        }
        else
        {
            return strcmp(*first1, *first2);
        }
    }
    if(comp == 0 && first1 != last1)
        return 1;
    if(comp == 0 && first2 != last2)
        return -1;
}

template<typename CharT>
void ZSL_String<CharT>::resize(size_type count)
{
    if(count < size())
    {
        while(finish != (start + count))
        {
            --finish;
            destroy(finish);
        }
    }
    if(count > capacity())
    {
        iterator new_start = new CharT[count];
        finish = new_start;
        for(int i = 0; i < size(); ++i)
            *finish++ = start[i];
        deallocate();
        start = new_start;
        end_of_storage = start + count;
    }
}

template<typename CharT>
void ZSL_String<CharT>::resize(size_type count, const CharT& c)
{
    if(count < size())
    {
        while(finish != (start + count))
        {
            --finish;
            destroy(finish);
        }
    }
    else if(count < capacity())
    {
        while(finish != (start + count))
        {
            *finish = c;
            ++finish;
        }
    }
    else
    {
        iterator new_start = new CharT[count];
        finish = new_start;
        for(int i = 0; i < size(); ++i)
            *finish++ = start[i];
        for(int i = size(); i < count; ++i)
            *finish++ = c;
        deallocate();
        start = new_start;
        end_of_storage = finish;
    }
}

template<typename CharT>
ZSL_String<CharT> operator+ (ZSL_String<CharT>& str1, ZSL_String<CharT>& str2)
{
    str1.append(str2);
    return str1;
}

template<typename CharT>
ZSL_String<CharT> operator+ (CharT& c, ZSL_String<CharT>& str)
{
    ZSL_String<CharT> tmp(c);
    tmp.append(str);
    return tmp;
}

template<typename CharT>
ZSL_String<CharT> operator+ (ZSL_String<CharT>& str, CharT& c)
{
    str.push_back(c);
    return str;
}

template<typename CharT>
ZSL_String<CharT> operator+ (CharT* str1, ZSL_String<CharT>& str2)
{
    ZSL_String<CharT> newStr(str1);
    newStr.append(str2);
    return newStr;
}

template<typename CharT>
ZSL_String<CharT> operator+ (ZSL_String<CharT>& str1, CharT* str2)
{
    str1.append(str2);
    return str1;
}

template<typename CharT>
bool operator== (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return str1.compare(str2) == 0;
}

template<typename CharT>
bool operator!= (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return !(str1 == str2);
}

template<typename CharT>
bool operator< (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return str1.compare(str2) == -1;
}

template<typename CharT>
bool operator> (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return str1.compare(str2) == 1;
}

template<typename CharT>
bool operator<= (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return (str1.compare(str2) == -1) || (str1.compare(str2) == 0);
}

template<typename CharT>
bool operator>= (const ZSL_String<CharT>& str1, const ZSL_String<CharT>& str2)
{
    return !(str1 <= str2);
}
#endif //__ZSL_String__

 

ZSL_String

标签:inter   continue   push   函数   eal   sizeof   构造函数   locate   size_type   

原文地址:http://www.cnblogs.com/CoderZSL/p/7823304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!