类似c17的string_view,提供一个fast string 类,提供字符串的常用工具

本文档介绍了一个名为xfast_str_basic的模板类,用于高效地处理字符串。该类提供了如数据获取、长度计算、子串提取、前后缀检查、查找和拆分等操作。通过DD_ASSERT进行调试,并且可以转换为std::basic_string。此外,还包含了实例化的xfast_str(char类型)和wxfast_str(wchar_t类型)。

工欲善其事必先利其器



#ifndef xfast_str_basic_h__
#define xfast_str_basic_h__

#undef DD_ASSERT
#ifdef _DEBUG
#include <assert.h>
#define DD_ASSERT(e) assert(e)
#else
#define DD_ASSERT(x) ((void)0)
#endif

#include <string>

template <class t>
class xfast_str_basic {
public:
    using t_str = std::basic_string<t>;
    using t_size = typename t_str::size_type;
    static constexpr auto xnpos = t_str::npos;

public:
    xfast_str_basic(const t* buff);
    xfast_str_basic(const t_str& str);
    xfast_str_basic(const t* buff, t_size len);
    xfast_str_basic(const t* buff, t_size l, t_size r);

    inline const t* data() const;
    inline t_size length() const;
    inline t operator[](t_size index) const;
    inline bool operator==(const xfast_str_basic& r) const;

public:
    inline t_str to_str() const;
    inline const t* c_str() const;

    void trim();

    bool beg_with(const xfast_str_basic& cmp) const;
    bool end_with(const xfast_str_basic& cmp) const;

    xfast_str_basic sub_str(t_size l, t_size len = xnpos) const;
    void to_sub_str(t_size l, t_size len = xnpos);

    t_size find(t c) const;
    t_size find(const xfast_str_basic& cmp) const;
    t_size find_last_of(t c) const;
    t_size find_last_of(const xfast_str_basic& cmp) const;

    void split(const xfast_str_basic& cmp, std::vector<xfast_str_basic>& out) const;

private:
    const t* m_buff;
    t_size m_l_pos = 0; // 包含
    t_size m_r_pos = 0; // 不包含
};

template <class t>
xfast_str_basic<t>::xfast_str_basic(const t* buff) : m_buff(buff), m_l_pos(0)
{
    DD_ASSERT(buff != nullptr);
    t_str tmp(m_buff);
    m_r_pos = tmp.length();
}

template <class t>
xfast_str_basic<t>::xfast_str_basic(const t_str& str) :
    m_buff(str.c_str()), m_l_pos(0), m_r_pos(str.length()) { }

template <class t>
xfast_str_basic<t>::xfast_str_basic(const t* buff, t_size len) :
    m_buff(buff), m_l_pos(0), m_r_pos(len) 
{
    DD_ASSERT(buff != nullptr);
}

template <class t>
xfast_str_basic<t>::xfast_str_basic(const t* buff, t_size l, t_size r) :
    m_buff(buff), m_l_pos(l), m_r_pos(r)
{
    DD_ASSERT(buff != nullptr);
    DD_ASSERT(l <= r);
}

template <class t>
inline const t* xfast_str_basic<t>::data() const
{
    return m_buff;
}

template <class t>
inline typename xfast_str_basic<t>::t_size xfast_str_basic<t>::length() const
{
    return m_r_pos - m_l_pos;
}

template <class t>
inline t xfast_str_basic<t>::operator[](t_size index) const
{
    DD_ASSERT(index < length());
    return m_buff[m_l_pos + index];
}

template <class t>
inline bool xfast_str_basic<t>::operator==(const xfast_str_basic& r) const
{
    if (length() != r.length()) {
        return false;
    }

    for (t_size i = 0; i < length(); ++i) {
        if ((*this)[i] != r[i]) {
            return false;
        }
    }

    return true;
}

template <class t>
inline typename xfast_str_basic<t>::t_str xfast_str_basic<t>::to_str() const
{
    return t_str(m_buff + m_l_pos, m_buff + m_r_pos);
}

template <class t>
inline const t* xfast_str_basic<t>::c_str() const
{
    return m_buff + m_l_pos;
}

template <class t>
void xfast_str_basic<t>::trim()
{
    for (t_size i = m_l_pos; i < m_r_pos; ++i) {
        if (m_buff[i] != ' ') {
            break;
        }

        ++m_l_pos;
    }

    for (t_size i = m_r_pos; i > m_l_pos + 1; --i) {
        if (m_buff[i - 1] != ' ') {
            break;
        }
        --m_r_pos;
    }
}

template <class t>
bool xfast_str_basic<t>::beg_with(const xfast_str_basic& cmp) const
{
    if (length() < cmp.length()) {
        return false;
    }

    for (t_size i = 0; i < cmp.length(); ++i) {
        if ((*this)[i] != cmp[i]) {
            return false;
        }
    }

    return true;
}

template <class t>
bool xfast_str_basic<t>::end_with(const xfast_str_basic& cmp) const
{
    if (length() < cmp.length()) {
        return false;
    }

    for (t_size i = 0; i < cmp.length(); ++i) {
        if ((*this)[length() - cmp.length() + i] != cmp[i]) {
            return false;
        }
    }

    return true;
}

template <class t>
xfast_str_basic<t> xfast_str_basic<t>::sub_str(t_size l, t_size len/* = xnpos*/) const
{
    DD_ASSERT(l <= length());
    if (len == xnpos) {
        return xfast_str_basic(m_buff, m_l_pos + l, m_r_pos);
    } else {
        DD_ASSERT(l + len <= m_r_pos);
        return xfast_str_basic(m_buff, m_l_pos + l, m_l_pos + l + len);
    }
}

template <class t>
void xfast_str_basic<t>::to_sub_str(xfast_str_basic<t>::t_size l, xfast_str_basic<t>::t_size len/* = xnpos*/)
{
    DD_ASSERT(l <= length());
    m_l_pos += l;
    if (len != xnpos) {
        DD_ASSERT(l + len <= m_r_pos);
        m_r_pos = m_l_pos + len;
    }
}

template <class t>
typename xfast_str_basic<t>::t_size xfast_str_basic<t>::find(t c) const
{
    for (t_size i = 0; i < length(); ++i) {
        if ((*this)[i] == c) {
            return i;
        }
    }

    return xnpos;
}

template <class t>
typename xfast_str_basic<t>::t_size xfast_str_basic<t>::find(const xfast_str_basic& cmp) const
{
    if (cmp.length() == 0) {
        return 0;
    }

    if (cmp.length() > length()) {
        return xnpos;
    }

    for (t_size i = 0; i < length(); ++i) {
        if ((*this)[i] != cmp[0]) {
            continue;
        }

        if (sub_str(i).beg_with(cmp)) {
            return i;
        }
    }

    return xnpos;
}

template <class t>
typename xfast_str_basic<t>::t_size xfast_str_basic<t>::find_last_of(t c) const
{
    for (t_size i = length(); i > 0; --i) {
        if ((*this)[i - 1] == c) {
            return i - 1;
        }
    }

    return xnpos;
}

template <class t>
typename xfast_str_basic<t>::t_size xfast_str_basic<t>::find_last_of(const xfast_str_basic& cmp) const
{
    if (cmp.length() == 0) {
        return 0;
    }

    if (cmp.length() > length()) {
        return xnpos;
    }

    for (t_size i = length() - cmp.length() + 1; i > 0; --i) {
        if ((*this)[i - 1] != cmp[0]) {
            continue;
        }

        if (sub_str(i - 1).beg_with(cmp)) {
            return i - 1;
        }
    }

    return xnpos;
}

template <class t>
void xfast_str_basic<t>::split(const xfast_str_basic& cmp, std::vector<xfast_str_basic>& out) const
{
    DD_ASSERT(cmp.length() > 0);
    xfast_str_basic src(*this);
    t_size pos = src.find(cmp);
    while (pos != xnpos)
    {
        out.emplace_back(src.sub_str(0, pos));
        src.to_sub_str(pos + cmp.length());
        pos = src.find(cmp);
    }

    out.emplace_back(src);
}

using xfast_str = xfast_str_basic<char>;
using wxfast_str = xfast_str_basic<wchar_t>;

#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值