strbuffer: fix issue with order of properties with the same position

This commit is contained in:
Andrzej Rybczak
2015-09-09 19:12:57 +02:00
parent b9a0608053
commit 71fa345280
3 changed files with 31 additions and 62 deletions

View File

@@ -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();
};

View File

@@ -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);

View File

@@ -22,7 +22,7 @@
#define NCMPCPP_STRBUFFER_H
#include <boost/lexical_cast.hpp>
#include <set>
#include <map>
#include "window.h"
namespace NC {
@@ -35,34 +35,13 @@ template <typename CharT> 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 <typename OutputStreamT>
friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
{
@@ -80,7 +59,6 @@ template <typename CharT> 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 <typename CharT> class BasicBuffer
public:
typedef std::basic_string<CharT> StringType;
typedef std::multiset<Property> Properties;
typedef std::multimap<size_t, Property> Properties;
const StringType &str() const { return m_string; }
const Properties &properties() const { return m_properties; }
template <typename PropertyT>
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<PropertyT>(property), id));
assert(position <= m_string.size());
m_properties.emplace(position, Property(std::forward<PropertyT>(property), id));
}
template <typename PropertyT>
bool removeProperty(size_t position, PropertyT &&property, size_t id = -1)
{
auto it = m_properties.find(Property(position, std::forward<PropertyT>(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<CharT> &operator<<(Color color)
{
setProperty(m_string.size(), color);
addProperty(m_string.size(), color);
return *this;
}
BasicBuffer<CharT> &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<CharT> &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;
}