1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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. *
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. *
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>
30 /// Buffer template class that stores text
31 /// along with its properties (colors/formatting).
32 template <typename CharT
> class BasicBuffer
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
;
55 if (m_color
!= rhs
.m_color
)
56 return m_color
< rhs
.m_color
;
59 if (m_format
!= rhs
.m_format
)
60 return m_format
< rhs
.m_format
;
63 return m_id
< rhs
.m_id
;
66 template <typename OutputStreamT
>
67 friend OutputStreamT
&operator<<(OutputStreamT
&os
, const Property
&p
)
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();
108 m_properties
.erase(it
);
112 void removeProperties(size_t id
= -1)
114 auto it
= m_properties
.begin();
115 while (it
!= m_properties
.end())
118 m_properties
.erase(it
++);
127 m_properties
.clear();
130 BasicBuffer
<CharT
> &operator<<(int n
)
132 m_string
+= boost::lexical_cast
<StringType
>(n
);
136 BasicBuffer
<CharT
> &operator<<(long int n
)
138 m_string
+= boost::lexical_cast
<StringType
>(n
);
142 BasicBuffer
<CharT
> &operator<<(unsigned int n
)
144 m_string
+= boost::lexical_cast
<StringType
>(n
);
148 BasicBuffer
<CharT
> &operator<<(unsigned long int n
)
150 m_string
+= boost::lexical_cast
<StringType
>(n
);
154 BasicBuffer
<CharT
> &operator<<(CharT c
)
160 BasicBuffer
<CharT
> &operator<<(const CharT
*s
)
166 BasicBuffer
<CharT
> &operator<<(const StringType
&s
)
172 BasicBuffer
<CharT
> &operator<<(Color color
)
174 setProperty(m_string
.size(), color
);
178 BasicBuffer
<CharT
> &operator<<(Format format
)
180 setProperty(m_string
.size(), format
);
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
)
190 result
.construct(std::forward
<Args
>(args
)...);
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
)...);
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())
217 auto &s
= buffer
.str();
218 auto &ps
= buffer
.properties();
220 for (size_t i
= 0; i
< s
.size(); ++i
)
222 for (; p
!= ps
.end() && p
->position() == i
; ++p
)
226 // load remaining properties
227 for (; p
!= ps
.end(); ++p
)
235 #endif // NCMPCPP_STRBUFFER_H