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