Untitled

 avatar
unknown
c_cpp
9 months ago
1.5 kB
4
Indexable
class SplitViewSentinel {};

class SplitViewIterator {
public:
    using difference_type = std::ptrdiff_t; // Required for std::input_or_output_iterator, even though we can't take iterator difference...

    SplitViewIterator(std::string_view s, char separator) : _pos(s.data()), _end(s.data() + s.size()), _separator(separator) {}

    SplitViewIterator &operator++() {
        return *this; // This is an input iterator, all the work is done in `operator*`.
    }

    SplitViewIterator operator++(int) {
        return *this; // This is an input iterator, all the work is done in `operator*`.
    }

    std::string_view operator*() {
        const char *next = std::find(_pos, _end, _separator);

        std::string_view result(_pos, next);

        _pos = next + 1;

        return result;
    }

    friend bool operator==(const SplitViewIterator &l, const SplitViewSentinel &r) {
        return l._pos == l._end + 1;
    }

private:
    const char *_pos = nullptr;
    const char *_end = nullptr;
    char _separator = '\0';
};

class SplitView : public std::ranges::view_interface<SplitView> {
public:
    SplitView(std::string_view string, char separator) : _string(string), _separator(separator) {}

    [[nodiscard]] auto begin() const {
        return SplitViewIterator(_string.data(), _separator);
    }

    [[nodiscard]] auto end() const {
        return SplitViewSentinel();
    }

private:
    std::string_view _string;
    char _separator;
};
Editor is loading...
Leave a Comment