From 71fa345280a4fd231ef441e55b3886aa667839ed Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Wed, 9 Sep 2015 19:12:57 +0200 Subject: [PATCH] strbuffer: fix issue with order of properties with the same position --- src/helpers.cpp | 10 +++---- src/scrollpad.cpp | 10 +++---- src/strbuffer.h | 73 ++++++++++++++--------------------------------- 3 files changed, 31 insertions(+), 62 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index 52988025..bd9b93a8 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -205,21 +205,21 @@ void writeCyclicBuffer(const NC::WBuffer &buf, NC::Window &w, size_t &start_pos, auto p = ps.begin(); // load attributes from before starting pos - for (; p != ps.end() && p->position() < start_pos; ++p) - w << *p; + for (; p != ps.end() && p->first < start_pos; ++p) + w << p->second; auto write_buffer = [&](size_t start) { for (size_t i = start; i < s.length() && len < width; ++i) { - for (; p != ps.end() && p->position() == i; ++p) - w << *p; + for (; p != ps.end() && p->first == i; ++p) + w << p->second; len += wcwidth(s[i]); if (len > width) break; w << s[i]; } for (; p != ps.end(); ++p) - w << *p; + w << p->second; p = ps.begin(); }; diff --git a/src/scrollpad.cpp b/src/scrollpad.cpp index 166cc5d6..27af910b 100644 --- a/src/scrollpad.cpp +++ b/src/scrollpad.cpp @@ -36,8 +36,8 @@ bool regexSearch(NC::Buffer &buf, PropT begin, const std::string &ws, PropT end, bool success = first != last; for (; first != last; ++first) { - buf.setProperty(first->position(), begin, id); - buf.setProperty(first->position() + first->length(), end, id); + buf.addProperty(first->position(), begin, id); + buf.addProperty(first->position() + first->length(), end, id); } return success; } catch (boost::bad_expression &e) { @@ -147,8 +147,8 @@ void Scrollpad::flush() size_t i = 0; auto load_properties = [&]() { - for (; p != ps.end() && p->position() == i; ++p) - w << *p; + for (; p != ps.end() && p->first == i; ++p) + w << p->second; }; auto write_whitespace = [&]() { for (; i < s.length() && iswspace(s[i]); ++i) @@ -257,7 +257,7 @@ void Scrollpad::flush() } // load remaining properties if there are any for (; p != ps.end(); ++p) - w << *p; + w << p->second; return height; }; m_real_height = std::max(write_buffer(true), m_height); diff --git a/src/strbuffer.h b/src/strbuffer.h index fbfb1ade..c5b59be6 100644 --- a/src/strbuffer.h +++ b/src/strbuffer.h @@ -22,7 +22,7 @@ #define NCMPCPP_STRBUFFER_H #include -#include +#include #include "window.h" namespace NC { @@ -35,34 +35,13 @@ template class BasicBuffer { enum class Type { Color, Format }; - Property(size_t position_, NC::Color color_, int id_) - : m_type(Type::Color), m_position(position_), m_color(std::move(color_)), m_id(id_) { } - Property(size_t position_, NC::Format format_, int id_) - : m_type(Type::Format), m_position(position_), m_format(format_), m_id(id_) { } + Property(NC::Color color_, size_t id_) + : m_type(Type::Color), m_color(std::move(color_)), m_id(id_) { } + Property(NC::Format format_, size_t id_) + : m_type(Type::Format), m_format(format_), m_id(id_) { } - size_t position() const { return m_position; } size_t id() const { return m_id; } - - bool operator<(const Property &rhs) const - { - if (m_position != rhs.m_position) - return m_position < rhs.m_position; - if (m_type != rhs.m_type) - return m_type < rhs.m_type; - switch (m_type) - { - case Type::Color: - if (m_color != rhs.m_color) - return m_color < rhs.m_color; - break; - case Type::Format: - if (m_format != rhs.m_format) - return m_format < rhs.m_format; - break; - } - return m_id < rhs.m_id; - } - + template friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p) { @@ -80,7 +59,6 @@ template class BasicBuffer private: Type m_type; - size_t m_position; Color m_color; Format m_format; size_t m_id; @@ -88,33 +66,24 @@ template class BasicBuffer public: typedef std::basic_string StringType; - typedef std::multiset Properties; + typedef std::multimap Properties; const StringType &str() const { return m_string; } const Properties &properties() const { return m_properties; } template - void setProperty(size_t position, PropertyT &&property, size_t id = -1) + void addProperty(size_t position, PropertyT &&property, size_t id = -1) { - m_properties.insert(Property(position, std::forward(property), id)); + assert(position <= m_string.size()); + m_properties.emplace(position, Property(std::forward(property), id)); } - - template - bool removeProperty(size_t position, PropertyT &&property, size_t id = -1) - { - auto it = m_properties.find(Property(position, std::forward(property), id)); - bool found = it != m_properties.end(); - if (found) - m_properties.erase(it); - return found; - } - + void removeProperties(size_t id = -1) { auto it = m_properties.begin(); while (it != m_properties.end()) { - if (it->id() == id) + if (it->second.id() == id) m_properties.erase(it++); else ++it; @@ -171,13 +140,13 @@ public: BasicBuffer &operator<<(Color color) { - setProperty(m_string.size(), color); + addProperty(m_string.size(), color); return *this; } BasicBuffer &operator<<(Format format) { - setProperty(m_string.size(), format); + addProperty(m_string.size(), format); return *this; } @@ -217,15 +186,15 @@ OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer &buffer) auto &s = buffer.str(); auto &ps = buffer.properties(); auto p = ps.begin(); - for (size_t i = 0; i < s.size(); ++i) + for (size_t i = 0;; ++i) { - for (; p != ps.end() && p->position() == i; ++p) - os << *p; - os << s[i]; + for (; p != ps.end() && p->first == i; ++p) + os << p->second; + if (i < s.size()) + os << s[i]; + else + break; } - // load remaining properties - for (; p != ps.end(); ++p) - os << *p; } return os; }