set SIGWINCH handler before initializing ncurses to avoid races
[ncmpcpp.git] / src / strbuffer.h
blob2cbe4395fc3e7747be86c7df1e3435a83dcc393b
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(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 template <typename... Args>
94 BasicBuffer(Args... args)
96 construct(std::forward<Args>(args)...);
99 const StringType &str() const { return m_string; }
100 const Properties &properties() const { return m_properties; }
102 template <typename PropertyT>
103 void setProperty(size_t position, PropertyT property, size_t id = -1)
105 m_properties.insert(Property(position, property, id));
108 template <typename PropertyT>
109 bool removeProperty(size_t position, PropertyT property, size_t id = -1)
111 auto it = m_properties.find(Property(position, property, id));
112 bool found = it != m_properties.end();
113 if (found)
114 m_properties.erase(it);
115 return found;
118 void removeProperties(size_t id = -1)
120 auto it = m_properties.begin();
121 while (it != m_properties.end())
123 if (it->id() == id)
124 m_properties.erase(it++);
125 else
126 ++it;
130 void clear()
132 m_string.clear();
133 m_properties.clear();
136 BasicBuffer<CharT> &operator<<(int n)
138 m_string += boost::lexical_cast<StringType>(n);
139 return *this;
142 BasicBuffer<CharT> &operator<<(long int n)
144 m_string += boost::lexical_cast<StringType>(n);
145 return *this;
148 BasicBuffer<CharT> &operator<<(unsigned int n)
150 m_string += boost::lexical_cast<StringType>(n);
151 return *this;
154 BasicBuffer<CharT> &operator<<(unsigned long int n)
156 m_string += boost::lexical_cast<StringType>(n);
157 return *this;
160 BasicBuffer<CharT> &operator<<(CharT c)
162 m_string += c;
163 return *this;
166 BasicBuffer<CharT> &operator<<(const CharT *s)
168 m_string += s;
169 return *this;
172 BasicBuffer<CharT> &operator<<(const StringType &s)
174 m_string += s;
175 return *this;
178 BasicBuffer<CharT> &operator<<(Color color)
180 setProperty(m_string.size(), color);
181 return *this;
184 BasicBuffer<CharT> &operator<<(Format format)
186 setProperty(m_string.size(), format);
187 return *this;
190 private:
191 void construct() { }
192 template <typename ArgT, typename... Args>
193 void construct(ArgT &&arg, Args... args)
195 *this << std::forward<ArgT>(arg);
196 construct(std::forward<Args>(args)...);
199 StringType m_string;
200 Properties m_properties;
203 typedef BasicBuffer<char> Buffer;
204 typedef BasicBuffer<wchar_t> WBuffer;
206 template <typename OutputStreamT, typename CharT>
207 OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer<CharT> &buffer)
209 if (buffer.properties().empty())
210 os << buffer.str();
211 else
213 auto &s = buffer.str();
214 auto &ps = buffer.properties();
215 auto p = ps.begin();
216 for (size_t i = 0; i < s.size(); ++i)
218 for (; p != ps.end() && p->position() == i; ++p)
219 os << *p;
220 os << s[i];
222 // load remaining properties
223 for (; p != ps.end(); ++p)
224 os << *p;
226 return os;
231 #endif // NCMPCPP_STRBUFFER_H