Move ncurses related files to curses directory
[ncmpcpp.git] / src / curses / strbuffer.h
blob9c8ffb18f9d9947eac2eca365488843d7d2a5496
1 /***************************************************************************
2 * Copyright (C) 2008-2016 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 <map>
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(NC::Color color_, size_t id_)
39 : m_type(Type::Color), m_color(std::move(color_)), m_id(id_) { }
40 Property(NC::Format format_, size_t id_)
41 : m_type(Type::Format), m_format(format_), m_id(id_) { }
43 size_t id() const { return m_id; }
45 template <typename OutputStreamT>
46 friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
48 switch (p.m_type)
50 case Type::Color:
51 os << p.m_color;
52 break;
53 case Type::Format:
54 os << p.m_format;
55 break;
57 return os;
60 private:
61 Type m_type;
62 Color m_color;
63 Format m_format;
64 size_t m_id;
67 public:
68 typedef std::basic_string<CharT> StringType;
69 typedef std::multimap<size_t, Property> Properties;
71 const StringType &str() const { return m_string; }
72 const Properties &properties() const { return m_properties; }
74 template <typename PropertyT>
75 void addProperty(size_t position, PropertyT &&property, size_t id = -1)
77 assert(position <= m_string.size());
78 m_properties.emplace(position, Property(std::forward<PropertyT>(property), id));
81 void removeProperties(size_t id = -1)
83 auto it = m_properties.begin();
84 while (it != m_properties.end())
86 if (it->second.id() == id)
87 m_properties.erase(it++);
88 else
89 ++it;
93 bool empty() const
95 return m_string.empty() && m_properties.empty();
98 void clear()
100 m_string.clear();
101 m_properties.clear();
104 BasicBuffer<CharT> &operator<<(int n)
106 m_string += boost::lexical_cast<StringType>(n);
107 return *this;
110 BasicBuffer<CharT> &operator<<(long int n)
112 m_string += boost::lexical_cast<StringType>(n);
113 return *this;
116 BasicBuffer<CharT> &operator<<(unsigned int n)
118 m_string += boost::lexical_cast<StringType>(n);
119 return *this;
122 BasicBuffer<CharT> &operator<<(unsigned long int n)
124 m_string += boost::lexical_cast<StringType>(n);
125 return *this;
128 BasicBuffer<CharT> &operator<<(CharT c)
130 m_string += c;
131 return *this;
134 BasicBuffer<CharT> &operator<<(const CharT *s)
136 m_string += s;
137 return *this;
140 BasicBuffer<CharT> &operator<<(const StringType &s)
142 m_string += s;
143 return *this;
146 BasicBuffer<CharT> &operator<<(Color color)
148 addProperty(m_string.size(), color);
149 return *this;
152 BasicBuffer<CharT> &operator<<(Format format)
154 addProperty(m_string.size(), format);
155 return *this;
158 // static variadic initializer. used instead of a proper constructor because
159 // it's too polymorphic and would end up invoked as a copy/move constructor.
160 template <typename... Args>
161 static BasicBuffer init(Args&&... args)
163 BasicBuffer result;
164 result.construct(std::forward<Args>(args)...);
165 return result;
168 private:
169 void construct() { }
170 template <typename ArgT, typename... Args>
171 void construct(ArgT &&arg, Args&&... args)
173 *this << std::forward<ArgT>(arg);
174 construct(std::forward<Args>(args)...);
177 StringType m_string;
178 Properties m_properties;
181 typedef BasicBuffer<char> Buffer;
182 typedef BasicBuffer<wchar_t> WBuffer;
184 template <typename OutputStreamT, typename CharT>
185 OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer<CharT> &buffer)
187 if (buffer.properties().empty())
188 os << buffer.str();
189 else
191 auto &s = buffer.str();
192 auto &ps = buffer.properties();
193 auto p = ps.begin();
194 for (size_t i = 0;; ++i)
196 for (; p != ps.end() && p->first == i; ++p)
197 os << p->second;
198 if (i < s.size())
199 os << s[i];
200 else
201 break;
204 return os;
209 #endif // NCMPCPP_STRBUFFER_H