From f534205a9159de3eeab64dacf7c224285be17dcb Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 17 Dec 2013 20:04:52 -0800 Subject: [PATCH] Make line_iterator less slow --- .../include/libaegisub/line_iterator.h | 63 +++++++++---------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/aegisub/libaegisub/include/libaegisub/line_iterator.h b/aegisub/libaegisub/include/libaegisub/line_iterator.h index 57f86ff14..9e86ed1c0 100644 --- a/aegisub/libaegisub/include/libaegisub/line_iterator.h +++ b/aegisub/libaegisub/include/libaegisub/line_iterator.h @@ -34,9 +34,7 @@ namespace agi { template class line_iterator : public std::iterator { std::istream *stream; ///< Stream to iterator over - bool valid; ///< Are there any more values to read? OutputType value; ///< Value to return when this is dereference - std::string encoding; ///< Encoding of source stream std::shared_ptr conv; int cr; ///< CR character in the source encoding int lf; ///< LF character in the source encoding @@ -65,8 +63,6 @@ public: /// @param encoding Encoding of the text read from the stream line_iterator(std::istream &stream, std::string encoding = "utf-8") : stream(&stream) - , valid(true) - , encoding(encoding) , cr('\r') , lf('\n') , width(1) @@ -84,25 +80,11 @@ public: } /// @brief Invalid iterator constructor; use for end iterator - line_iterator() - : stream(nullptr) - , valid(false) - { - } + line_iterator() : stream(nullptr) { } /// @brief Copy constructor /// @param that line_iterator to copy from - line_iterator(line_iterator const& that) - : stream(that.stream) - , valid(that.valid) - , value(that.value) - , encoding(that.encoding) - , conv(that.conv) - , cr(that.cr) - , lf(that.lf) - , width(that.width) - { - } + line_iterator(line_iterator const&) = default; OutputType const& operator*() const { return value; } OutputType const* operator->() const { return &value; } @@ -117,7 +99,7 @@ public: return tmp; } - bool operator==(line_iterator const& rgt) const { return valid == rgt.valid; } + bool operator==(line_iterator const& rgt) const { return stream == rgt.stream; } bool operator!=(line_iterator const& rgt) const { return !operator==(rgt); } // typedefs needed by some stl algorithms @@ -126,7 +108,7 @@ public: typedef const OutputType* const_pointer; typedef const OutputType& const_reference; - line_iterator operator=(line_iterator that) { + line_iterator& operator=(line_iterator that) { using std::swap; swap(*this, that); return *this; @@ -135,9 +117,7 @@ public: void swap(line_iterator &that) throw() { using std::swap; swap(stream, that.stream); - swap(valid, that.valid); swap(value, that.value); - swap(encoding, that.encoding); swap(conv, that.conv); swap(lf, that.lf); swap(cr, that.cr); @@ -179,16 +159,16 @@ void line_iterator::getline(std::string &str) { template void line_iterator::next() { - if (!valid) return; + if (!stream) return; if (!stream->good()) { - valid = false; + stream = nullptr; return; } std::string str, cstr, *target; if (width == 1) { std::getline(*stream, str); - if (str.size() && *str.rbegin() == '\r') - str.resize(str.size() - 1); + if (str.size() && str.back() == '\r') + str.pop_back(); } else { getline(str); @@ -200,10 +180,30 @@ void line_iterator::next() { else { target = &str; } - if (!convert(*target)) { + if (!convert(*target)) next(); +} + +template<> +inline void line_iterator::next() { + if (!stream) return; + if (!stream->good()) { + stream = nullptr; return; } + std::string cstr; + std::string *target = conv ? &cstr : &value; + if (width == 1) { + std::getline(*stream, *target); + if (target->size() && target->back() == '\r') + target->pop_back(); + } + else + getline(*target); + if (conv.get()) { + value.clear(); + conv->Convert(*target, value); + } } template @@ -212,11 +212,6 @@ inline bool line_iterator::convert(std::string &str) { ss >> value; return !ss.fail(); } -template<> -inline bool line_iterator::convert(std::string &str) { - value = str; - return true; -} template void swap(agi::line_iterator &lft, agi::line_iterator &rgt) {