diff --git a/libaegisub/include/libaegisub/split.h b/libaegisub/include/libaegisub/split.h index b2f968cbf..9183e3a02 100644 --- a/libaegisub/include/libaegisub/split.h +++ b/libaegisub/include/libaegisub/split.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013, Thomas Goyne +// Copyright (c) 2015, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -14,32 +14,89 @@ // // Aegisub Project http://www.aegisub.org/ -#include -#include +#include namespace agi { typedef boost::iterator_range StringRange; + template + class split_iterator { + bool is_end = false; + Iterator b; + Iterator cur; + Iterator e; + typename Iterator::value_type c; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = boost::iterator_range; + using pointer = value_type*; + using reference = value_type&; + using difference_type = ptrdiff_t; + + split_iterator(Iterator begin, Iterator end, typename Iterator::value_type c) + : b(begin), cur(begin), e(end), c(c) + { + if (b != e) + cur = std::find(b, e, c); + else + is_end = true; + } + + split_iterator() : is_end(true) { } + + bool eof() const { return is_end; } + + boost::iterator_range operator*() const { + return boost::make_iterator_range(b, cur); + } + + bool operator==(split_iterator const& it) const { + if (is_end || it.is_end) + return is_end && it.is_end; + return b == it.b && cur == it.cur && e == it.e && c == it.c; + } + + bool operator!=(split_iterator const& it) const { + return !(*this == it); + } + + split_iterator& operator++() { + if (cur != e) { + b = cur + 1; + cur = std::find(b, e, c); + } + else { + b = e; + is_end = true; + } + + return *this; + } + + split_iterator operator++(int) { + split_iterator tmp = *this; + ++*this; + return tmp; + } + }; + + template + split_iterator begin(split_iterator const& it) { + return it; + } + + template + split_iterator end(split_iterator const&) { + return split_iterator(); + } + template - boost::split_iterator Split(Str const& str, Char delim) { - return boost::make_split_iterator(str, boost::token_finder([=](Char c) { return c == delim; })); + split_iterator Split(Str const& str, Char delim) { + return split_iterator(begin(str), end(str), delim); } static inline std::string str(StringRange const& r) { return std::string(r.begin(), r.end()); } } - -namespace boost { - namespace algorithm { - template - split_iterator begin(split_iterator it) { - return it; - } - - template - split_iterator end(split_iterator) { - return split_iterator(); - } - } -} diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index f37062f1e..88ce9386a 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -73,7 +73,7 @@ AssDialogue::~AssDialogue () { } class tokenizer { agi::StringRange str; - boost::split_iterator pos; + agi::split_iterator pos; public: tokenizer(agi::StringRange const& str) : str(str) , pos(agi::Split(str, ',')) { } diff --git a/src/ass_style.cpp b/src/ass_style.cpp index 45072b943..37645c043 100644 --- a/src/ass_style.cpp +++ b/src/ass_style.cpp @@ -54,7 +54,7 @@ AssEntryGroup AssStyle::Group() const { return AssEntryGroup::STYLE; } namespace { class parser { - boost::split_iterator pos; + agi::split_iterator pos; std::string next_tok() { if (pos.eof()) diff --git a/tests/tests/split.cpp b/tests/tests/split.cpp index 9ab5ea2e8..6dadeff87 100644 --- a/tests/tests/split.cpp +++ b/tests/tests/split.cpp @@ -41,7 +41,7 @@ TEST(lagi_split, does_not_copy_input) { } auto rng = agi::Split(str, 'e'); - EXPECT_EQ(str.begin(), rng->begin()); - EXPECT_EQ(str.end(), std::next(rng)->end()); + EXPECT_EQ(str.begin(), begin(*rng)); + EXPECT_EQ(str.end(), end(*std::next(rng))); }