最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - In my custom string class, can I have a special behavior if `substr` assigns to self? - Stack Overflow

programmeradmin6浏览0评论

I have a very simple fixed-buffer string class. I am targeting embedded and don't want dynamic allocations. I am including it for reference, but the question is more general.

template <auto MaxSizeT = size_t(16)>
class FixedString
{
   public:
    using size_type = decltype(MaxSizeT);

    constexpr static size_type maxSize = MaxSizeT;

    FixedString() : length(0)
    {
        data[0] = '\0';  // Ensure null termination
    }

    FixedString(const char* inData) { assignStr(inData); }

    FixedString(const FixedString& other) { assignStr(other); }

    char data[maxSize + 1];  // Add space for null terminator
    size_type length;        // Current length of the string

    FixedString operator+(const FixedString& other) const
    {
        FixedString result{*this};
        result += other;
        return result;
    }

    FixedString& operator+=(const FixedString& other)
    {
        if (length >= maxSize)
        {
            return *this;
        }
        size_type const space = maxSize - length;
        auto copyLen          = mcu::nmin(space, other.length);

        memcpy(&data[length], other.data, copyLen);

        length += copyLen;
        data[length] = 0;
        return *this;
    }

    FixedString& operator=(const FixedString& other)
    {
        assignStr(other);
        return *this;
    }

    template <auto OtherMaxSizeT = size_t(16)>
    FixedString& operator=(const FixedString<OtherMaxSizeT>& other)
    {
        assignStr(other.data, other.length);
        return *this;
    }

    FixedString& operator=(const char* other)
    {
        assignStr(other);
        return *this;
    }

    bool operator==(const FixedString& other) const
    {
        return length == other.length && memcmp(data, other.data, length) == 0;
    }

    bool operator==(const char* other) const
    {
        auto const otherLen = strlen(other);
        if (otherLen != length)
        {
            return false;
        }
        else
        {
            return memcmp(&data[0], other, length) == 0;
        }
    }

    void assignStr(const char* inData)
    {
        auto len = strlen(inData);
        assignStr(inData, len);
    }

    void assignStr(const char* inData, size_t len)
    {
        if (len > maxSize)
        {
            len = maxSize;
        }
        memcpy(data, inData, len);
        data[len] = 0;
        length    = len;
    }

    void assignStr(const FixedString& other)
    {
        memcpy(data, other.data, maxSize);
        length       = other.length;
        data[length] = 0;
    }

    char& operator[](size_t index) { return index < length ? data[index] : data[0]; }

    const char& operator[](size_t index) const
    {
        // Bounds check: return a dummy value if out of range
        static char dummy = '\0';
        return index < length ? data[index] : dummy;
    }

    char* begin() { return data; }
    char* end() { return data + length; }
    const char* begin() const { return data; }
    const char* end() const { return data + length; }
    const char* cbegin() const { return data; }
    const char* cend() const { return data + length; }

    const char* c_str() const
    {
        return data;  // Already null-terminated
    }

    size_t size() const { return length; }
    size_t max_size() const { return maxSize; }
};

What I want is to have a substr function, which is simple enough:

    [[nodiscard]] FixedString substr(size_type start, size_type end) const
    {
        if(end > length) {
            end = length;
        }
        if(start >= end || start >= length)
        {
            return {};
        }
        else {
            const size_type newLen = end - start;
            FixedString copy;
            copy.assignStr(&data[start], newLen);
            return copy;
        }
    }

However, if I do this:

FixedString<16> myStr = "abcdef";
myStr = myStr.substr(1,4);

I am doing two memcpy calls. I was wondering if there's a way to have an intermediate string_view type (std::string_view does not exist in my target platform stdlib). I would like it to have the following properties:

  • When used as auto x = somesStr.substr(x,y) it should decay into FixedString copy of the original
  • If passed to the FixedString constructor or assignment operator, if the target and source are the same, memmove should be done instead

I am not sure if that's possible. I can of course just have a separate crop non const function that does substr in place, but I was mostly curious if there's a way to hide this behavior in the substr method.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论