You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.2 KiB

#pragma once
#include <iterator>
#include <type_traits>
#include "utils/stdcompat/string_view.hpp"
namespace devilution {
class SplitByCharIterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = string_view;
using reference = std::add_lvalue_reference<value_type>::type;
using pointer = std::add_pointer<value_type>::type;
static SplitByCharIterator begin(string_view text, char split_by) // NOLINT(readability-identifier-naming)
{
return SplitByCharIterator(split_by, text, text.substr(0, text.find(split_by)));
}
static SplitByCharIterator end(string_view text, char split_by) // NOLINT(readability-identifier-naming)
{
return SplitByCharIterator(split_by, text, text.substr(text.size()));
}
[[nodiscard]] string_view operator*() const
{
return slice_;
}
[[nodiscard]] const string_view *operator->() const
{
return &slice_;
}
SplitByCharIterator &operator++()
{
slice_ = text_.substr(slice_.data() - text_.data() + slice_.size());
if (!slice_.empty())
slice_.remove_prefix(1); // skip the split_by char
slice_ = slice_.substr(0, slice_.find(split_by_));
return *this;
}
SplitByCharIterator operator++(int)
{
auto copy = *this;
++(*this);
return copy;
}
bool operator==(const SplitByCharIterator &rhs) const
{
return slice_.data() == rhs.slice_.data();
}
bool operator!=(const SplitByCharIterator &rhs) const
{
return !(*this == rhs);
}
private:
SplitByCharIterator(char split_by, string_view text, string_view slice)
: split_by_(split_by)
, text_(text)
, slice_(slice)
{
}
const char split_by_;
const string_view text_;
string_view slice_;
};
class SplitByChar {
public:
explicit SplitByChar(string_view text, char split_by)
: text_(text)
, split_by_(split_by)
{
}
[[nodiscard]] SplitByCharIterator begin() const // NOLINT(readability-identifier-naming)
{
return SplitByCharIterator::begin(text_, split_by_);
}
[[nodiscard]] SplitByCharIterator end() const // NOLINT(readability-identifier-naming)
{
return SplitByCharIterator::end(text_, split_by_);
}
private:
const string_view text_;
const char split_by_;
};
} // namespace devilution