Terminal++ 4.0.1.23
A C++ library for interacting with ANSI terminal windows
Loading...
Searching...
No Matches
string.hpp
1#pragma once
2
3#include "terminalpp/element.hpp"
4
5#include <boost/container_hash/hash.hpp>
6
7#include <algorithm>
8#include <concepts> // IWYU pragma: keep
9#include <initializer_list>
10#include <string>
11#include <vector>
12#include <cstddef>
13
14namespace terminalpp {
15
16//* =========================================================================
20//* =========================================================================
22{
23 using elements_storage = std::vector<element>;
24
25public:
26 //* =====================================================================
28 //* =====================================================================
30 using reference = value_type &;
31 using const_reference = value_type const &;
32 using pointer = element *;
33 using const_pointer = element const *;
34 using iterator = elements_storage::iterator;
35 using const_iterator = elements_storage::const_iterator;
36 using reverse_iterator = elements_storage::reverse_iterator;
37 using const_reverse_iterator = elements_storage::const_reverse_iterator;
38 using difference_type = std::ptrdiff_t;
39 using size_type = std::size_t;
40
41 //* =====================================================================
43 //* =====================================================================
44 constexpr string() = default;
45
46 //* =====================================================================
48 //* =====================================================================
49 template <std::forward_iterator ForwardIterator>
50 constexpr string(ForwardIterator &&begin, ForwardIterator &&end)
51 : elements_{begin, end}
52 {
53 }
54
55 //* =====================================================================
57 //* =====================================================================
58 constexpr string(std::initializer_list<element> const &ilist)
59 : string{ilist.begin(), ilist.end()}
60 {
61 }
62
63 //* =====================================================================
68 //* =====================================================================
69 constexpr string(char const *text) // NOLINT
71 {
72 }
73
74 //* =====================================================================
80 //* =====================================================================
81 constexpr string(char const *text, size_type len)
82 : elements_{text, text + len}
83 {
84 }
85
86 //* =====================================================================
91 //* =====================================================================
92 constexpr string(std::string const &text) // NOLINT
93 : string{text.data(), text.size()}
94 {
95 }
96
97 //* =====================================================================
101 //* =====================================================================
102 constexpr string(std::string const &text, terminalpp::attribute const &attr)
103 : string{text}
104 {
105 std::ranges::for_each(
106 elements_, [&attr](auto &elem) { elem.attribute_ = attr; });
107 }
108
109 //* =====================================================================
113 //* =====================================================================
114 constexpr string(size_type size, terminalpp::element const &elem)
115 : elements_(size, elem)
116 {
117 }
118
119 //* =====================================================================
121 //* =====================================================================
122 [[nodiscard]] constexpr size_type size() const noexcept
123 {
124 return elements_.size();
125 }
126
127 //* =====================================================================
129 //* =====================================================================
130 [[nodiscard]] constexpr iterator begin() noexcept
131 {
132 return elements_.begin();
133 }
134
135 //* =====================================================================
137 //* =====================================================================
138 [[nodiscard]] constexpr const_iterator begin() const noexcept
139 {
140 return elements_.begin();
141 }
142
143 //* =====================================================================
146 //* =====================================================================
147 [[nodiscard]] constexpr reverse_iterator rbegin() noexcept
148 {
149 return elements_.rbegin();
150 }
151
152 //* =====================================================================
155 //* =====================================================================
156 [[nodiscard]] constexpr const_reverse_iterator rbegin() const noexcept
157 {
158 return elements_.rbegin();
159 }
160
161 //* =====================================================================
163 //* =====================================================================
164 [[nodiscard]] constexpr iterator end() noexcept
165 {
166 return elements_.end();
167 }
168
169 //* =====================================================================
171 //* =====================================================================
172 [[nodiscard]] constexpr const_iterator end() const noexcept
173 {
174 return elements_.end();
175 }
176
177 //* =====================================================================
179 //* =====================================================================
180 [[nodiscard]] constexpr reverse_iterator rend() noexcept
181 {
182 return elements_.rend();
183 }
184
185 //* =====================================================================
187 //* =====================================================================
188 [[nodiscard]] constexpr const_reverse_iterator rend() const noexcept
189 {
190 return elements_.rend();
191 }
192
193 //* =====================================================================
195 //* =====================================================================
196 [[nodiscard]] constexpr const_iterator cbegin() noexcept
197 {
198 return elements_.cbegin();
199 }
200
201 //* =====================================================================
203 //* =====================================================================
204 [[nodiscard]] constexpr const_iterator cend() noexcept
205 {
206 return elements_.cend();
207 }
208
209 //* =====================================================================
211 //* =====================================================================
212 constexpr void swap(string &other) noexcept
213 {
214 std::swap(elements_, other.elements_);
215 }
216
217 //* =====================================================================
219 //* =====================================================================
220 [[nodiscard]] constexpr size_type max_size() const noexcept
221 {
222 return std::numeric_limits<size_type>::max();
223 }
224
225 //* =====================================================================
227 //* =====================================================================
228 [[nodiscard]] constexpr bool empty() const noexcept
229 {
230 return elements_.empty();
231 }
232
233 //* =====================================================================
235 //* =====================================================================
236 [[nodiscard]] constexpr reference operator[](size_type index) noexcept
237 {
238 return elements_[index];
239 }
240
241 //* =====================================================================
243 //* =====================================================================
245 size_type index) const noexcept
246 {
247 return elements_[index];
248 }
249
250 //* =====================================================================
252 //* =====================================================================
253 constexpr string &operator+=(element const &elem)
254 {
255 elements_.insert(elements_.end(), elem);
256 return *this;
257 }
258
259 //* =====================================================================
261 //* =====================================================================
262 [[nodiscard]] friend string operator+(string lhs, element const &rhs)
263 {
264 return lhs += rhs;
265 }
266
267 //* =====================================================================
269 //* =====================================================================
270 constexpr string &operator+=(string const &rhs)
271 {
272 elements_.insert(elements_.end(), rhs.begin(), rhs.end());
273 return *this;
274 }
275
276 //* =====================================================================
278 //* =====================================================================
279 [[nodiscard]] friend string operator+(string lhs, string const &rhs)
280 {
281 return lhs += rhs;
282 }
283
284 //* =====================================================================
286 //* =====================================================================
287 constexpr void insert(iterator pos, element const &elem)
288 {
289 elements_.insert(pos, elem);
290 }
291
292 //* =====================================================================
294 //* =====================================================================
295 template <class InputIterator>
296 constexpr void insert(
298 {
299 elements_.insert(pos, range_begin, range_end);
300 }
301
302 //* =====================================================================
304 //* =====================================================================
305 constexpr void erase()
306 {
307 elements_.clear();
308 }
309
310 //* =====================================================================
312 //* =====================================================================
313 constexpr void erase(iterator range_begin)
314 {
315 elements_.erase(range_begin, elements_.end());
316 }
317
318 //* =====================================================================
320 //* =====================================================================
321 constexpr void erase(iterator range_begin, iterator range_end)
322 {
323 elements_.erase(range_begin, range_end);
324 }
325
326 //* =====================================================================
328 //* =====================================================================
329 [[nodiscard]] constexpr friend auto operator<=>(
330 string const &lhs, string const &rhs) noexcept = default;
331
332 //* =====================================================================
334 //* =====================================================================
336 constexpr friend bool operator==(
337 string const &lhs, string const &rhs) noexcept = default;
338
339 //* =====================================================================
341 //* =====================================================================
342 [[nodiscard]] friend std::size_t hash_value(string const &str) noexcept
343 {
344 return boost::hash_range(str.elements_.begin(), str.elements_.end());
345 }
346
347private:
348 elements_storage elements_;
349};
350
351//* =========================================================================
355//* =========================================================================
356TERMINALPP_EXPORT
357std::ostream &operator<<(std::ostream &out, string const &text);
358
359//* =========================================================================
362//* =========================================================================
363TERMINALPP_EXPORT
364[[nodiscard]] constexpr ::std::string to_string(terminalpp::string const &tstr)
365{
366 std::string result;
367
368 for (auto const &elem : tstr)
369 {
370 if (elem.glyph_.charset_ == charset::utf8)
371 {
372 for (auto const &ch : elem.glyph_.ucharacter_)
373 {
374 if (ch == 0)
375 {
376 break;
377 }
378
379 result += static_cast<char>(ch);
380 }
381 }
382 else
383 {
384 result += static_cast<char>(elem.glyph_.character_);
385 }
386 }
387
388 return result;
389}
390
391//* =========================================================================
394//* =========================================================================
395TERMINALPP_EXPORT
396constexpr terminalpp::string encode(std::span<char const> text)
397{
398 string result;
399 element prev_element;
400
401 while (!text.empty())
402 {
403 result += detail::parse_element(text, prev_element);
404 prev_element = *result.rbegin();
405 }
406
407 return result;
408}
409
410inline namespace literals {
411inline namespace string_literals {
412
413//* =========================================================================
415//* =========================================================================
416TERMINALPP_EXPORT
417[[nodiscard]] constexpr ::terminalpp::string operator""_ts(
418 char const *text, ::terminalpp::string::size_type length)
419{
420 return {text, length};
421}
422
423//* =========================================================================
425//* =========================================================================
426TERMINALPP_EXPORT
427[[nodiscard]] constexpr ::terminalpp::string operator""_ets(
428 char const *text, ::terminalpp::string::size_type length)
429{
430 return encode(std::span{text, length});
431}
432
433} // namespace string_literals
434} // namespace literals
435} // namespace terminalpp
436
437namespace std {
438
439template <>
440struct hash<terminalpp::string>
441{
442 using argument_type = terminalpp::string;
443 using result_type = std::size_t;
444
445 [[nodiscard]] result_type operator()(
446 argument_type const &str) const noexcept
447 {
448 return hash_value(str);
449 }
450};
451
452} // namespace std
A class that represents strings of elements.
Definition string.hpp:22
constexpr iterator begin() noexcept
Returns an iterator to the beginning of the string.
Definition string.hpp:130
constexpr friend auto operator<=>(string const &lhs, string const &rhs) noexcept=default
Relational operators for strings.
constexpr const_iterator cbegin() noexcept
Returns an iterator to the beginning of the string.
Definition string.hpp:196
constexpr reverse_iterator rend() noexcept
Returns a reverse iterator to the reverse end of the string.
Definition string.hpp:180
constexpr const_iterator end() const noexcept
Returns an iterator to the end of the string.
Definition string.hpp:172
constexpr string(std::string const &text)
Constructor.
Definition string.hpp:92
friend string operator+(string lhs, element const &rhs)
Append operator.
Definition string.hpp:262
constexpr size_type max_size() const noexcept
Returns the maximum size of the string allowed.
Definition string.hpp:220
constexpr string & operator+=(string const &rhs)
Append operator.
Definition string.hpp:270
constexpr string()=default
Constructor.
constexpr const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the reverse end of the string.
Definition string.hpp:188
constexpr void erase()
Erase.
Definition string.hpp:305
constexpr string & operator+=(element const &elem)
Append operator.
Definition string.hpp:253
constexpr string(std::initializer_list< element > const &ilist)
Initializer List Constructor.
Definition string.hpp:58
constexpr void erase(iterator range_begin)
Erase.
Definition string.hpp:313
constexpr void insert(iterator pos, element const &elem)
Inserts an element at the iterator position.
Definition string.hpp:287
constexpr const_iterator cend() noexcept
Returns an iterator to the end of the string.
Definition string.hpp:204
constexpr size_type size() const noexcept
Returns the number of elements in the string.
Definition string.hpp:122
constexpr string(ForwardIterator &&begin, ForwardIterator &&end)
Range Constructor.
Definition string.hpp:50
constexpr reverse_iterator rbegin() noexcept
Returns a reverse iterator to the reverse beginning of the string.
Definition string.hpp:147
constexpr void swap(string &other) noexcept
Swaps the contents of this and another string.
Definition string.hpp:212
constexpr void erase(iterator range_begin, iterator range_end)
Erase.
Definition string.hpp:321
constexpr const_iterator begin() const noexcept
Returns an iterator to the beginning of the string.
Definition string.hpp:138
constexpr string(std::string const &text, terminalpp::attribute const &attr)
Constructor.
Definition string.hpp:102
constexpr iterator end() noexcept
Returns an iterator to the end of the string.
Definition string.hpp:164
constexpr reference operator[](size_type index) noexcept
Array access operator.
Definition string.hpp:236
constexpr string(char const *text)
Constructor.
Definition string.hpp:69
constexpr const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the reverse beginning of the string.
Definition string.hpp:156
constexpr const_reference operator[](size_type index) const noexcept
Array access operator.
Definition string.hpp:244
TERMINALPP_EXPORT constexpr friend bool operator==(string const &lhs, string const &rhs) noexcept=default
Equality operator.
friend string operator+(string lhs, string const &rhs)
Append operator.
Definition string.hpp:279
friend std::size_t hash_value(string const &str) noexcept
Hash function.
Definition string.hpp:342
constexpr void insert(iterator pos, InputIterator range_begin, InputIterator range_end)
Inserts a range of elements at the iterator position.
Definition string.hpp:296
constexpr string(size_type size, terminalpp::element const &elem)
Construct a string of a number of identical elements.
Definition string.hpp:114
constexpr bool empty() const noexcept
Returns whether the string is empty or not.
Definition string.hpp:228
constexpr string(char const *text, size_type len)
Constructor.
Definition string.hpp:81
A structure that carries around the presentation attributes of an ANSI element.
Definition attribute.hpp:17
A structure representing an ANSI graphics effect (e.g. intensity, underlining)
Definition effect.hpp:27
constexpr effect() noexcept
Initialises the intensity to the default (normal) value.
Definition effect.hpp:31
A structure that represents the fundamental printable element of a terminal screen,...
Definition element.hpp:20