mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
70 lines
1.6 KiB
C++
70 lines
1.6 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include <algorithm>
|
|
#include <string_view>
|
|
|
|
/// Iterates over the lines of a string. If the string is empty, the range is
|
|
/// empty. Each element line (except the last one) ends in a newline character.
|
|
class LineRange {
|
|
public:
|
|
class Sentinel {
|
|
public:
|
|
explicit Sentinel() = default;
|
|
};
|
|
|
|
class Iterator {
|
|
const char *LineBegin = nullptr;
|
|
const char *LineEnd = nullptr;
|
|
const char *End = nullptr;
|
|
|
|
public:
|
|
using value_type = std::string_view;
|
|
using difference_type = ptrdiff_t;
|
|
|
|
Iterator() = default;
|
|
|
|
explicit Iterator(std::string_view String) :
|
|
LineBegin(String.data()),
|
|
LineEnd(LineBegin),
|
|
End(LineBegin + String.size()) {
|
|
if (LineBegin != End)
|
|
++(*this);
|
|
}
|
|
|
|
[[nodiscard]] std::string_view operator*() const {
|
|
return std::string_view(LineBegin, LineEnd);
|
|
}
|
|
|
|
Iterator &operator++() & {
|
|
const char *LF = std::find(LineEnd, End, '\n');
|
|
LineBegin = LineEnd;
|
|
LineEnd = LF == End ? End : LF + 1;
|
|
return *this;
|
|
}
|
|
|
|
[[nodiscard]] Iterator operator++(int) & {
|
|
auto Result = *this;
|
|
++(*this);
|
|
return Result;
|
|
}
|
|
|
|
[[nodiscard]] friend bool operator==(const Iterator &Self,
|
|
const Sentinel &) {
|
|
return Self.LineBegin == Self.End;
|
|
}
|
|
};
|
|
|
|
private:
|
|
Iterator Begin;
|
|
|
|
public:
|
|
explicit LineRange(std::string_view String) : Begin(String) {}
|
|
|
|
[[nodiscard]] Iterator begin() const { return Begin; }
|
|
[[nodiscard]] Sentinel end() const { return Sentinel(); }
|
|
};
|