TGUI  0.10-dev
String.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2021 Bruno Van de Velde (vdv_b@tgui.eu)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
25
26#ifndef TGUI_STRING_HPP
27#define TGUI_STRING_HPP
28
29#include <TGUI/Config.hpp>
30#include <TGUI/Utf.hpp>
31#include <string>
32#include <vector>
33#include <cstring>
34#include <locale>
35#include <iomanip>
36#include <ostream>
37#include <sstream>
38
39#if TGUI_HAS_WINDOW_BACKEND_SFML
40 #include <SFML/System/String.hpp>
41#endif
42
43#if TGUI_COMPILED_WITH_CPP_VER >= 17
44 #include <type_traits>
45 #include <string_view>
46#endif
47
49
50namespace tgui
51{
55 TGUI_API bool isWhitespace(char character);
56
57
61 TGUI_API bool isWhitespace(char32_t character);
62
63
78 class TGUI_API String
79 {
80 private:
81 std::u32string m_string;
82
83#if TGUI_COMPILED_WITH_CPP_VER >= 17
84 // Helper to check if template parameter is a string_view
85 template <typename StringViewType>
86 using IsStringViewType = std::enable_if_t<
87 std::is_same_v<StringViewType, std::string_view>
88#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
89 || std::is_same_v<StringViewType, std::u8string_view>
90#endif
91 || std::is_same_v<StringViewType, std::wstring_view>
92 || std::is_same_v<StringViewType, std::u16string_view>
93 || std::is_same_v<StringViewType, std::u32string_view>,
94 void>;
95#endif
96
97 public:
98
99 static const decltype(std::u32string::npos) npos;
100
101 using iterator = std::u32string::iterator;
102 using const_iterator = std::u32string::const_iterator;
103 using reverse_iterator = std::u32string::reverse_iterator;
104 using const_reverse_iterator = std::u32string::const_reverse_iterator;
105
106 using value_type = char32_t;
107 using reference = char32_t&;
108 using const_reference = const char32_t&;
109
110
111 public:
112
120 bool attemptToInt(int& result) const;
121
122
130 bool attemptToUInt(unsigned int& result) const;
131
132
140 bool attemptToFloat(float& result) const;
141
142
150 int toInt(int defaultValue = 0) const;
151
152
160 unsigned int toUInt(unsigned int defaultValue = 0) const;
161
162
170 float toFloat(float defaultValue = 0) const;
171
172
178 String trim() const;
179
180
187
188
195
196
204 bool equalIgnoreCase(const String& other) const;
205
206
214 bool startsWith(const String& substring) const;
215
216
224 bool endsWith(const String& substring) const;
225
226
235 String& replace(const String& searchFor, const String& replaceWith);
236
237
244 std::vector<String> split(char32_t delimiter, bool trim = false) const;
245
246
253 static String join(const std::vector<String>& segments, const String& separator);
254
255
263 template <typename T>
264 static String fromNumber(T value)
265 {
266 std::ostringstream oss;
267 oss.imbue(std::locale::classic());
268 oss << value;
269 return String(oss.str());
270 }
271
272
281 template <typename T>
282 static String fromNumberRounded(T value, int decimals)
283 {
284 std::ostringstream oss;
285 oss.imbue(std::locale::classic());
286 oss << std::fixed << std::setprecision(decimals);
287 oss << value;
288 return String(oss.str());
289 }
290
292 public:
293
294 String() = default;
295
296 String(const std::string& str);
297 String(const std::wstring& str);
298 String(const std::u16string& str);
299 String(const std::u32string& str);
300
301 String(std::u32string&& str) :
302 m_string{std::move(str)}
303 {
304 }
305
306 String(char ansiChar);
307 String(wchar_t wideChar);
308 String(char16_t utfChar);
309 String(char32_t utfChar);
310
311 String(const char* str);
312 String(const wchar_t* str);
313 String(const char16_t* str);
314 String(const char32_t* str) :
315 m_string{str}
316 {
317 }
318
319 // Constructor to initialize the string from a number (integer or float)
320 template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
321 explicit String(T number) :
322 String{fromNumber(number)}
323 {
324 }
325
326 String(std::size_t count, char ch);
327 String(std::size_t count, wchar_t ch);
328 String(std::size_t count, char16_t ch);
329 String(std::size_t count, char32_t ch);
330
331 String(const std::string& str, std::size_t pos);
332 String(const std::wstring& str, std::size_t pos);
333 String(const std::u16string& str, std::size_t pos);
334 String(const std::u32string& str, std::size_t pos);
335
336 String(const std::string& str, std::size_t pos, std::size_t count);
337 String(const std::wstring& str, std::size_t pos, std::size_t count);
338 String(const std::u16string& str, std::size_t pos, std::size_t count);
339 String(const std::u32string& str, std::size_t pos, std::size_t count);
340
341 String(const char* str, std::size_t count);
342 String(const wchar_t* str, std::size_t count);
343 String(const char16_t* str, std::size_t count);
344 String(const char32_t* str, std::size_t count);
345
346 explicit String(std::initializer_list<char> chars);
347 explicit String(std::initializer_list<wchar_t> chars);
348 explicit String(std::initializer_list<char16_t> chars);
349 explicit String(std::initializer_list<char32_t> chars);
350
351 // Constructors using iterators have to be explicit to prevent {"1", "2"} to be ambiguous between String and std::vector<String>.
352 // The reason these constructors were considered a candicate to clang is due to a private constructor in the iterator class.
353 explicit String(std::string::const_iterator first, std::string::const_iterator last);
354 explicit String(std::wstring::const_iterator first, std::wstring::const_iterator last);
355 explicit String(std::u16string::const_iterator first, std::u16string::const_iterator last);
356 explicit String(std::u32string::const_iterator first, std::u32string::const_iterator last);
357
358#if TGUI_COMPILED_WITH_CPP_VER >= 17
359 template <typename StringViewType, typename = IsStringViewType<StringViewType>>
360 explicit String(const StringViewType& stringView) :
361 String(stringView.data(), stringView.size())
362 {
363 }
364
365 template <typename StringViewType, typename = IsStringViewType<StringViewType>>
366 explicit String(const StringViewType& stringView, std::size_t pos, std::size_t count) :
367 String(stringView.data(), pos, count)
368 {
369 }
370#endif
371
372#if TGUI_HAS_WINDOW_BACKEND_SFML
373 // This constructor has to be explicit or it will cause MSVC to no longer compile code that performs sf::String + std::string
374 explicit String(const sf::String& str)
375 : m_string{reinterpret_cast<const char32_t*>(str.toUtf32().c_str())}
376 {
377 }
378
379 explicit operator sf::String() const
380 {
381 return sf::String::fromUtf32(m_string.begin(), m_string.end());
382 }
383#endif
384
385 explicit operator std::string() const;
386 explicit operator std::wstring() const;
387 explicit operator std::u16string() const;
388 explicit operator const std::u32string&() const
389 {
390 return m_string;
391 }
392
393#if TGUI_COMPILED_WITH_CPP_VER >= 17
394 operator std::u32string_view() const noexcept
395 {
396 return m_string;
397 }
398#endif
399
400 std::string toStdString() const;
401 std::wstring toWideString() const;
402 std::u16string toUtf16() const;
403 const std::u32string& toUtf32() const
404 {
405 return m_string;
406 }
407
408 String& assign(std::size_t count, char ch);
409 String& assign(std::size_t count, wchar_t ch);
410 String& assign(std::size_t count, char16_t ch);
411 String& assign(std::size_t count, char32_t ch);
412
413 String& assign(const std::string& str);
414 String& assign(const std::wstring& str);
415 String& assign(const std::u16string& str);
416 String& assign(const std::u32string& str);
417 String& assign(const String& str);
418
419 String& assign(const std::string& str, std::size_t pos, std::size_t count = npos);
420 String& assign(const std::wstring& str, std::size_t pos, std::size_t count = npos);
421 String& assign(const std::u16string& str, std::size_t pos, std::size_t count = npos);
422 String& assign(const std::u32string& str, std::size_t pos, std::size_t count = npos);
423 String& assign(const String& str, std::size_t pos, std::size_t count = npos);
424
425 String& assign(std::string&& str);
426 String& assign(std::wstring&& str);
427 String& assign(std::u16string&& str);
428 String& assign(std::u32string&& str);
429 String& assign(String&& str);
430
431 String& assign(const char* str, std::size_t count);
432 String& assign(const wchar_t* str, std::size_t count);
433 String& assign(const char16_t* str, std::size_t count);
434 String& assign(const char32_t* str, std::size_t count);
435
436 String& assign(const char* str);
437 String& assign(const wchar_t* str);
438 String& assign(const char16_t* str);
439 String& assign(const char32_t* str);
440
441 String& assign(std::initializer_list<char> chars);
442 String& assign(std::initializer_list<wchar_t> chars);
443 String& assign(std::initializer_list<char16_t> chars);
444 String& assign(std::initializer_list<char32_t> chars);
445
446 String& assign(std::string::const_iterator first, std::string::const_iterator last);
447 String& assign(std::wstring::const_iterator first, std::wstring::const_iterator last);
448 String& assign(std::u16string::const_iterator first, std::u16string::const_iterator last);
449 String& assign(std::u32string::const_iterator first, std::u32string::const_iterator last);
450
451 reference at(std::size_t pos);
452 const_reference at(std::size_t pos) const;
453
454 const_reference operator [](std::size_t index) const;
455 reference operator [](std::size_t index);
456
457 reference front();
458 const_reference front() const;
459
460 reference back();
461 const_reference back() const;
462
463 const char32_t* data() const noexcept
464 {
465 return m_string.data();
466 }
467
468#if __cplusplus >= 201703L
469 char32_t* data() noexcept
470 {
471 return m_string.data();
472 }
473#endif
474 const char32_t* c_str() const noexcept
475 {
476 return m_string.c_str();
477 }
478
479 iterator begin() noexcept;
480 const_iterator begin() const noexcept;
481 const_iterator cbegin() const noexcept;
482
483 iterator end() noexcept;
484 const_iterator end() const noexcept;
485 const_iterator cend() const noexcept;
486
487 reverse_iterator rbegin() noexcept;
488 const_reverse_iterator rbegin() const noexcept;
489 const_reverse_iterator crbegin() const noexcept;
490
491 reverse_iterator rend() noexcept;
492 const_reverse_iterator rend() const noexcept;
493 const_reverse_iterator crend() const noexcept;
494
495 bool empty() const noexcept
496 {
497 return m_string.empty();
498 }
499
500 std::size_t size() const noexcept
501 {
502 return m_string.size();
503 }
504
505 std::size_t length() const noexcept
506 {
507 return m_string.length();
508 }
509
510 std::size_t max_size() const noexcept;
511
512 void reserve(std::size_t newCap);
513 std::size_t capacity() const noexcept;
514 void shrink_to_fit();
515
516 void clear() noexcept;
517
518 String& insert(std::size_t index, std::size_t count, char ch);
519 String& insert(std::size_t index, std::size_t count, wchar_t ch);
520 String& insert(std::size_t index, std::size_t count, char16_t ch);
521 String& insert(std::size_t index, std::size_t count, char32_t ch);
522
523 String& insert(std::size_t index, const std::string& str);
524 String& insert(std::size_t index, const std::wstring& str);
525 String& insert(std::size_t index, const std::u16string& str);
526 String& insert(std::size_t index, const std::u32string& str);
527 String& insert(std::size_t index, const String& str);
528
529 String& insert(std::size_t index, const std::string& str, std::size_t pos, std::size_t count = npos);
530 String& insert(std::size_t index, const std::wstring& str, std::size_t pos, std::size_t count = npos);
531 String& insert(std::size_t index, const std::u16string& str, std::size_t pos, std::size_t count = npos);
532 String& insert(std::size_t index, const std::u32string& str, std::size_t pos, std::size_t count = npos);
533 String& insert(std::size_t index, const String& str, std::size_t pos, std::size_t count = npos);
534
535 String& insert(std::size_t index, const char* str, std::size_t count);
536 String& insert(std::size_t index, const wchar_t* str, std::size_t count);
537 String& insert(std::size_t index, const char16_t* str, std::size_t count);
538 String& insert(std::size_t index, const char32_t* str, std::size_t count);
539
540 String& insert(std::size_t index, const char* str);
541 String& insert(std::size_t index, const wchar_t* str);
542 String& insert(std::size_t index, const char16_t* str);
543 String& insert(std::size_t index, const char32_t* str);
544
545 iterator insert(const_iterator pos, char ch);
546 iterator insert(const_iterator pos, wchar_t ch);
547 iterator insert(const_iterator pos, char16_t ch);
548 iterator insert(const_iterator pos, char32_t ch);
549
550 iterator insert(const_iterator pos, std::size_t count, char ch);
551 iterator insert(const_iterator pos, std::size_t count, wchar_t ch);
552 iterator insert(const_iterator pos, std::size_t count, char16_t ch);
553 iterator insert(const_iterator pos, std::size_t count, char32_t ch);
554
555 iterator insert(const_iterator pos, std::initializer_list<char> chars);
556 iterator insert(const_iterator pos, std::initializer_list<wchar_t> chars);
557 iterator insert(const_iterator pos, std::initializer_list<char16_t> chars);
558 iterator insert(const_iterator pos, std::initializer_list<char32_t> chars);
559
560 iterator insert(const_iterator pos, std::string::const_iterator first, std::string::const_iterator last);
561 iterator insert(const_iterator pos, std::wstring::const_iterator first, std::wstring::const_iterator last);
562 iterator insert(const_iterator pos, std::u16string::const_iterator first, std::u16string::const_iterator last);
563 iterator insert(const_iterator pos, std::u32string::const_iterator first, std::u32string::const_iterator last);
564
565 String& erase(std::size_t index = 0, std::size_t count = npos);
566
567 iterator erase(const_iterator position);
568 iterator erase(const_iterator first, const_iterator last);
569
570 void push_back(char ch);
571 void push_back(wchar_t ch);
572 void push_back(char16_t ch);
573 void push_back(char32_t ch);
574
575 void pop_back();
576
577 String& append(std::size_t count, char ch);
578 String& append(std::size_t count, wchar_t ch);
579 String& append(std::size_t count, char16_t ch);
580 String& append(std::size_t count, char32_t ch);
581
582 String& append(const std::string& str);
583 String& append(const std::wstring& str);
584 String& append(const std::u16string& str);
585 String& append(const std::u32string& str);
586 String& append(const String& str);
587
588 String& append(const std::string& str, std::size_t pos, std::size_t count = npos);
589 String& append(const std::wstring& str, std::size_t pos, std::size_t count = npos);
590 String& append(const std::u16string& str, std::size_t pos, std::size_t count = npos);
591 String& append(const std::u32string& str, std::size_t pos, std::size_t count = npos);
592 String& append(const String& str, std::size_t pos, std::size_t count = npos);
593
594 String& append(const char* str, std::size_t count);
595 String& append(const wchar_t* str, std::size_t count);
596 String& append(const char16_t* str, std::size_t count);
597 String& append(const char32_t* str, std::size_t count);
598
599 String& append(const char* str);
600 String& append(const wchar_t* str);
601 String& append(const char16_t* str);
602 String& append(const char32_t* str);
603
604 String& append(std::string::const_iterator first, std::string::const_iterator last);
605 String& append(std::wstring::const_iterator first, std::wstring::const_iterator last);
606 String& append(std::u16string::const_iterator first, std::u16string::const_iterator last);
607 String& append(std::u32string::const_iterator first, std::u32string::const_iterator last);
608
609 String& append(std::initializer_list<char> chars);
610 String& append(std::initializer_list<wchar_t> chars);
611 String& append(std::initializer_list<char16_t> chars);
612 String& append(std::initializer_list<char32_t> chars);
613
614 String& operator+=(const String& str);
615
616 int compare(const std::string& str) const noexcept;
617 int compare(const std::wstring& str) const noexcept;
618 int compare(const std::u16string& str) const noexcept;
619 int compare(const std::u32string& str) const noexcept;
620 int compare(const String& str) const noexcept;
621
622 int compare(std::size_t pos1, std::size_t count1, const std::string& str) const;
623 int compare(std::size_t pos1, std::size_t count1, const std::wstring& str) const;
624 int compare(std::size_t pos1, std::size_t count1, const std::u16string& str) const;
625 int compare(std::size_t pos1, std::size_t count1, const std::u32string& str) const;
626 int compare(std::size_t pos1, std::size_t count1, const String& str) const;
627
628 int compare(std::size_t pos1, std::size_t count1, const std::string& str, std::size_t pos2, std::size_t count2 = npos) const;
629 int compare(std::size_t pos1, std::size_t count1, const std::wstring& str, std::size_t pos2, std::size_t count2 = npos) const;
630 int compare(std::size_t pos1, std::size_t count1, const std::u16string& str, std::size_t pos2, std::size_t count2 = npos) const;
631 int compare(std::size_t pos1, std::size_t count1, const std::u32string& str, std::size_t pos2, std::size_t count2 = npos) const;
632 int compare(std::size_t pos1, std::size_t count1, const String& str, std::size_t pos2, std::size_t count2 = npos) const;
633
634 int compare(const char* s) const;
635 int compare(const wchar_t* s) const;
636 int compare(const char16_t* s) const;
637 int compare(const char32_t* s) const;
638
639 int compare(std::size_t pos1, std::size_t count1, const char* s) const;
640 int compare(std::size_t pos1, std::size_t count1, const wchar_t* s) const;
641 int compare(std::size_t pos1, std::size_t count1, const char16_t* s) const;
642 int compare(std::size_t pos1, std::size_t count1, const char32_t* s) const;
643
644 int compare(std::size_t pos1, std::size_t count1, const char* s, std::size_t count2) const;
645 int compare(std::size_t pos1, std::size_t count1, const wchar_t* s, std::size_t count2) const;
646 int compare(std::size_t pos1, std::size_t count1, const char16_t* s, std::size_t count2) const;
647 int compare(std::size_t pos1, std::size_t count1, const char32_t* s, std::size_t count2) const;
648
649 String& replace(std::size_t pos, std::size_t count, const std::string& str);
650 String& replace(std::size_t pos, std::size_t count, const std::wstring& str);
651 String& replace(std::size_t pos, std::size_t count, const std::u16string& str);
652 String& replace(std::size_t pos, std::size_t count, const std::u32string& str);
653 String& replace(std::size_t pos, std::size_t count, const String& str);
654
655 String& replace(const_iterator first, const_iterator last, const std::string& str);
656 String& replace(const_iterator first, const_iterator last, const std::wstring& str);
657 String& replace(const_iterator first, const_iterator last, const std::u16string& str);
658 String& replace(const_iterator first, const_iterator last, const std::u32string& str);
659 String& replace(const_iterator first, const_iterator last, const String& str);
660
661 String& replace(std::size_t pos, std::size_t count, const std::string& str, std::size_t pos2, std::size_t count2 = npos);
662 String& replace(std::size_t pos, std::size_t count, const std::wstring& str, std::size_t pos2, std::size_t count2 = npos);
663 String& replace(std::size_t pos, std::size_t count, const std::u16string& str, std::size_t pos2, std::size_t count2 = npos);
664 String& replace(std::size_t pos, std::size_t count, const std::u32string& str, std::size_t pos2, std::size_t count2 = npos);
665 String& replace(std::size_t pos, std::size_t count, const String& str, std::size_t pos2, std::size_t count2 = npos);
666
667 String& replace(const_iterator first, const_iterator last, std::string::const_iterator first2, std::string::const_iterator last2);
668 String& replace(const_iterator first, const_iterator last, std::wstring::const_iterator first2, std::wstring::const_iterator last2);
669 String& replace(const_iterator first, const_iterator last, std::u16string::const_iterator first2, std::u16string::const_iterator last2);
670 String& replace(const_iterator first, const_iterator last, std::u32string::const_iterator first2, std::u32string::const_iterator last2);
671
672 String& replace(std::size_t pos, std::size_t count, const char* cstr, std::size_t count2);
673 String& replace(std::size_t pos, std::size_t count, const wchar_t* cstr, std::size_t count2);
674 String& replace(std::size_t pos, std::size_t count, const char16_t* cstr, std::size_t count2);
675 String& replace(std::size_t pos, std::size_t count, const char32_t* cstr, std::size_t count2);
676
677 String& replace(const_iterator first, const_iterator last, const char* cstr, std::size_t count2);
678 String& replace(const_iterator first, const_iterator last, const wchar_t* cstr, std::size_t count2);
679 String& replace(const_iterator first, const_iterator last, const char16_t* cstr, std::size_t count2);
680 String& replace(const_iterator first, const_iterator last, const char32_t* cstr, std::size_t count2);
681
682 String& replace(std::size_t pos, std::size_t count, const char* cstr);
683 String& replace(std::size_t pos, std::size_t count, const wchar_t* cstr);
684 String& replace(std::size_t pos, std::size_t count, const char16_t* cstr);
685 String& replace(std::size_t pos, std::size_t count, const char32_t* cstr);
686
687 String& replace(const_iterator first, const_iterator last, const char* cstr);
688 String& replace(const_iterator first, const_iterator last, const wchar_t* cstr);
689 String& replace(const_iterator first, const_iterator last, const char16_t* cstr);
690 String& replace(const_iterator first, const_iterator last, const char32_t* cstr);
691
692 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char ch);
693 String& replace(std::size_t pos, std::size_t count, std::size_t count2, wchar_t ch);
694 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char16_t ch);
695 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char32_t ch);
696
697 String& replace(const_iterator first, const_iterator last, std::size_t count2, char ch);
698 String& replace(const_iterator first, const_iterator last, std::size_t count2, wchar_t ch);
699 String& replace(const_iterator first, const_iterator last, std::size_t count2, char16_t ch);
700 String& replace(const_iterator first, const_iterator last, std::size_t count2, char32_t ch);
701
702 String& replace(const_iterator first, const_iterator last, std::initializer_list<char> chars);
703 String& replace(const_iterator first, const_iterator last, std::initializer_list<wchar_t> chars);
704 String& replace(const_iterator first, const_iterator last, std::initializer_list<char16_t> chars);
705 String& replace(const_iterator first, const_iterator last, std::initializer_list<char32_t> chars);
706
707 String substr(std::size_t pos = 0, std::size_t count = npos) const;
708
709 std::size_t copy(char32_t* dest, std::size_t count, std::size_t pos = 0) const;
710
711 void resize(std::size_t count);
712 void resize(std::size_t count, char ch);
713 void resize(std::size_t count, wchar_t ch);
714 void resize(std::size_t count, char16_t ch);
715 void resize(std::size_t count, char32_t ch);
716
717 void swap(String& other);
718
719#if TGUI_COMPILED_WITH_CPP_VER >= 17
720 bool contains(std::u32string_view sv) const noexcept;
721#endif
722
723 bool contains(char c) const noexcept;
724 bool contains(wchar_t c) const noexcept;
725 bool contains(char16_t c) const noexcept;
726 bool contains(char32_t c) const noexcept;
727
728 bool contains(const char* s) const;
729 bool contains(const wchar_t* s) const;
730 bool contains(const char16_t* s) const;
731 bool contains(const char32_t* s) const;
732
733 std::size_t find(const std::string& str, std::size_t pos = 0) const noexcept;
734 std::size_t find(const std::wstring& str, std::size_t pos = 0) const noexcept;
735 std::size_t find(const std::u16string& str, std::size_t pos = 0) const noexcept;
736 std::size_t find(const std::u32string& str, std::size_t pos = 0) const noexcept;
737 std::size_t find(const String& str, std::size_t pos = 0) const noexcept;
738
739 std::size_t find(const char* s, std::size_t pos, std::size_t count) const;
740 std::size_t find(const wchar_t* s, std::size_t pos, std::size_t count) const;
741 std::size_t find(const char16_t* s, std::size_t pos, std::size_t count) const;
742 std::size_t find(const char32_t* s, std::size_t pos, std::size_t count) const;
743
744 std::size_t find(const char* s, std::size_t pos = 0) const;
745 std::size_t find(const wchar_t* s, std::size_t pos = 0) const;
746 std::size_t find(const char16_t* s, std::size_t pos = 0) const;
747 std::size_t find(const char32_t* s, std::size_t pos = 0) const;
748
749 std::size_t find(char ch, std::size_t pos = 0) const noexcept;
750 std::size_t find(wchar_t ch, std::size_t pos = 0) const noexcept;
751 std::size_t find(char16_t ch, std::size_t pos = 0) const noexcept;
752 std::size_t find(char32_t ch, std::size_t pos = 0) const noexcept;
753
754#if TGUI_COMPILED_WITH_CPP_VER >= 17
755 std::size_t find(std::u32string_view sv, std::size_t pos = 0) const noexcept;
756#endif
757
758 std::size_t find_first_of(const std::string& str, std::size_t pos = 0) const noexcept;
759 std::size_t find_first_of(const std::wstring& str, std::size_t pos = 0) const noexcept;
760 std::size_t find_first_of(const std::u16string& str, std::size_t pos = 0) const noexcept;
761 std::size_t find_first_of(const std::u32string& str, std::size_t pos = 0) const noexcept;
762 std::size_t find_first_of(const String& str, std::size_t pos = 0) const noexcept;
763
764 std::size_t find_first_of(const char* s, std::size_t pos, std::size_t count) const;
765 std::size_t find_first_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
766 std::size_t find_first_of(const char16_t* s, std::size_t pos, std::size_t count) const;
767 std::size_t find_first_of(const char32_t* s, std::size_t pos, std::size_t count) const;
768
769 std::size_t find_first_of(const char* s, std::size_t pos = 0) const;
770 std::size_t find_first_of(const wchar_t* s, std::size_t pos = 0) const;
771 std::size_t find_first_of(const char16_t* s, std::size_t pos = 0) const;
772 std::size_t find_first_of(const char32_t* s, std::size_t pos = 0) const;
773
774 std::size_t find_first_of(char ch, std::size_t pos = 0) const noexcept;
775 std::size_t find_first_of(wchar_t ch, std::size_t pos = 0) const noexcept;
776 std::size_t find_first_of(char16_t ch, std::size_t pos = 0) const noexcept;
777 std::size_t find_first_of(char32_t ch, std::size_t pos = 0) const noexcept;
778
779 std::size_t find_first_not_of(const std::string& str, std::size_t pos = 0) const noexcept;
780 std::size_t find_first_not_of(const std::wstring& str, std::size_t pos = 0) const noexcept;
781 std::size_t find_first_not_of(const std::u16string& str, std::size_t pos = 0) const noexcept;
782 std::size_t find_first_not_of(const std::u32string& str, std::size_t pos = 0) const noexcept;
783 std::size_t find_first_not_of(const String& str, std::size_t pos = 0) const noexcept;
784
785 std::size_t find_first_not_of(const char* s, std::size_t pos, std::size_t count) const;
786 std::size_t find_first_not_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
787 std::size_t find_first_not_of(const char16_t* s, std::size_t pos, std::size_t count) const;
788 std::size_t find_first_not_of(const char32_t* s, std::size_t pos, std::size_t count) const;
789
790 std::size_t find_first_not_of(const char* s, std::size_t pos = 0) const;
791 std::size_t find_first_not_of(const wchar_t* s, std::size_t pos = 0) const;
792 std::size_t find_first_not_of(const char16_t* s, std::size_t pos = 0) const;
793 std::size_t find_first_not_of(const char32_t* s, std::size_t pos = 0) const;
794
795 std::size_t find_first_not_of(char ch, std::size_t pos = 0) const noexcept;
796 std::size_t find_first_not_of(wchar_t ch, std::size_t pos = 0) const noexcept;
797 std::size_t find_first_not_of(char16_t ch, std::size_t pos = 0) const noexcept;
798 std::size_t find_first_not_of(char32_t ch, std::size_t pos = 0) const noexcept;
799
800 std::size_t rfind(const std::string& str, std::size_t pos = npos) const noexcept;
801 std::size_t rfind(const std::wstring& str, std::size_t pos = npos) const noexcept;
802 std::size_t rfind(const std::u16string& str, std::size_t pos = npos) const noexcept;
803 std::size_t rfind(const std::u32string& str, std::size_t pos = npos) const noexcept;
804 std::size_t rfind(const String& str, std::size_t pos = npos) const noexcept;
805
806 std::size_t rfind(const char* s, std::size_t pos, std::size_t count) const;
807 std::size_t rfind(const wchar_t* s, std::size_t pos, std::size_t count) const;
808 std::size_t rfind(const char16_t* s, std::size_t pos, std::size_t count) const;
809 std::size_t rfind(const char32_t* s, std::size_t pos, std::size_t count) const;
810
811 std::size_t rfind(const char* s, std::size_t pos = npos) const;
812 std::size_t rfind(const wchar_t* s, std::size_t pos = npos) const;
813 std::size_t rfind(const char16_t* s, std::size_t pos = npos) const;
814 std::size_t rfind(const char32_t* s, std::size_t pos = npos) const;
815
816 std::size_t rfind(char ch, std::size_t pos = npos) const noexcept;
817 std::size_t rfind(wchar_t ch, std::size_t pos = npos) const noexcept;
818 std::size_t rfind(char16_t ch, std::size_t pos = npos) const noexcept;
819 std::size_t rfind(char32_t ch, std::size_t pos = npos) const noexcept;
820
821 std::size_t find_last_of(const std::string& str, std::size_t pos = npos) const noexcept;
822 std::size_t find_last_of(const std::wstring& str, std::size_t pos = npos) const noexcept;
823 std::size_t find_last_of(const std::u16string& str, std::size_t pos = npos) const noexcept;
824 std::size_t find_last_of(const std::u32string& str, std::size_t pos = npos) const noexcept;
825 std::size_t find_last_of(const String& str, std::size_t pos = npos) const noexcept;
826
827 std::size_t find_last_of(const char* s, std::size_t pos, std::size_t count) const;
828 std::size_t find_last_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
829 std::size_t find_last_of(const char16_t* s, std::size_t pos, std::size_t count) const;
830 std::size_t find_last_of(const char32_t* s, std::size_t pos, std::size_t count) const;
831
832 std::size_t find_last_of(const char* s, std::size_t pos = npos) const;
833 std::size_t find_last_of(const wchar_t* s, std::size_t pos = npos) const;
834 std::size_t find_last_of(const char16_t* s, std::size_t pos = npos) const;
835 std::size_t find_last_of(const char32_t* s, std::size_t pos = npos) const;
836
837 std::size_t find_last_of(char ch, std::size_t pos = npos) const noexcept;
838 std::size_t find_last_of(wchar_t ch, std::size_t pos = npos) const noexcept;
839 std::size_t find_last_of(char16_t ch, std::size_t pos = npos) const noexcept;
840 std::size_t find_last_of(char32_t ch, std::size_t pos = npos) const noexcept;
841
842 std::size_t find_last_not_of(const std::string& str, std::size_t pos = npos) const noexcept;
843 std::size_t find_last_not_of(const std::wstring& str, std::size_t pos = npos) const noexcept;
844 std::size_t find_last_not_of(const std::u16string& str, std::size_t pos = npos) const noexcept;
845 std::size_t find_last_not_of(const std::u32string& str, std::size_t pos = npos) const noexcept;
846 std::size_t find_last_not_of(const String& str, std::size_t pos = npos) const noexcept;
847
848 std::size_t find_last_not_of(const char* s, std::size_t pos, std::size_t count) const;
849 std::size_t find_last_not_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
850 std::size_t find_last_not_of(const char16_t* s, std::size_t pos, std::size_t count) const;
851 std::size_t find_last_not_of(const char32_t* s, std::size_t pos, std::size_t count) const;
852
853 std::size_t find_last_not_of(const char* s, std::size_t pos = npos) const;
854 std::size_t find_last_not_of(const wchar_t* s, std::size_t pos = npos) const;
855 std::size_t find_last_not_of(const char16_t* s, std::size_t pos = npos) const;
856 std::size_t find_last_not_of(const char32_t* s, std::size_t pos = npos) const;
857
858 std::size_t find_last_not_of(char ch, std::size_t pos = npos) const noexcept;
859 std::size_t find_last_not_of(wchar_t ch, std::size_t pos = npos) const noexcept;
860 std::size_t find_last_not_of(char16_t ch, std::size_t pos = npos) const noexcept;
861 std::size_t find_last_not_of(char32_t ch, std::size_t pos = npos) const noexcept;
862
863 friend bool operator==(const String& left, const String& right);
864 friend bool operator!=(const String& left, const String& right);
865 friend bool operator<(const String& left, const String& right);
866 friend bool operator<=(const String& left, const String& right);
867 friend bool operator>(const String& left, const String& right);
868 friend bool operator>=(const String& left, const String& right);
869 friend String operator+(const String& left, const String& right);
870 friend String operator+(const String& left, String&& right);
871 friend String operator+(String&& left, const String& right);
872 friend String operator+(String&& left, String&& right);
873
874#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
875 String(const std::u8string& str);
876 String(char8_t utfChar);
877 String(const char8_t* str);
878 String(std::size_t count, char8_t ch);
879 String(const std::u8string& str, std::size_t pos);
880 String(const std::u8string& str, std::size_t pos, std::size_t count);
881 String(const char8_t* str, std::size_t count);
882 String(std::initializer_list<char8_t> chars);
883 String(std::u8string::const_iterator first, std::u8string::const_iterator last);
884
885 explicit operator std::u8string() const;
886
887 std::u8string toUtf8() const;
888
889 String& assign(std::size_t count, char8_t ch);
890 String& assign(const std::u8string& str);
891 String& assign(const std::u8string& str, std::size_t pos, std::size_t count = npos);
892 String& assign(std::u8string&& str);
893 String& assign(const char8_t* str, std::size_t count);
894 String& assign(const char8_t* str);
895 String& assign(std::initializer_list<char8_t> chars);
896 String& assign(std::u8string::const_iterator first, std::u8string::const_iterator last);
897
898 String& insert(std::size_t index, std::size_t count, char8_t ch);
899 String& insert(std::size_t index, const std::u8string& str);
900 String& insert(std::size_t index, const std::u8string& str, std::size_t pos, std::size_t count = npos);
901 String& insert(std::size_t index, const char8_t* str, std::size_t count);
902 String& insert(std::size_t index, const char8_t* str);
903 iterator insert(const_iterator pos, char8_t ch);
904 iterator insert(const_iterator pos, std::size_t count, char8_t ch);
905 iterator insert(const_iterator pos, std::initializer_list<char8_t> chars);
906 iterator insert(const_iterator pos, std::u8string::const_iterator first, std::u8string::const_iterator last);
907
908 String& append(std::size_t count, char8_t ch);
909 String& append(const std::u8string& str);
910 String& append(const std::u8string& str, std::size_t pos, std::size_t count = npos);
911 String& append(const char8_t* str, std::size_t count);
912 String& append(const char8_t* str);
913 String& append(std::initializer_list<char8_t> chars);
914 String& append(std::u8string::const_iterator first, std::u8string::const_iterator last);
915
916 int compare(const std::u8string& str) const noexcept;
917 int compare(std::size_t pos1, std::size_t count1, const std::u8string& str) const;
918 int compare(std::size_t pos1, std::size_t count1, const std::u8string& str, std::size_t pos2, std::size_t count2 = npos) const;
919 int compare(const char8_t* s) const;
920 int compare(std::size_t pos1, std::size_t count1, const char8_t* s) const;
921 int compare(std::size_t pos1, std::size_t count1, const char8_t* s, std::size_t count2) const;
922
923 String& replace(std::size_t pos, std::size_t count, const std::u8string& str);
924 String& replace(const_iterator first, const_iterator last, const std::u8string& str);
925 String& replace(std::size_t pos, std::size_t count, const std::u8string& str, std::size_t pos2, std::size_t count2 = npos);
926 String& replace(const_iterator first, const_iterator last, std::u8string::const_iterator first2, std::u8string::const_iterator last2);
927 String& replace(std::size_t pos, std::size_t count, const char8_t* cstr, std::size_t count2);
928 String& replace(const_iterator first, const_iterator last, const char8_t* cstr, std::size_t count2);
929 String& replace(std::size_t pos, std::size_t count, const char8_t* cstr);
930 String& replace(const_iterator first, const_iterator last, const char8_t* cstr);
931 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char8_t ch);
932 String& replace(const_iterator first, const_iterator last, std::size_t count2, char8_t ch);
933 String& replace(const_iterator first, const_iterator last, std::initializer_list<char8_t> chars);
934
935 void resize(std::size_t count, char8_t ch);
936
937 bool contains(char8_t c) const noexcept;
938 bool contains(const char8_t* s) const noexcept;
939
940 std::size_t find(const std::u8string& str, std::size_t pos = 0) const noexcept;
941 std::size_t find(const char8_t* s, std::size_t pos, std::size_t count) const;
942 std::size_t find(const char8_t* s, std::size_t pos = 0) const;
943 std::size_t find(char8_t ch, std::size_t pos = 0) const noexcept;
944
945 std::size_t find_first_of(const std::u8string& str, std::size_t pos = 0) const noexcept;
946 std::size_t find_first_of(const char8_t* s, std::size_t pos, std::size_t count) const;
947 std::size_t find_first_of(const char8_t* s, std::size_t pos = 0) const;
948 std::size_t find_first_of(char8_t ch, std::size_t pos = 0) const noexcept;
949
950 std::size_t find_first_not_of(const std::u8string& str, std::size_t pos = 0) const noexcept;
951 std::size_t find_first_not_of(const char8_t* s, std::size_t pos, std::size_t count) const;
952 std::size_t find_first_not_of(const char8_t* s, std::size_t pos = 0) const;
953 std::size_t find_first_not_of(char8_t ch, std::size_t pos = 0) const noexcept;
954
955 std::size_t rfind(const std::u8string& str, std::size_t pos = npos) const noexcept;
956 std::size_t rfind(const char8_t* s, std::size_t pos, std::size_t count) const;
957 std::size_t rfind(const char8_t* s, std::size_t pos = npos) const;
958 std::size_t rfind(char8_t ch, std::size_t pos = npos) const noexcept;
959
960 std::size_t find_last_of(const std::u8string& str, std::size_t pos = npos) const noexcept;
961 std::size_t find_last_of(const char8_t* s, std::size_t pos, std::size_t count) const;
962 std::size_t find_last_of(const char8_t* s, std::size_t pos = npos) const;
963 std::size_t find_last_of(char8_t ch, std::size_t pos = npos) const noexcept;
964
965 std::size_t find_last_not_of(const std::u8string& str, std::size_t pos = npos) const noexcept;
966 std::size_t find_last_not_of(const char8_t* s, std::size_t pos, std::size_t count) const;
967 std::size_t find_last_not_of(const char8_t* s, std::size_t pos = npos) const;
968 std::size_t find_last_not_of(char8_t ch, std::size_t pos = npos) const noexcept;
969
970 //friend std::basic_ostream<char8_t>& operator<<(std::basic_ostream<char8_t>& os, const String& str);
971#endif
972 };
973
975
976 inline bool operator==(const String& left, const String& right)
977 {
978 return left.m_string == right.m_string;
979 }
980
981 inline bool operator!=(const String& left, const String& right)
982 {
983 return left.m_string != right.m_string;
984 }
985
986 inline bool operator<(const String& left, const String& right)
987 {
988 return left.m_string < right.m_string;
989 }
990
991 inline bool operator<=(const String& left, const String& right)
992 {
993 return left.m_string <= right.m_string;
994 }
995
996 inline bool operator>(const String& left, const String& right)
997 {
998 return left.m_string > right.m_string;
999 }
1000
1001 inline bool operator>=(const String& left, const String& right)
1002 {
1003 return left.m_string >= right.m_string;
1004 }
1005
1006 inline String operator+(const String& left, const String& right)
1007 {
1008 return String(left.m_string + right.m_string);
1009 }
1010 inline String operator+(String&& left, String&& right)
1011 {
1012 return String(std::move(left.m_string) + std::move(right.m_string));
1013 }
1014 inline String operator+(String&& left, const String& right)
1015 {
1016 return String(std::move(left.m_string) + right.m_string);
1017 }
1018 inline String operator+(const String& left, String&& right)
1019 {
1020 return String(left.m_string + std::move(right.m_string));
1021 }
1022
1023 TGUI_API std::basic_ostream<char>& operator<<(std::basic_ostream<char>& os, const String& str);
1024 TGUI_API std::basic_ostream<wchar_t>& operator<<(std::basic_ostream<wchar_t>& os, const String& str);
1025 //TGUI_API std::basic_ostream<char16_t>& operator<<(std::basic_ostream<char16_t>& os, const String& str);
1026 //TGUI_API std::basic_ostream<char32_t>& operator<<(std::basic_ostream<char32_t>& os, const String& str);
1027
1028
1029 // UTF-8 function are defined in the header so that they can be enabled/disabled based on
1030 // the compiler settings without having to recompile TGUI with a different c++ standard.
1031#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
1032 inline String::String(const std::u8string& str) :
1033 m_string(utf::convertUtf8toUtf32(str.begin(), str.end()))
1034 {
1035 }
1036
1037 inline String::String(char8_t utfChar)
1038 : m_string(1, static_cast<char32_t>(utfChar))
1039 {
1040 }
1041
1042 inline String::String(const char8_t* str)
1043 : String{utf::convertUtf8toUtf32(str, str + std::char_traits<char8_t>::length(str))}
1044 {
1045 }
1046
1047 inline String::String(std::size_t count, char8_t ch)
1048 : m_string(count, static_cast<char32_t>(ch))
1049 {
1050 }
1051
1052 inline String::String(const std::u8string& str, std::size_t pos)
1053 : String{std::u8string(str, pos)}
1054 {
1055 }
1056
1057 inline String::String(const std::u8string& str, std::size_t pos, std::size_t count)
1058 : String{std::u8string(str, pos, count)}
1059 {
1060 }
1061
1062 inline String::String(const char8_t* str, std::size_t count)
1063 : String{std::u8string{str, count}}
1064 {
1065 }
1066
1067 inline String::String(std::initializer_list<char8_t> chars)
1068 : String(std::u8string(chars.begin(), chars.end()))
1069 {
1070 }
1071
1072 inline String::String(std::u8string::const_iterator first, std::u8string::const_iterator last)
1073 : String{std::u8string(first, last)}
1074 {
1075 }
1076
1077 inline String::operator std::u8string() const
1078 {
1079 return toUtf8();
1080 }
1081
1082 inline std::u8string String::toUtf8() const
1083 {
1084 return utf::convertUtf32toUtf8(m_string);
1085 }
1086
1087 inline String& String::assign(std::size_t count, char8_t ch)
1088 {
1089 m_string.assign(count, static_cast<char32_t>(ch));
1090 return *this;
1091 }
1092
1093 inline String& String::assign(const std::u8string& str)
1094 {
1095 return *this = str;
1096 }
1097
1098 inline String& String::assign(const std::u8string& str, std::size_t pos, std::size_t count)
1099 {
1100 return *this = {str, pos, count};
1101 }
1102
1103 inline String& String::assign(std::u8string&& str)
1104 {
1105 return *this = std::move(str);
1106 }
1107
1108 inline String& String::assign(const char8_t* str, std::size_t count)
1109 {
1110 return *this = {str, count};
1111 }
1112
1113 inline String& String::assign(const char8_t* str)
1114 {
1115 return *this = str;
1116 }
1117
1118 inline String& String::assign(std::initializer_list<char8_t> chars)
1119 {
1120 return *this = chars;
1121 }
1122
1123 inline String& String::assign(std::u8string::const_iterator first, std::u8string::const_iterator last)
1124 {
1125 return *this = {first, last};
1126 }
1127
1128 inline String& String::insert(std::size_t index, std::size_t count, char8_t ch)
1129 {
1130 m_string.insert(index, count, static_cast<char32_t>(ch));
1131 return *this;
1132 }
1133
1134 inline String& String::insert(std::size_t index, const std::u8string& str)
1135 {
1136 m_string.insert(index, String{str}.m_string);
1137 return *this;
1138 }
1139
1140 inline String& String::insert(std::size_t index, const std::u8string& str, std::size_t pos, std::size_t count)
1141 {
1142 m_string.insert(index, String{str, pos, count}.m_string);
1143 return *this;
1144 }
1145
1146 inline String& String::insert(std::size_t index, const char8_t* str, std::size_t count)
1147 {
1148 m_string.insert(index, String{str, count}.m_string);
1149 return *this;
1150 }
1151
1152 inline String& String::insert(std::size_t index, const char8_t* str)
1153 {
1154 m_string.insert(index, String{str}.m_string);
1155 return *this;
1156 }
1157
1158 inline String::iterator String::insert(String::const_iterator pos, char8_t ch)
1159 {
1160 return m_string.insert(pos, static_cast<char32_t>(ch));
1161 }
1162
1163 inline String::iterator String::insert(String::const_iterator pos, std::size_t count, char8_t ch)
1164 {
1165 return m_string.insert(pos, count, static_cast<char32_t>(ch));
1166 }
1167
1168 inline String::iterator String::insert(String::const_iterator pos, std::initializer_list<char8_t> chars)
1169 {
1170 auto tmpStr = String{chars};
1171 return m_string.insert(pos, tmpStr.begin(), tmpStr.end());
1172 }
1173
1174 inline String::iterator String::insert(String::const_iterator pos, std::u8string::const_iterator first, std::u8string::const_iterator last)
1175 {
1176 auto tmpStr = String{first, last};
1177 return m_string.insert(pos, tmpStr.begin(), tmpStr.end());
1178 }
1179
1180 inline String& String::append(std::size_t count, char8_t ch)
1181 {
1182 return append(String(count, ch));
1183 }
1184
1185 inline String& String::append(const std::u8string& str)
1186 {
1187 return append(String{str});
1188 }
1189
1190 inline String& String::append(const std::u8string& str, std::size_t pos, std::size_t count)
1191 {
1192 return append(String{str, pos, count});
1193 }
1194
1195 inline String& String::append(const char8_t* str, std::size_t count)
1196 {
1197 return append(String{str, count});
1198 }
1199
1200 inline String& String::append(const char8_t* str)
1201 {
1202 return append(String{str});
1203 }
1204
1205 inline String& String::append(std::initializer_list<char8_t> chars)
1206 {
1207 return append(String{chars});
1208 }
1209
1210 inline String& String::append(std::u8string::const_iterator first, std::u8string::const_iterator last)
1211 {
1212 return append(String{first, last});
1213 }
1214
1215 inline int String::compare(const std::u8string& str) const noexcept
1216 {
1217 return m_string.compare(String{str}.m_string);
1218 }
1219
1220 inline int String::compare(std::size_t pos1, std::size_t count1, const std::u8string& str) const
1221 {
1222 return m_string.compare(pos1, count1, String{str}.m_string);
1223 }
1224
1225 inline int String::compare(std::size_t pos1, std::size_t count1, const std::u8string& str, std::size_t pos2, std::size_t count2) const
1226 {
1227 return m_string.compare(pos1, count1, String{str, pos2, count2}.m_string);
1228 }
1229
1230 inline int String::compare(const char8_t* s) const
1231 {
1232 return m_string.compare(String{s}.m_string);
1233 }
1234
1235 inline int String::compare(std::size_t pos1, std::size_t count1, const char8_t* s) const
1236 {
1237 return m_string.compare(pos1, count1, String{s}.m_string);
1238 }
1239
1240 inline int String::compare(std::size_t pos1, std::size_t count1, const char8_t* s, std::size_t count2) const
1241 {
1242 return m_string.compare(pos1, count1, String{s, count2}.m_string);
1243 }
1244
1245 inline String& String::replace(std::size_t pos, std::size_t count, const std::u8string& str)
1246 {
1247 m_string.replace(pos, count, String{str}.m_string);
1248 return *this;
1249 }
1250
1251 inline String& String::replace(const_iterator first, const_iterator last, const std::u8string& str)
1252 {
1253 m_string.replace(first, last, String{str}.m_string);
1254 return *this;
1255 }
1256
1257 inline String& String::replace(std::size_t pos, std::size_t count, const std::u8string& str, std::size_t pos2, std::size_t count2)
1258 {
1259 m_string.replace(pos, count, String{str, pos2, count2}.m_string);
1260 return *this;
1261 }
1262
1263 inline String& String::replace(const_iterator first, const_iterator last, std::u8string::const_iterator first2, std::u8string::const_iterator last2)
1264 {
1265 m_string.replace(first, last, String{first2, last2}.m_string);
1266 return *this;
1267 }
1268
1269 inline String& String::replace(std::size_t pos, std::size_t count, const char8_t* cstr, std::size_t count2)
1270 {
1271 m_string.replace(pos, count, String{cstr, count2}.m_string);
1272 return *this;
1273 }
1274
1275 inline String& String::replace(const_iterator first, const_iterator last, const char8_t* cstr, std::size_t count2)
1276 {
1277 m_string.replace(first, last, String{cstr, count2}.m_string);
1278 return *this;
1279 }
1280
1281 inline String& String::replace(std::size_t pos, std::size_t count, const char8_t* cstr)
1282 {
1283 m_string.replace(pos, count, String{cstr}.m_string);
1284 return *this;
1285 }
1286
1287 inline String& String::replace(const_iterator first, const_iterator last, const char8_t* cstr)
1288 {
1289 m_string.replace(first, last, String{cstr}.m_string);
1290 return *this;
1291 }
1292
1293 inline String& String::replace(std::size_t pos, std::size_t count, std::size_t count2, char8_t ch)
1294 {
1295 m_string.replace(pos, count, String(count2, ch).m_string);
1296 return *this;
1297 }
1298
1299 inline String& String::replace(const_iterator first, const_iterator last, std::size_t count2, char8_t ch)
1300 {
1301 m_string.replace(first, last, String(count2, ch).m_string);
1302 return *this;
1303 }
1304
1305 inline String& String::replace(const_iterator first, const_iterator last, std::initializer_list<char8_t> chars)
1306 {
1307 m_string.replace(first, last, String{chars}.m_string);
1308 return *this;
1309 }
1310
1311 inline void String::resize(std::size_t count, char8_t ch)
1312 {
1313 m_string.resize(count, static_cast<char32_t>(ch));
1314 }
1315
1316 inline bool String::contains(char8_t c) const noexcept
1317 {
1318 return contains(static_cast<char32_t>(c));
1319 }
1320
1321 inline bool String::contains(const char8_t* s) const noexcept
1322 {
1323 return find(s) != npos;
1324 }
1325
1326 inline std::size_t String::find(const std::u8string& str, std::size_t pos) const noexcept
1327 {
1328 return m_string.find(String{str}.m_string, pos);
1329 }
1330
1331 inline std::size_t String::find(const char8_t* s, std::size_t pos, std::size_t count) const
1332 {
1333 return m_string.find(String{s, count}.m_string, pos);
1334 }
1335
1336 inline std::size_t String::find(const char8_t* s, std::size_t pos) const
1337 {
1338 return m_string.find(String{s}.m_string, pos);
1339 }
1340
1341 inline std::size_t String::find(char8_t ch, std::size_t pos) const noexcept
1342 {
1343 return m_string.find(static_cast<char32_t>(ch), pos);
1344 }
1345
1346 inline std::size_t String::find_first_of(const std::u8string& str, std::size_t pos) const noexcept
1347 {
1348 return m_string.find_first_of(String{str}.m_string, pos);
1349 }
1350
1351 inline std::size_t String::find_first_of(const char8_t* s, std::size_t pos, std::size_t count) const
1352 {
1353 return m_string.find_first_of(String{s, count}.m_string, pos);
1354 }
1355
1356 inline std::size_t String::find_first_of(const char8_t* s, std::size_t pos) const
1357 {
1358 return m_string.find_first_of(String{s}.m_string, pos);
1359 }
1360
1361 inline std::size_t String::find_first_of(char8_t ch, std::size_t pos) const noexcept
1362 {
1363 return m_string.find_first_of(static_cast<char32_t>(ch), pos);
1364 }
1365
1366 inline std::size_t String::find_first_not_of(const std::u8string& str, std::size_t pos) const noexcept
1367 {
1368 return m_string.find_first_not_of(String{str}.m_string, pos);
1369 }
1370
1371 inline std::size_t String::find_first_not_of(const char8_t* s, std::size_t pos, std::size_t count) const
1372 {
1373 return m_string.find_first_not_of(String{s, count}.m_string, pos);
1374 }
1375
1376 inline std::size_t String::find_first_not_of(const char8_t* s, std::size_t pos) const
1377 {
1378 return m_string.find_first_not_of(String{s}.m_string, pos);
1379 }
1380
1381 inline std::size_t String::find_first_not_of(char8_t ch, std::size_t pos) const noexcept
1382 {
1383 return m_string.find_first_not_of(static_cast<char32_t>(ch), pos);
1384 }
1385
1386 inline std::size_t String::rfind(const std::u8string& str, std::size_t pos) const noexcept
1387 {
1388 return m_string.rfind(String{str}.m_string, pos);
1389 }
1390
1391 inline std::size_t String::rfind(const char8_t* s, std::size_t pos, std::size_t count) const
1392 {
1393 return m_string.rfind(String{s, count}.m_string, pos);
1394 }
1395
1396 inline std::size_t String::rfind(const char8_t* s, std::size_t pos) const
1397 {
1398 return m_string.rfind(String{s}.m_string, pos);
1399 }
1400
1401 inline std::size_t String::rfind(char8_t ch, std::size_t pos) const noexcept
1402 {
1403 return m_string.rfind(static_cast<char32_t>(ch), pos);
1404 }
1405
1406 inline std::size_t String::find_last_of(const std::u8string& str, std::size_t pos) const noexcept
1407 {
1408 return m_string.find_last_of(String{str}.m_string, pos);
1409 }
1410
1411 inline std::size_t String::find_last_of(const char8_t* s, std::size_t pos, std::size_t count) const
1412 {
1413 return m_string.find_last_of(String{s, count}.m_string, pos);
1414 }
1415
1416 inline std::size_t String::find_last_of(const char8_t* s, std::size_t pos) const
1417 {
1418 return m_string.find_last_of(String{s}.m_string, pos);
1419 }
1420
1421 inline std::size_t String::find_last_of(char8_t ch, std::size_t pos) const noexcept
1422 {
1423 return m_string.find_last_of(static_cast<char32_t>(ch), pos);
1424 }
1425
1426 inline std::size_t String::find_last_not_of(const std::u8string& str, std::size_t pos) const noexcept
1427 {
1428 return m_string.find_last_not_of(String{str}.m_string, pos);
1429 }
1430
1431 inline std::size_t String::find_last_not_of(const char8_t* s, std::size_t pos, std::size_t count) const
1432 {
1433 return m_string.find_last_not_of(String{s, count}.m_string, pos);
1434 }
1435
1436 inline std::size_t String::find_last_not_of(const char8_t* s, std::size_t pos) const
1437 {
1438 return m_string.find_last_not_of(String{s}.m_string, pos);
1439 }
1440
1441 inline std::size_t String::find_last_not_of(char8_t ch, std::size_t pos) const noexcept
1442 {
1443 return m_string.find_last_not_of(static_cast<char8_t>(ch), pos);
1444 }
1445
1446 // Doesn't compile with libc++
1447 //inline std::basic_ostream<char8_t>& operator<<(std::basic_ostream<char8_t>& os, const String& str)
1448 //{
1449 // os << std::u8string(str);
1450 // return os;
1451 //}
1452#endif
1453
1455
1456#if TGUI_COMPILED_WITH_CPP_VER >= 17
1457 using StringView = std::u32string_view;
1458 using CharStringView = std::string_view;
1459#else
1460 using StringView = String;
1461 using CharStringView = std::string;
1462#endif
1463}
1464
1466
1467#endif // TGUI_STRING_HPP
Wrapper class to store strings.
Definition: String.hpp:79
bool attemptToFloat(float &result) const
Converts the string to a float.
std::vector< String > split(char32_t delimiter, bool trim=false) const
Splits the string into multiple substrings given the delimiter that separates them.
float toFloat(float defaultValue=0) const
Converts the string to a float.
static String fromNumberRounded(T value, int decimals)
Construct the string from a floating point number, keeping only a certain amount of decimals behind t...
Definition: String.hpp:282
bool equalIgnoreCase(const String &other) const
Compares this string to another and checks if they are equal if ASCII letters would have been lowerca...
bool startsWith(const String &substring) const
Checks whether the first part of the string matches the given substring.
static String fromNumber(T value)
Construct the string from a number.
Definition: String.hpp:264
static String join(const std::vector< String > &segments, const String &separator)
Joins multiple string segments into a single string.
bool endsWith(const String &substring) const
Checks whether the last part of the string matches the given substring.
bool attemptToUInt(unsigned int &result) const
Converts the string to an unsigned int.
String trim() const
Returns a string with the whitespace at the start and end of this string removed.
unsigned int toUInt(unsigned int defaultValue=0) const
Converts the string to an unsigned int.
int toInt(int defaultValue=0) const
Converts the string to an integer.
String toLower() const
Converts the ASCII characters in the string to lowercase.
bool attemptToInt(int &result) const
Converts the string to an integer.
String & replace(const String &searchFor, const String &replaceWith)
Replaces all occurrences of a substring with a replacement string.
String toUpper() const
Converts the ASCII characters in the string to uppercase.
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36
TGUI_API bool isWhitespace(char character)
Checks if a character is a whitespace character (space, tab, carriage return or line feed)