bindinds: add support for alt/ctrl/shift modifiers and escape key
[ncmpcpp.git] / src / strbuffer.h
blobfbfb1adef67366ae0f5cff116699a34cad69940d
1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #ifndef NCMPCPP_STRBUFFER_H
22 #define NCMPCPP_STRBUFFER_H
24 #include <boost/lexical_cast.hpp>
25 #include <set>
26 #include "window.h"
28 namespace NC {
30 /// Buffer template class that stores text
31 /// along with its properties (colors/formatting).
32 template <typename CharT> class BasicBuffer
34 struct Property
36 enum class Type { Color, Format };
38 Property(size_t position_, NC::Color color_, int id_)
39 : m_type(Type::Color), m_position(position_), m_color(std::move(color_)), m_id(id_) { }
40 Property(size_t position_, NC::Format format_, int id_)
41 : m_type(Type::Format), m_position(position_), m_format(format_), m_id(id_) { }
43 size_t position() const { return m_position; }
44 size_t id() const { return m_id; }
46 bool operator<(const Property &rhs) const
48 if (m_position != rhs.m_position)
49 return m_position < rhs.m_position;
50 if (m_type != rhs.m_type)
51 return m_type < rhs.m_type;
52 switch (m_type)
54 case Type::Color:
55 if (m_color != rhs.m_color)
56 return m_color < rhs.m_color;
57 break;
58 case Type::Format:
59 if (m_format != rhs.m_format)
60 return m_format < rhs.m_format;
61 break;
63 return m_id < rhs.m_id;
66 template <typename OutputStreamT>
67 friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
69 switch (p.m_type)
71 case Type::Color:
72 os << p.m_color;
73 break;
74 case Type::Format:
75 os << p.m_format;
76 break;
78 return os;
81 private:
82 Type m_type;
83 size_t m_position;
84 Color m_color;
85 Format m_format;
86 size_t m_id;
89 public:
90 typedef std::basic_string<CharT> StringType;
91 typedef std::multiset<Property> Properties;
93 const StringType &str() const { return m_string; }
94 const Properties &properties() const { return m_properties; }
96 template <typename PropertyT>
97 void setProperty(size_t position, PropertyT &&property, size_t id = -1)
99 m_properties.insert(Property(position, std::forward<PropertyT>(property), id));
102 template <typename PropertyT>
103 bool removeProperty(size_t position, PropertyT &&property, size_t id = -1)
105 auto it = m_properties.find(Property(position, std::forward<PropertyT>(property), id));
106 bool found = it != m_properties.end();
107 if (found)
108 m_properties.erase(it);
109 return found;
112 void removeProperties(size_t id = -1)
114 auto it = m_properties.begin();
115 while (it != m_properties.end())
117 if (it->id() == id)
118 m_properties.erase(it++);
119 else
120 ++it;
124 void clear()
126 m_string.clear();
127 m_properties.clear();
130 BasicBuffer<CharT> &operator<<(int n)
132 m_string += boost::lexical_cast<StringType>(n);
133 return *this;
136 BasicBuffer<CharT> &operator<<(long int n)
138 m_string += boost::lexical_cast<StringType>(n);
139 return *this;
142 BasicBuffer<CharT> &operator<<(unsigned int n)
144 m_string += boost::lexical_cast<StringType>(n);
145 return *this;
148 BasicBuffer<CharT> &operator<<(unsigned long int n)
150 m_string += boost::lexical_cast<StringType>(n);
151 return *this;
154 BasicBuffer<CharT> &operator<<(CharT c)
156 m_string += c;
157 return *this;
160 BasicBuffer<CharT> &operator<<(const CharT *s)
162 m_string += s;
163 return *this;
166 BasicBuffer<CharT> &operator<<(const StringType &s)
168 m_string += s;
169 return *this;
172 BasicBuffer<CharT> &operator<<(Color color)
174 setProperty(m_string.size(), color);
175 return *this;
178 BasicBuffer<CharT> &operator<<(Format format)
180 setProperty(m_string.size(), format);
181 return *this;
184 // static variadic initializer. used instead of a proper constructor because
185 // it's too polymorphic and would end up invoked as a copy/move constructor.
186 template <typename... Args>
187 static BasicBuffer init(Args&&... args)
189 BasicBuffer result;
190 result.construct(std::forward<Args>(args)...);
191 return result;
194 private:
195 void construct() { }
196 template <typename ArgT, typename... Args>
197 void construct(ArgT &&arg, Args&&... args)
199 *this << std::forward<ArgT>(arg);
200 construct(std::forward<Args>(args)...);
203 StringType m_string;
204 Properties m_properties;
207 typedef BasicBuffer<char> Buffer;
208 typedef BasicBuffer<wchar_t> WBuffer;
210 template <typename OutputStreamT, typename CharT>
211 OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer<CharT> &buffer)
213 if (buffer.properties().empty())
214 os << buffer.str();
215 else
217 auto &s = buffer.str();
218 auto &ps = buffer.properties();
219 auto p = ps.begin();
220 for (size_t i = 0; i < s.size(); ++i)
222 for (; p != ps.end() && p->position() == i; ++p)
223 os << *p;
224 os << s[i];
226 // load remaining properties
227 for (; p != ps.end(); ++p)
228 os << *p;
230 return os;
235 #endif // NCMPCPP_STRBUFFER_H