从零开始写STL-string类型

    class string
    {
    public:
        typedef size_t size_type;
        typedef char* iterator;
        typedef char value_type;
    private:
        char *start, *end_of_storage, *End;
        std::allocator<char> data_allocator;
        void DeallocateAndDestory()
        {
            data_allocator.deallocate(start, end_of_storage - start);
        }
        //重新构造元素 
        void reallocate(size_t new_size = 0)
        {
            size_t old_size = size();
            if (new_size == 0)
                new_size = size() ? 2 * size() : 1;
            char* new_start = data_allocator.allocate(new_size);
            std::copy(start, start + size(), new_start);
            DeallocateAndDestory();
            start = new_start;
            End = new_start + old_size;
            end_of_storage = new_start + new_size;
        }
        //移动构造元素
        /*void reallocate()
        {
        int old_size = size();
        int new_size = size() ? 2 * size() : 1;
        char* new_start = data_allocator.allocate(new_size);
        char* pos = new_start;
        char* old_pos = start;
        for (int i = 0; i < old_size; i++)
        data_allocator.construct(pos++, std::move(*old_pos)), old_pos++;
        data_allocator.deallocate(start, old_size);
        start = new_start;
        End = new_start + old_size;
        end_of_storage = new_start + new_size;
        }*/
    public:
        //debug
        void print()
        {
            for (auto it = start; it != End; it++)
                std::cout << *it;
            std::cout << std::endl;
        }
        //Construct
        string()
        {
            start = end_of_storage = End = nullptr;
        }
        string(const string& rhs)
        {
            start = end_of_storage = End = nullptr;
            append(rhs);
        }
        string(string&& rhs)noexcept :start(rhs.start), end_of_storage(rhs.end_of_storage), End(rhs.End)
        {
            rhs.start = rhs.end_of_storage = rhs.End = nullptr;
        }
        string(const char* s)
        {
            if (s == nullptr)
                string();
            else
            {
                int cnt = 0;
                for (; s[cnt] != '\0'; cnt++) {}
                start = data_allocator.allocate(cnt);
                std::uninitialized_copy_n(s, cnt, start);
                end_of_storage = End = start + cnt;
            }
        }
        string(size_type n, char c)
        {
            start = data_allocator.allocate(n);
            std::uninitialized_fill_n(start, n, c);
            end_of_storage = End = start + n;
        }
        string(const char* s, size_t n)
        {
            start = data_allocator.allocate(n);
            std::uninitialized_copy_n(s, n, start);
            End = end_of_storage = start + n;
        }
        ~string()
        {
            DeallocateAndDestory();
        }
        //Iterator
        const iterator begin() const
        {
            return start;
        }

        const iterator end() const
        {
            return End;
        }

        iterator begin()
        {
            return start;
        }
        iterator end()
        {
            return End;
        }

        //Capacity
        void clear()
        {
            DeallocateAndDestory();
            End = start = end_of_storage = nullptr;
        }
        bool empty()const
        {
            return (start == End);
        }
        const size_type size() const
        {
            return End - start;
        }
        const size_type length() const
        {
            return size();
        }
        const size_type capacity() const
        {
            return end_of_storage - start;
        }
        void resize(size_type n)
        {
            resize(n, value_type());
        }
        void resize(size_type n, const value_type &val)
        {
            if (n <= size())
            {
                End = start + n;
            }
            else
            {
                append(string(n - size(), val));
            }
        }
        void reserve(size_type res_arg = 0)
        {
            if (res_arg + size() < capacity()) return;
            reallocate(res_arg + size());
        }
        //Modifiers
        value_type& operator[](size_type index)
        {
            if (index < 0 || index >= size())
            {
                std::cerr << "index out of range!" << std::endl;
                std::exit(1);
            }
            else
            {
                return *(start + index);
            }
        }
        value_type& front()
        {
            return *start;
        }
        value_type& back()
        {
            auto tmp = end();
            return *(--tmp);
        }
        void push_back(const value_type& val)
        {
            if (size() == capacity())
                reallocate();
            *End = val;
            End++;
        }
        void pop_back()
        {
            if (empty())
            {
                std::cerr << "Error : pop_back() on empty String!" << std::endl;
                exit(1);
            }
            End--;
        }
        void swap(string& rhs)
        {
            std::swap(start, rhs.start);
            std::swap(end_of_storage, rhs.end_of_storage);
            std::swap(End, rhs.End);
        }
        void append(const string& rhs)
        {
            if (rhs.empty()) return;
            if (capacity()<size() + rhs.size()) reallocate(size() + rhs.size());
            std::copy(rhs.start, rhs.end_of_storage, End);
            End += rhs.size();
        }
        void append(const char* s)
        {
            if (s == nullptr) return;
            size_t cnt = 0;
            for (; s[cnt] != '\0'; cnt++) {}
            if (capacity() < size() + cnt)  reallocate(size() + cnt);
            std::uninitialized_copy_n(s, cnt, End);
            End += cnt;
        }
        void append(const char* s, size_t l, size_t r)
        {
            if (r <= l ) return;
            if (s == nullptr) return;
            if (capacity()<size() + r - l - 1) reallocate(size() + r - l);
            std::uninitialized_copy_n(s + l, r - l, End);
            End += r - l;
        }
        string& operator+=(const char c)
        {
            (*this).push_back(c);
            return *this;
        }
        string& operator+=(const string& rhs)
        {
            (*this).append(rhs);
            return *this;
        }
        string operator+(const string& rhs)
        {
            string tmp(*this);
            return tmp += rhs;
        }
        string& operator=(const string& str)
        {
            return assign(str);
        }
        string& operator=(const char* s)
        {
            return assign(string(s));
        }
        string& operator=(char c)
        {
            return assign(string((size_type)1, c));
        }
        string& assign(const string& str)
        {
            clear();
            append(str);
            return (*this);
        }
        string& assign(const char* s)
        {
            clear();
            if (s == nullptr) return *this;
            size_t cnt = 0;
            while (s[cnt] != '\0') cnt++;
            start = data_allocator.allocate(cnt);
            End = std::uninitialized_copy_n(s, cnt, start);
            end_of_storage += cnt;
        }
        string& assign(size_type n, char c)
        {
            clear();
            if (n == 0) return *this;
            start = data_allocator.allocate(n);
            End = end_of_storage = std::uninitialized_fill_n(start, n, c);
        }
        string& insert(size_type pos, const string& rhs)
        {
            pos = std::min(size(), pos);
            size_type new_size = size() + rhs.size();
            iterator new_start = data_allocator.allocate(new_size);
            std::copy(start, start + pos, new_start);
            std::copy(rhs.start, rhs.End, new_start + pos);
            std::copy(start + pos, End, new_start + pos + rhs.size());
            start = new_start;
            end_of_storage = End = new_size + new_start;
            return *this;
        }
        string& insert(size_type pos, const char* s, size_type n)
        {
            return insert(pos, string(s, n));
        }
        string& insert(size_type pos, const char* s)
        {
            return insert(pos, string(s));
        }
        iterator insert(iterator pos, const value_type& val)
        {
            size_type index = pos - start;
            if (size() == capacity())
                reallocate();
            pos = start + index;
            if (pos > end()) pos = end();
            std::copy(pos, End, pos + 1);
            (*pos) = val;
            End++;
            return pos;
        }
        string& insert(size_type pos, size_type num, const value_type& val)
        {
            return insert(pos, string(num, val));
        }
        string& insert(iterator pos, size_type num, const value_type& val)
        {
            return insert(pos - start, string(num, val));
        }
        string& erase(size_type pos, size_type n)
        {
            std::copy(pos + n + start, End, start + pos);
            End = End - n;
            return *this;
        }
        iterator erase(iterator pos)
        {
            std::copy(pos + 1, End, pos);
            End--;
            return pos;
        }
        iterator erase(iterator first, iterator last)
        {
            std::copy(last, End, first);
            End = End - (last - first);
            return first;
        }
        string& replace(size_t pos, size_t n, const string& str)
        {
            erase(pos, n);
            insert(pos, str);
            return *this;
        }
        string& replace(iterator i1, iterator i2, const string& str)
        {
            insert(erase(i1, i2) - start, str);
            return *this;
        }
        const char* c_str() const
        {
            if (empty()) return "";
            char* ret = new char[End - start + 1];
            std::uninitialized_copy(start, End, ret);
            ret[End - start] = '\0';
            return ret;
        }
        bool operator == (const string& rhs)
        {
            if (size() != rhs.size())
                return false;
            else
            {
                for (auto i = start, j = rhs.start; i != End; i++, j++)
                {
                    if ((*i) != (*j))
                        return false;
                }
                return true;
            }
        }
        bool operator == (const string& rhs) const
        {
            if (size() != rhs.size())
                return false;
            else
            {
                for (auto i = start, j = rhs.start; i != End; i++, j++)
                {
                    if ((*i) != (*j))
                        return false;
                }
                return true;
            }
        }
        int compare(const string& rhs)
        {
            iterator i = start, j = rhs.start;
            while (i != End && j != rhs.End)
            {
                if ((*i) > (*j))
                    return 1;
                else if ((*i) < (*j))
                    return -1;
                else
                    i++, j++;
            }
            if (i == End&&j == rhs.End)
                return 0;
            else if (i == End)
                return -1;
            else
                return 1;
        }
        size_type copy(char* s, size_type n, size_type pos = 0) const
        {
            if (pos + n >= size())
            {
                std::cerr << "out of range" << std::endl;
                std::exit(1);
            }
            std::uninitialized_copy_n(start + pos, n, s);
            return n;
        }
        size_t find(const string& str, size_t pos = 0) const
        {
            if (size() - pos < str.size())
                return (size_type)(-1);
            for (auto it = start + pos; it != End; it++)
            {
                auto i = it, j = str.start;
                while (j<str.End && *i == *j)
                    i++, j++;
                if (j == str.End)
                    return it - start;
            }
            return (size_type)(-1);
        }
        size_t find(const char* s, size_t pos, size_t n) const
        {
            return find(string(s, n), pos);
        }
        size_t find(const char* s, size_t pos = 0) const
        {
            return find(string(s), pos);
        }
        size_t find(char c, size_t pos = 0) const
        {
            if (empty())
                return size_type(-1);
            else
            {
                for (auto it = start; it != End; it++)
                    if (*it == c)
                        return it - start;
                return size_type(-1);
            }
        }
        string substr(size_t pos = 0, size_t n = 0)
        {
            return string(start + pos, n);
        }
        size_t rfind(string& rhs, size_t pos = 0)
        {
            if (pos == 0) pos = size();
            for (auto it = std::min(start + pos, End - 1); it != start - 1; it--)
            {
                size_t i;
                for (i = 0; i < rhs.size();)
                    if (rhs[i] == *(it + i))
                        i++;
                    else
                        break;
                if (i == rhs.size())
                    return it - start;
            }
            return size_t(-1);
        }
        size_t rfind(const char& c, size_t pos = 0)
        {
            if (pos == 0) pos = size();
            for (auto it = std::min(End - 1, start + pos); it != start; it--)
            {
                if (*it == c)
                    return it - start;
            }
            return size_t(-1);
        }
        size_t rfind(const char* str)
        {
            return rfind(string(str));
        }
        size_t find_first_of(const string& rhs, size_t pos = 0)
        {
            for (auto it = start + pos; it != End; it++)
            {
                auto i = rhs.start;
                while (i != rhs.End)
                {
                    if (*i == *it)
                        break;
                    i++;
                }
                if (i != rhs.End)
                    return it - start;
            }
            return (size_t)-1;
        }
        size_t find_first_of(const char& c, size_t pos = 0)
        {
            for (auto it = start + pos; it != End; it++)
            {
                if (*it == c)
                    return it - start;
            }
            return (size_t)-1;
        }
        size_t find_last_of(const char &c, size_t pos = 0)
        {
            if (pos == 0) pos = size();
            for (auto it = pos + start; it != start - 1; it--)
                if (*it == c)
                    return it - start;
            return (size_t)-1;
        }
        size_t find_last_of(const char* str, size_t pos, size_t len)
        {
            size_t l = 0;
            for (size_t i = 0; str[i] != '\0'; i++)
                l++;
            for (auto it = start + pos; it != start + pos - len; it--)
            {
                size_t i;
                for (i = 0; str[i] != '\0'; i++)
                    if (str[i] == *it)
                        break;
                if (str[i] != '\0') return it - start;
            }
            return size_t(-1);
        }
        size_t find_last_of(const string& rhs, size_t pos)
        {
            for (auto it = start + pos; it != start - 1; it--)
            {
                size_t i = 0;
                while (rhs.start + i != rhs.End)
                    if (*it == *(start + i))
                        break;
                    else
                        i++;
                if (rhs.size() != i)    return it - start;
            }
            return size_t(-1);
        }
        size_t find_first_not_of(const string& rhs)
        {
            for (auto it = start; it != End; it++)
            {
                size_t i = 0;
                while (i < rhs.size())
                    if (*(rhs.start + i) == *it)
                        break;
                    else
                        i++;
                if (i == rhs.size()) return it - start;
            }
            return size_t(-1);
        }
        size_t find_last_not_of(const string& rhs, size_t pos)
        {
            for (auto it = start + pos; it != start - 1; it--)
            {
                size_t i = 0;
                while (i < rhs.size())
                    if (*(rhs.start + i) == *it)
                        break;
                    else
                        i++;
                if (i == rhs.size()) return it - start;
            }
            return size_t(-1);
        }
        bool operator!=(const string& rhs)
        {
            return !(*this == rhs);
        }
        bool operator>(const string& rhs)
        {
            return compare(rhs) > 0;
        }
        bool operator>=(const string& rhs)
        {
            return compare(rhs) >= 0;
        }
        bool operator<(const string& rhs)
        {
            return compare(rhs) < 0;
        }
        bool operator<=(const string& rhs)
        {
            return compare(rhs) <= 0;
        }
    };
    std::ostream& operator<<(std::ostream& os, const ministl::string& rhs) 
    {
        os << rhs.c_str();
        return os;
    }

    size_t hash_value(const string& val)
    {
        const size_t _FNV_offset_basis = 2166136261U;
        const size_t _FNV_prime = 16777619U;
        size_t ans = _FNV_offset_basis;
        for (auto it = val.begin(); it != val.end(); it++)
        {
            ans ^= *it;
            ans *= _FNV_prime;
        }
        return ans;
    }

}

转载于:https://www.cnblogs.com/joeylee97/p/8877252.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值