mirror of https://github.com/odrling/Aegisub
Make line_iterator less slow
This commit is contained in:
parent
45726bea3c
commit
f534205a91
|
@ -34,9 +34,7 @@ namespace agi {
|
||||||
template<class OutputType = std::string>
|
template<class OutputType = std::string>
|
||||||
class line_iterator : public std::iterator<std::input_iterator_tag, OutputType> {
|
class line_iterator : public std::iterator<std::input_iterator_tag, OutputType> {
|
||||||
std::istream *stream; ///< Stream to iterator over
|
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
|
OutputType value; ///< Value to return when this is dereference
|
||||||
std::string encoding; ///< Encoding of source stream
|
|
||||||
std::shared_ptr<agi::charset::IconvWrapper> conv;
|
std::shared_ptr<agi::charset::IconvWrapper> conv;
|
||||||
int cr; ///< CR character in the source encoding
|
int cr; ///< CR character in the source encoding
|
||||||
int lf; ///< LF 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
|
/// @param encoding Encoding of the text read from the stream
|
||||||
line_iterator(std::istream &stream, std::string encoding = "utf-8")
|
line_iterator(std::istream &stream, std::string encoding = "utf-8")
|
||||||
: stream(&stream)
|
: stream(&stream)
|
||||||
, valid(true)
|
|
||||||
, encoding(encoding)
|
|
||||||
, cr('\r')
|
, cr('\r')
|
||||||
, lf('\n')
|
, lf('\n')
|
||||||
, width(1)
|
, width(1)
|
||||||
|
@ -84,25 +80,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Invalid iterator constructor; use for end iterator
|
/// @brief Invalid iterator constructor; use for end iterator
|
||||||
line_iterator()
|
line_iterator() : stream(nullptr) { }
|
||||||
: stream(nullptr)
|
|
||||||
, valid(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Copy constructor
|
/// @brief Copy constructor
|
||||||
/// @param that line_iterator to copy from
|
/// @param that line_iterator to copy from
|
||||||
line_iterator(line_iterator<OutputType> const& that)
|
line_iterator(line_iterator<OutputType> const&) = default;
|
||||||
: stream(that.stream)
|
|
||||||
, valid(that.valid)
|
|
||||||
, value(that.value)
|
|
||||||
, encoding(that.encoding)
|
|
||||||
, conv(that.conv)
|
|
||||||
, cr(that.cr)
|
|
||||||
, lf(that.lf)
|
|
||||||
, width(that.width)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputType const& operator*() const { return value; }
|
OutputType const& operator*() const { return value; }
|
||||||
OutputType const* operator->() const { return &value; }
|
OutputType const* operator->() const { return &value; }
|
||||||
|
@ -117,7 +99,7 @@ public:
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(line_iterator<OutputType> const& rgt) const { return valid == rgt.valid; }
|
bool operator==(line_iterator<OutputType> const& rgt) const { return stream == rgt.stream; }
|
||||||
bool operator!=(line_iterator<OutputType> const& rgt) const { return !operator==(rgt); }
|
bool operator!=(line_iterator<OutputType> const& rgt) const { return !operator==(rgt); }
|
||||||
|
|
||||||
// typedefs needed by some stl algorithms
|
// typedefs needed by some stl algorithms
|
||||||
|
@ -126,7 +108,7 @@ public:
|
||||||
typedef const OutputType* const_pointer;
|
typedef const OutputType* const_pointer;
|
||||||
typedef const OutputType& const_reference;
|
typedef const OutputType& const_reference;
|
||||||
|
|
||||||
line_iterator<OutputType> operator=(line_iterator<OutputType> that) {
|
line_iterator<OutputType>& operator=(line_iterator<OutputType> that) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(*this, that);
|
swap(*this, that);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -135,9 +117,7 @@ public:
|
||||||
void swap(line_iterator<OutputType> &that) throw() {
|
void swap(line_iterator<OutputType> &that) throw() {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(stream, that.stream);
|
swap(stream, that.stream);
|
||||||
swap(valid, that.valid);
|
|
||||||
swap(value, that.value);
|
swap(value, that.value);
|
||||||
swap(encoding, that.encoding);
|
|
||||||
swap(conv, that.conv);
|
swap(conv, that.conv);
|
||||||
swap(lf, that.lf);
|
swap(lf, that.lf);
|
||||||
swap(cr, that.cr);
|
swap(cr, that.cr);
|
||||||
|
@ -179,16 +159,16 @@ void line_iterator<OutputType>::getline(std::string &str) {
|
||||||
|
|
||||||
template<class OutputType>
|
template<class OutputType>
|
||||||
void line_iterator<OutputType>::next() {
|
void line_iterator<OutputType>::next() {
|
||||||
if (!valid) return;
|
if (!stream) return;
|
||||||
if (!stream->good()) {
|
if (!stream->good()) {
|
||||||
valid = false;
|
stream = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string str, cstr, *target;
|
std::string str, cstr, *target;
|
||||||
if (width == 1) {
|
if (width == 1) {
|
||||||
std::getline(*stream, str);
|
std::getline(*stream, str);
|
||||||
if (str.size() && *str.rbegin() == '\r')
|
if (str.size() && str.back() == '\r')
|
||||||
str.resize(str.size() - 1);
|
str.pop_back();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getline(str);
|
getline(str);
|
||||||
|
@ -200,10 +180,30 @@ void line_iterator<OutputType>::next() {
|
||||||
else {
|
else {
|
||||||
target = &str;
|
target = &str;
|
||||||
}
|
}
|
||||||
if (!convert(*target)) {
|
if (!convert(*target))
|
||||||
next();
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void line_iterator<std::string>::next() {
|
||||||
|
if (!stream) return;
|
||||||
|
if (!stream->good()) {
|
||||||
|
stream = nullptr;
|
||||||
return;
|
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<class OutputType>
|
template<class OutputType>
|
||||||
|
@ -212,11 +212,6 @@ inline bool line_iterator<OutputType>::convert(std::string &str) {
|
||||||
ss >> value;
|
ss >> value;
|
||||||
return !ss.fail();
|
return !ss.fail();
|
||||||
}
|
}
|
||||||
template<>
|
|
||||||
inline bool line_iterator<std::string>::convert(std::string &str) {
|
|
||||||
value = str;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void swap(agi::line_iterator<T> &lft, agi::line_iterator<T> &rgt) {
|
void swap(agi::line_iterator<T> &lft, agi::line_iterator<T> &rgt) {
|
||||||
|
|
Loading…
Reference in New Issue