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
99 lines
2.2 KiB
|
4 years ago
|
#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
|