C++ 一个字符串的代理类(String View)

在学习muduo/base源码的时候看到一个StringPiece类,是个string view,记录下来。

关于string view,看http://stackoverflow.com/questions/20803826/what-is-string-view。

简单摘抄下来就是

The purpose of any and all kinds of “string reference” and “array reference” proposals is to avoid copying data which is already owned somewhere else and of which only a non-mutating view is required. The string_view in question is one such proposal; there were earlier ones called string_ref and array_ref, too.

The idea is always to store a pair of pointer-to-first-element and size of some existing data array or string.

string view解释过来就是个窗口,你通过这个窗口查看代理的字符串的内容,移动指针和改变长度就可以移动窗口,而且,自身不需要存储字符串,只读,不可修改,生命期应和代理的字符串一致。

muduo的StringPiece代码如下,个人做了一点修改:

class StringPiece {
public:
    StringPiece()
        : _ptr(nullptr),
          _length(0)
    {
    }

    StringPiece(const char* str)
        : _ptr(str),
          _length(strlen(_ptr))
    {
    }

    StringPiece(const unsigned char* str)
        : _ptr(reinterpret_cast<const char*>(str)),
          _length(strlen(_ptr))
    {
    }

    StringPiece(const std::string& str)
        : _ptr(str.data()),
          _length(static_cast(str.length()))
    {
    }

    StringPiece(const char* offset, size_t len)
        : _ptr(offset),
          _length(len)
    {
    }

    const char* data() const { return _ptr; }

    size_t size() const { return _length; }

    bool empty() const { return _length == 0; }

    const char* begin() const { return _ptr; }

    const char* end() const { return _ptr + _length; }

    void clear()
    {
        _ptr = nullptr; 
        _length = 0; 
    }

    void set(const char* buffer, size_t len)
    {
        _ptr = buffer;
        _length = len;
    }

    void set(const char* str)
    {
        _ptr = str;
        _length = strlen(str);
    }

    void set(const void* buffer, size_t len)
    {
        _ptr = reinterpret_cast<const char*>(buffer);
        _length = len;
    }

    char operator[](size_t i) const { return _ptr[i]; }

    void remove_prefix(size_t n)
    {
        assert(n <= _length);
        _ptr += n;
        _length -= n;
    }

    void remove_suffix(size_t n)
    {
        assert(n <= _length);
        _length -= n;
    }

    bool operator==(const StringPiece& x) const
    {
        return ((_length == x._length) &&
                 (memcmp(_ptr, x._ptr, _length) == 0));
    }

    bool operator!=(const StringPiece& sp) const
    {
        return !(*this == sp);
    }

    std::string asString() const 
    { 
        return std::string(data(), size());
    } 

    void copyToStdString(std::string* target) const
    {
        assert(target != nullptr);
        target->assign(_ptr, _length);
    }

    bool startWith(const StringPiece& x) const
    {
        return ((_length >= x._length) && 
                (memcmp(_ptr, x._ptr, x._length) == 0));
    }

    int compare(const StringPiece& x) const 
    {
        int r = memcmp(_ptr, x._ptr, _length < x._length ? _length : x._length);
        if (r == 0)
        {
            if (_length < x._length) r = -1;
            else if (_length > x._length) r = +1;
        }
        return r;
    }
private:
    const char* _ptr;
    size_t _length;
};

你可能感兴趣的:(c++)