TGUI  1.0-beta
Loading...
Searching...
No Matches
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#ifndef TGUI_REMOVE_DEPRECATED_CODE
214 TGUI_DEPRECATED("Use starts_with instead") bool startsWith(const String& substring) const;
215#endif
216
224 bool startsWithIgnoreCase(const String& substring) const;
225
226#ifndef TGUI_REMOVE_DEPRECATED_CODE
234 TGUI_DEPRECATED("Use ends_with instead") bool endsWith(const String& substring) const;
235#endif
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 {oss.str()};
290 }
291
292
301 template <typename T>
302 static String fromNumberRounded(T value, unsigned int decimals)
303 {
304 std::ostringstream oss;
305 oss.imbue(std::locale::classic());
306 oss << std::fixed << std::setprecision(static_cast<int>(decimals));
307 oss << value;
308 return {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_t<std::is_arithmetic<T>::value, T>>
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 // We can't accept string_view::const_iterator iterators, because it would lead to the same kind of ambiguity even when the
374 // constructor is marked explicit (in GCC but not MSVC if we define the function normally, in MSVC but not GCC if we use a template).
375 explicit String(std::string::const_iterator first, std::string::const_iterator last);
376 explicit String(std::wstring::const_iterator first, std::wstring::const_iterator last);
377 explicit String(std::u16string::const_iterator first, std::u16string::const_iterator last);
378 explicit String(std::u32string::const_iterator first, std::u32string::const_iterator last);
379
380#if TGUI_COMPILED_WITH_CPP_VER >= 17
381 template <typename StringViewType, typename = IsStringViewType<StringViewType>>
382 explicit String(const StringViewType& stringView) :
383 String(stringView.data(), stringView.size())
384 {
385 }
386
387 template <typename StringViewType, typename = IsStringViewType<StringViewType>>
388 explicit String(const StringViewType& stringView, std::size_t pos, std::size_t count) :
389 String(stringView.data(), pos, count)
390 {
391 }
392#endif
393
394#if TGUI_HAS_WINDOW_BACKEND_SFML
395 // This constructor has to be explicit or it will cause MSVC to no longer compile code that performs sf::String + std::string
396 explicit String(const sf::String& str)
397 : m_string{reinterpret_cast<const char32_t*>(str.toUtf32().c_str())}
398 {
399 }
400
401 explicit operator sf::String() const
402 {
403 return sf::String::fromUtf32(m_string.begin(), m_string.end());
404 }
405#endif
406
407 explicit operator std::string() const;
408 explicit operator std::wstring() const;
409 explicit operator std::u16string() const;
410 explicit operator const std::u32string&() const
411 {
412 return m_string;
413 }
414
415#if TGUI_COMPILED_WITH_CPP_VER >= 17
416 operator std::u32string_view() const noexcept
417 {
418 return m_string;
419 }
420#endif
421
422 std::string toStdString() const;
423 std::wstring toWideString() const;
424 std::u16string toUtf16() const;
425 const std::u32string& toUtf32() const
426 {
427 return m_string;
428 }
429
430 String& assign(std::size_t count, char ch);
431 String& assign(std::size_t count, wchar_t ch);
432 String& assign(std::size_t count, char16_t ch);
433 String& assign(std::size_t count, char32_t ch);
434
435#if TGUI_COMPILED_WITH_CPP_VER >= 17
436 String& assign(std::u32string_view sv);
437#endif
438 String& assign(const char32_t* str);
439 String& assign(const std::u32string& str);
440 String& assign(const String& str);
441
442#if TGUI_COMPILED_WITH_CPP_VER >= 17
443 String& assign(std::u32string_view sv, std::size_t pos, std::size_t count = npos);
444#endif
445 String& assign(const std::string& str, std::size_t pos, std::size_t count = npos);
446 String& assign(const std::wstring& str, std::size_t pos, std::size_t count = npos);
447 String& assign(const std::u16string& str, std::size_t pos, std::size_t count = npos);
448 String& assign(const std::u32string& str, std::size_t pos, std::size_t count = npos);
449 String& assign(const String& str, std::size_t pos, std::size_t count = npos);
450
451 String& assign(std::u32string&& str);
452 String& assign(String&& str);
453
454 String& assign(const char* str, std::size_t count);
455 String& assign(const wchar_t* str, std::size_t count);
456 String& assign(const char16_t* str, std::size_t count);
457 String& assign(const char32_t* str, std::size_t count);
458
459 String& assign(std::initializer_list<char> chars);
460 String& assign(std::initializer_list<wchar_t> chars);
461 String& assign(std::initializer_list<char16_t> chars);
462 String& assign(std::initializer_list<char32_t> chars);
463
464 String& assign(std::string::const_iterator first, std::string::const_iterator last);
465 String& assign(std::wstring::const_iterator first, std::wstring::const_iterator last);
466 String& assign(std::u16string::const_iterator first, std::u16string::const_iterator last);
467 String& assign(std::u32string::const_iterator first, std::u32string::const_iterator last);
468#if TGUI_COMPILED_WITH_CPP_VER >= 17
469 String& assign(std::u32string_view::const_iterator first, std::u32string_view::const_iterator last);
470#endif
471
472 reference at(std::size_t pos);
473 const_reference at(std::size_t pos) const;
474
475 const_reference operator [](std::size_t index) const;
476 reference operator [](std::size_t index);
477
478 reference front();
479 const_reference front() const;
480
481 reference back();
482 const_reference back() const;
483
484 const char32_t* data() const noexcept
485 {
486 return m_string.data();
487 }
488
489#if __cplusplus >= 201703L
490 char32_t* data() noexcept
491 {
492 return m_string.data();
493 }
494#endif
495 const char32_t* c_str() const noexcept
496 {
497 return m_string.c_str();
498 }
499
500 iterator begin() noexcept;
501 const_iterator begin() const noexcept;
502 const_iterator cbegin() const noexcept;
503
504 iterator end() noexcept;
505 const_iterator end() const noexcept;
506 const_iterator cend() const noexcept;
507
508 reverse_iterator rbegin() noexcept;
509 const_reverse_iterator rbegin() const noexcept;
510 const_reverse_iterator crbegin() const noexcept;
511
512 reverse_iterator rend() noexcept;
513 const_reverse_iterator rend() const noexcept;
514 const_reverse_iterator crend() const noexcept;
515
516 bool empty() const noexcept
517 {
518 return m_string.empty();
519 }
520
521 std::size_t size() const noexcept
522 {
523 return m_string.size();
524 }
525
526 std::size_t length() const noexcept
527 {
528 return m_string.length();
529 }
530
531 std::size_t max_size() const noexcept;
532
533 void reserve(std::size_t newCap);
534 std::size_t capacity() const noexcept;
535 void shrink_to_fit();
536
537 void clear() noexcept;
538
539 String& insert(std::size_t index, std::size_t count, char ch);
540 String& insert(std::size_t index, std::size_t count, wchar_t ch);
541 String& insert(std::size_t index, std::size_t count, char16_t ch);
542 String& insert(std::size_t index, std::size_t count, char32_t ch);
543
544#if TGUI_COMPILED_WITH_CPP_VER >= 17
545 String& insert(std::size_t index, std::u32string_view sv);
546#endif
547 String& insert(std::size_t index, const char32_t* str);
548 String& insert(std::size_t index, const std::u32string& str);
549 String& insert(std::size_t index, const String& str);
550
551#if TGUI_COMPILED_WITH_CPP_VER >= 17
552 String& insert(std::size_t index, std::u32string_view sv, std::size_t pos, std::size_t count = npos);
553#endif
554 String& insert(std::size_t index, const std::string& str, std::size_t pos, std::size_t count = npos);
555 String& insert(std::size_t index, const std::wstring& str, std::size_t pos, std::size_t count = npos);
556 String& insert(std::size_t index, const std::u16string& str, std::size_t pos, std::size_t count = npos);
557 String& insert(std::size_t index, const std::u32string& str, std::size_t pos, std::size_t count = npos);
558 String& insert(std::size_t index, const String& str, std::size_t pos, std::size_t count = npos);
559
560 String& insert(std::size_t index, const char* str, std::size_t count);
561 String& insert(std::size_t index, const wchar_t* str, std::size_t count);
562 String& insert(std::size_t index, const char16_t* str, std::size_t count);
563 String& insert(std::size_t index, const char32_t* str, std::size_t count);
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#if TGUI_COMPILED_WITH_CPP_VER >= 17
585 iterator insert(const_iterator pos, std::u32string_view::const_iterator first, std::u32string_view::const_iterator last);
586#endif
587
588 String& erase(std::size_t index = 0, std::size_t count = npos);
589
590 iterator erase(const_iterator position);
591 iterator erase(const_iterator first, const_iterator last);
592
593 void push_back(char ch);
594 void push_back(wchar_t ch);
595 void push_back(char16_t ch);
596 void push_back(char32_t ch);
597
598 void pop_back();
599
600 String& append(std::size_t count, char ch);
601 String& append(std::size_t count, wchar_t ch);
602 String& append(std::size_t count, char16_t ch);
603 String& append(std::size_t count, char32_t ch);
604
605#if TGUI_COMPILED_WITH_CPP_VER >= 17
606 String& append(std::u32string_view sv);
607#endif
608 String& append(const char32_t* str);
609 String& append(const std::u32string& str);
610 String& append(const String& str);
611
612#if TGUI_COMPILED_WITH_CPP_VER >= 17
613 String& append(std::u32string_view sv, std::size_t pos, std::size_t count = npos);
614#endif
615 String& append(const std::string& str, std::size_t pos, std::size_t count = npos);
616 String& append(const std::wstring& str, std::size_t pos, std::size_t count = npos);
617 String& append(const std::u16string& str, std::size_t pos, std::size_t count = npos);
618 String& append(const std::u32string& str, std::size_t pos, std::size_t count = npos);
619 String& append(const String& str, std::size_t pos, std::size_t count = npos);
620
621 String& append(const char* str, std::size_t count);
622 String& append(const wchar_t* str, std::size_t count);
623 String& append(const char16_t* str, std::size_t count);
624 String& append(const char32_t* str, std::size_t count);
625
626 String& append(std::string::const_iterator first, std::string::const_iterator last);
627 String& append(std::wstring::const_iterator first, std::wstring::const_iterator last);
628 String& append(std::u16string::const_iterator first, std::u16string::const_iterator last);
629 String& append(std::u32string::const_iterator first, std::u32string::const_iterator last);
630#if TGUI_COMPILED_WITH_CPP_VER >= 17
631 String& append(std::u32string_view::const_iterator first, std::u32string_view::const_iterator last);
632#endif
633
634 String& append(std::initializer_list<char> chars);
635 String& append(std::initializer_list<wchar_t> chars);
636 String& append(std::initializer_list<char16_t> chars);
637 String& append(std::initializer_list<char32_t> chars);
638
639 String& operator+=(const String& str);
640
641#if TGUI_COMPILED_WITH_CPP_VER >= 17
642 int compare(std::u32string_view sv) const noexcept;
643#endif
644 int compare(const char32_t* s) const;
645 int compare(const std::u32string& str) const noexcept;
646 int compare(const String& str) const noexcept;
647
648#if TGUI_COMPILED_WITH_CPP_VER >= 17
649 int compare(std::size_t pos1, std::size_t count1, std::u32string_view sv) const;
650#endif
651 int compare(std::size_t pos1, std::size_t count1, const char32_t* s) const;
652 int compare(std::size_t pos1, std::size_t count1, const std::u32string& str) const;
653 int compare(std::size_t pos1, std::size_t count1, const String& str) const;
654
655#if TGUI_COMPILED_WITH_CPP_VER >= 17
656 int compare(std::size_t pos1, std::size_t count1, std::u32string_view sv, std::size_t pos2, std::size_t count2 = npos) const;
657#endif
658 int compare(std::size_t pos1, std::size_t count1, const std::string& str, std::size_t pos2, std::size_t count2 = npos) const;
659 int compare(std::size_t pos1, std::size_t count1, const std::wstring& str, std::size_t pos2, std::size_t count2 = npos) const;
660 int compare(std::size_t pos1, std::size_t count1, const std::u16string& str, std::size_t pos2, std::size_t count2 = npos) const;
661 int compare(std::size_t pos1, std::size_t count1, const std::u32string& str, std::size_t pos2, std::size_t count2 = npos) const;
662 int compare(std::size_t pos1, std::size_t count1, const String& str, std::size_t pos2, std::size_t count2 = npos) 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#if TGUI_COMPILED_WITH_CPP_VER >= 17
670 String& replace(std::size_t pos, std::size_t count, std::u32string_view sv);
671#endif
672 String& replace(std::size_t pos, std::size_t count, const char32_t* cstr);
673 String& replace(std::size_t pos, std::size_t count, const std::u32string& str);
674 String& replace(std::size_t pos, std::size_t count, const String& str);
675
676#if TGUI_COMPILED_WITH_CPP_VER >= 17
677 String& replace(const_iterator first, const_iterator last, std::u32string_view sv);
678#endif
679 String& replace(const_iterator first, const_iterator last, const char32_t* cstr);
680 String& replace(const_iterator first, const_iterator last, const std::u32string& str);
681 String& replace(const_iterator first, const_iterator last, const String& str);
682
683#if TGUI_COMPILED_WITH_CPP_VER >= 17
684 String& replace(std::size_t pos, std::size_t count, std::u32string_view sv, std::size_t pos2, std::size_t count2 = npos);
685#endif
686 String& replace(std::size_t pos, std::size_t count, const std::string& str, std::size_t pos2, std::size_t count2 = npos);
687 String& replace(std::size_t pos, std::size_t count, const std::wstring& str, std::size_t pos2, std::size_t count2 = npos);
688 String& replace(std::size_t pos, std::size_t count, const std::u16string& str, std::size_t pos2, std::size_t count2 = npos);
689 String& replace(std::size_t pos, std::size_t count, const std::u32string& str, std::size_t pos2, std::size_t count2 = npos);
690 String& replace(std::size_t pos, std::size_t count, const String& str, std::size_t pos2, std::size_t count2 = npos);
691
692 String& replace(const_iterator first, const_iterator last, std::string::const_iterator first2, std::string::const_iterator last2);
693 String& replace(const_iterator first, const_iterator last, std::wstring::const_iterator first2, std::wstring::const_iterator last2);
694 String& replace(const_iterator first, const_iterator last, std::u16string::const_iterator first2, std::u16string::const_iterator last2);
695 String& replace(const_iterator first, const_iterator last, std::u32string::const_iterator first2, std::u32string::const_iterator last2);
696#if TGUI_COMPILED_WITH_CPP_VER >= 17
697 String& replace(const_iterator first, const_iterator last, std::u32string_view::const_iterator first2, std::u32string_view::const_iterator last2);
698#endif
699
700 String& replace(std::size_t pos, std::size_t count, const char* cstr, std::size_t count2);
701 String& replace(std::size_t pos, std::size_t count, const wchar_t* cstr, std::size_t count2);
702 String& replace(std::size_t pos, std::size_t count, const char16_t* cstr, std::size_t count2);
703 String& replace(std::size_t pos, std::size_t count, const char32_t* cstr, std::size_t count2);
704
705 String& replace(const_iterator first, const_iterator last, const char* cstr, std::size_t count2);
706 String& replace(const_iterator first, const_iterator last, const wchar_t* cstr, std::size_t count2);
707 String& replace(const_iterator first, const_iterator last, const char16_t* cstr, std::size_t count2);
708 String& replace(const_iterator first, const_iterator last, const char32_t* cstr, std::size_t count2);
709
710 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char ch);
711 String& replace(std::size_t pos, std::size_t count, std::size_t count2, wchar_t ch);
712 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char16_t ch);
713 String& replace(std::size_t pos, std::size_t count, std::size_t count2, char32_t ch);
714
715 String& replace(const_iterator first, const_iterator last, std::size_t count2, char ch);
716 String& replace(const_iterator first, const_iterator last, std::size_t count2, wchar_t ch);
717 String& replace(const_iterator first, const_iterator last, std::size_t count2, char16_t ch);
718 String& replace(const_iterator first, const_iterator last, std::size_t count2, char32_t ch);
719
720 String& replace(const_iterator first, const_iterator last, std::initializer_list<char> chars);
721 String& replace(const_iterator first, const_iterator last, std::initializer_list<wchar_t> chars);
722 String& replace(const_iterator first, const_iterator last, std::initializer_list<char16_t> chars);
723 String& replace(const_iterator first, const_iterator last, std::initializer_list<char32_t> chars);
724
725 String substr(std::size_t pos = 0, std::size_t count = npos) const;
726
727 std::size_t copy(char32_t* dest, std::size_t count, std::size_t pos = 0) const;
728
729 void resize(std::size_t count);
730 void resize(std::size_t count, char ch);
731 void resize(std::size_t count, wchar_t ch);
732 void resize(std::size_t count, char16_t ch);
733 void resize(std::size_t count, char32_t ch);
734
735 void swap(String& other);
736
737 bool contains(char c) const noexcept;
738 bool contains(wchar_t c) const noexcept;
739 bool contains(char16_t c) const noexcept;
740 bool contains(char32_t c) const noexcept;
741
742#if TGUI_COMPILED_WITH_CPP_VER >= 17
743 bool contains(std::u32string_view sv) const noexcept;
744#endif
745 bool contains(const char32_t* s) const;
746 bool contains(const std::u32string& s) const;
747 bool contains(const String& s) const;
748
749#if TGUI_COMPILED_WITH_CPP_VER >= 17
750 std::size_t find(std::u32string_view sv, std::size_t pos = 0) const noexcept;
751#endif
752 std::size_t find(const char32_t* s, std::size_t pos = 0) const;
753 std::size_t find(const std::u32string& str, std::size_t pos = 0) const noexcept;
754 std::size_t find(const String& str, std::size_t pos = 0) const noexcept;
755
756 std::size_t find(const char* s, std::size_t pos, std::size_t count) const;
757 std::size_t find(const wchar_t* s, std::size_t pos, std::size_t count) const;
758 std::size_t find(const char16_t* s, std::size_t pos, std::size_t count) const;
759 std::size_t find(const char32_t* s, std::size_t pos, std::size_t count) const;
760
761 std::size_t find(char ch, std::size_t pos = 0) const noexcept;
762 std::size_t find(wchar_t ch, std::size_t pos = 0) const noexcept;
763 std::size_t find(char16_t ch, std::size_t pos = 0) const noexcept;
764 std::size_t find(char32_t ch, std::size_t pos = 0) const noexcept;
765
766#if TGUI_COMPILED_WITH_CPP_VER >= 17
767 std::size_t find_first_of(std::u32string_view sv, std::size_t pos = 0) const noexcept;
768#endif
769 std::size_t find_first_of(const char32_t* s, std::size_t pos = 0) const;
770 std::size_t find_first_of(const std::u32string& str, std::size_t pos = 0) const noexcept;
771 std::size_t find_first_of(const String& str, std::size_t pos = 0) const noexcept;
772
773 std::size_t find_first_of(const char* s, std::size_t pos, std::size_t count) const;
774 std::size_t find_first_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
775 std::size_t find_first_of(const char16_t* s, std::size_t pos, std::size_t count) const;
776 std::size_t find_first_of(const char32_t* s, std::size_t pos, std::size_t count) const;
777
778 std::size_t find_first_of(char ch, std::size_t pos = 0) const noexcept;
779 std::size_t find_first_of(wchar_t ch, std::size_t pos = 0) const noexcept;
780 std::size_t find_first_of(char16_t ch, std::size_t pos = 0) const noexcept;
781 std::size_t find_first_of(char32_t ch, std::size_t pos = 0) const noexcept;
782
783#if TGUI_COMPILED_WITH_CPP_VER >= 17
784 std::size_t find_first_not_of(std::u32string_view sv, std::size_t pos = 0) const noexcept;
785#endif
786 std::size_t find_first_not_of(const char32_t* s, std::size_t pos = 0) const;
787 std::size_t find_first_not_of(const std::u32string& str, std::size_t pos = 0) const noexcept;
788 std::size_t find_first_not_of(const String& str, std::size_t pos = 0) const noexcept;
789
790 std::size_t find_first_not_of(const char* s, std::size_t pos, std::size_t count) const;
791 std::size_t find_first_not_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
792 std::size_t find_first_not_of(const char16_t* s, std::size_t pos, std::size_t count) const;
793 std::size_t find_first_not_of(const char32_t* s, std::size_t pos, std::size_t count) 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#if TGUI_COMPILED_WITH_CPP_VER >= 17
801 std::size_t rfind(std::u32string_view sv, std::size_t pos = npos) const noexcept;
802#endif
803 std::size_t rfind(const char32_t* s, std::size_t pos = npos) const;
804 std::size_t rfind(const std::u32string& str, std::size_t pos = npos) const noexcept;
805 std::size_t rfind(const String& str, std::size_t pos = npos) const noexcept;
806
807 std::size_t rfind(const char* s, std::size_t pos, std::size_t count) const;
808 std::size_t rfind(const wchar_t* s, std::size_t pos, std::size_t count) const;
809 std::size_t rfind(const char16_t* s, std::size_t pos, std::size_t count) const;
810 std::size_t rfind(const char32_t* s, std::size_t pos, std::size_t count) const;
811
812 std::size_t rfind(char ch, std::size_t pos = npos) const noexcept;
813 std::size_t rfind(wchar_t ch, std::size_t pos = npos) const noexcept;
814 std::size_t rfind(char16_t ch, std::size_t pos = npos) const noexcept;
815 std::size_t rfind(char32_t ch, std::size_t pos = npos) const noexcept;
816
817#if TGUI_COMPILED_WITH_CPP_VER >= 17
818 std::size_t find_last_of(std::u32string_view sv, std::size_t pos = npos) const noexcept;
819#endif
820 std::size_t find_last_of(const char32_t* s, std::size_t pos = npos) const;
821 std::size_t find_last_of(const std::u32string& str, std::size_t pos = npos) const noexcept;
822 std::size_t find_last_of(const String& str, std::size_t pos = npos) const noexcept;
823
824 std::size_t find_last_of(const char* s, std::size_t pos, std::size_t count) const;
825 std::size_t find_last_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
826 std::size_t find_last_of(const char16_t* s, std::size_t pos, std::size_t count) const;
827 std::size_t find_last_of(const char32_t* s, std::size_t pos, std::size_t count) const;
828
829 std::size_t find_last_of(char ch, std::size_t pos = npos) const noexcept;
830 std::size_t find_last_of(wchar_t ch, std::size_t pos = npos) const noexcept;
831 std::size_t find_last_of(char16_t ch, std::size_t pos = npos) const noexcept;
832 std::size_t find_last_of(char32_t ch, std::size_t pos = npos) const noexcept;
833
834#if TGUI_COMPILED_WITH_CPP_VER >= 17
835 std::size_t find_last_not_of(std::u32string_view sv, std::size_t pos = npos) const noexcept;
836#endif
837 std::size_t find_last_not_of(const char32_t* s, std::size_t pos = npos) const;
838 std::size_t find_last_not_of(const std::u32string& str, std::size_t pos = npos) const noexcept;
839 std::size_t find_last_not_of(const String& str, std::size_t pos = npos) const noexcept;
840
841 std::size_t find_last_not_of(const char* s, std::size_t pos, std::size_t count) const;
842 std::size_t find_last_not_of(const wchar_t* s, std::size_t pos, std::size_t count) const;
843 std::size_t find_last_not_of(const char16_t* s, std::size_t pos, std::size_t count) const;
844 std::size_t find_last_not_of(const char32_t* s, std::size_t pos, std::size_t count) const;
845
846 std::size_t find_last_not_of(char ch, std::size_t pos = npos) const noexcept;
847 std::size_t find_last_not_of(wchar_t ch, std::size_t pos = npos) const noexcept;
848 std::size_t find_last_not_of(char16_t ch, std::size_t pos = npos) const noexcept;
849 std::size_t find_last_not_of(char32_t ch, std::size_t pos = npos) const noexcept;
850
851 inline friend bool operator==(const String& left, const String& right);
852 inline friend bool operator!=(const String& left, const String& right);
853 inline friend bool operator<(const String& left, const String& right);
854 inline friend bool operator<=(const String& left, const String& right);
855 inline friend bool operator>(const String& left, const String& right);
856 inline friend bool operator>=(const String& left, const String& right);
857 inline friend String operator+(const String& left, const String& right);
858 inline friend String operator+(const String& left, String&& right);
859 inline friend String operator+(String&& left, const String& right);
860 inline friend String operator+(String&& left, String&& right);
861
862#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
863 inline String(const std::u8string& str);
864 inline String(char8_t utfChar);
865 inline String(const char8_t* str);
866 inline String(std::size_t count, char8_t ch);
867 inline String(const std::u8string& str, std::size_t pos);
868 inline String(const std::u8string& str, std::size_t pos, std::size_t count);
869 inline String(const char8_t* str, std::size_t count);
870 inline explicit String(std::initializer_list<char8_t> chars);
871 inline explicit String(std::u8string::const_iterator first, std::u8string::const_iterator last);
872
873 inline explicit operator std::u8string() const;
874
875 inline std::u8string toUtf8() const;
876
877 inline String& assign(std::size_t count, char8_t ch);
878 inline String& assign(const std::u8string& str, std::size_t pos, std::size_t count = npos);
879 inline String& assign(const char8_t* str, std::size_t count);
880 inline String& assign(std::initializer_list<char8_t> chars);
881 inline String& assign(std::u8string::const_iterator first, std::u8string::const_iterator last);
882
883 inline String& insert(std::size_t index, std::size_t count, char8_t ch);
884 inline String& insert(std::size_t index, const std::u8string& str, std::size_t pos, std::size_t count = npos);
885 inline String& insert(std::size_t index, const char8_t* str, std::size_t count);
886 inline iterator insert(const_iterator pos, char8_t ch);
887 inline iterator insert(const_iterator pos, std::size_t count, char8_t ch);
888 inline iterator insert(const_iterator pos, std::initializer_list<char8_t> chars);
889 inline iterator insert(const_iterator pos, std::u8string::const_iterator first, std::u8string::const_iterator last);
890
891 inline String& append(std::size_t count, char8_t ch);
892 inline String& append(const std::u8string& str, std::size_t pos, std::size_t count = npos);
893 inline String& append(const char8_t* str, std::size_t count);
894 inline String& append(std::initializer_list<char8_t> chars);
895 inline String& append(std::u8string::const_iterator first, std::u8string::const_iterator last);
896
897 inline int compare(std::size_t pos1, std::size_t count1, const std::u8string& str, std::size_t pos2, std::size_t count2 = npos) const;
898 inline int compare(std::size_t pos1, std::size_t count1, const char8_t* s, std::size_t count2) const;
899
900 inline String& replace(std::size_t pos, std::size_t count, const std::u8string& str, std::size_t pos2, std::size_t count2 = npos);
901 inline String& replace(const_iterator first, const_iterator last, std::u8string::const_iterator first2, std::u8string::const_iterator last2);
902 inline String& replace(std::size_t pos, std::size_t count, const char8_t* cstr, std::size_t count2);
903 inline String& replace(const_iterator first, const_iterator last, const char8_t* cstr, std::size_t count2);
904 inline String& replace(std::size_t pos, std::size_t count, std::size_t count2, char8_t ch);
905 inline String& replace(const_iterator first, const_iterator last, std::size_t count2, char8_t ch);
906 inline String& replace(const_iterator first, const_iterator last, std::initializer_list<char8_t> chars);
907
908 inline void resize(std::size_t count, char8_t ch);
909
910 inline bool contains(char8_t c) const noexcept;
911
912 inline std::size_t find(const char8_t* s, std::size_t pos, std::size_t count) const;
913 inline std::size_t find(char8_t ch, std::size_t pos = 0) const noexcept;
914
915 inline std::size_t find_first_of(const char8_t* s, std::size_t pos, std::size_t count) const;
916 inline std::size_t find_first_of(char8_t ch, std::size_t pos = 0) const noexcept;
917
918 inline std::size_t find_first_not_of(const char8_t* s, std::size_t pos, std::size_t count) const;
919 inline std::size_t find_first_not_of(char8_t ch, std::size_t pos = 0) const noexcept;
920
921 inline std::size_t rfind(const char8_t* s, std::size_t pos, std::size_t count) const;
922 inline std::size_t rfind(char8_t ch, std::size_t pos = npos) const noexcept;
923
924 inline std::size_t find_last_of(const char8_t* s, std::size_t pos, std::size_t count) const;
925 inline std::size_t find_last_of(char8_t ch, std::size_t pos = npos) const noexcept;
926
927 inline std::size_t find_last_not_of(const char8_t* s, std::size_t pos, std::size_t count) const;
928 inline std::size_t find_last_not_of(char8_t ch, std::size_t pos = npos) const noexcept;
929#endif
930
931#if TGUI_COMPILED_WITH_CPP_VER >= 17 && defined(__cpp_lib_starts_ends_with) && defined(__cpp_lib_char8_t) && (__cpp_lib_starts_ends_with >= 201711L) && (__cpp_lib_char8_t >= 201811L)
932 inline bool starts_with(std::u32string_view sv) const noexcept;
933 inline bool starts_with(const char32_t* s) const;
934 inline bool starts_with(const std::u32string& s) const;
935 inline bool starts_with(const String& s) const;
936
937 inline bool starts_with(char ch) const noexcept;
938 inline bool starts_with(wchar_t ch) const noexcept;
939 inline bool starts_with(char8_t ch) const noexcept;
940 inline bool starts_with(char16_t ch) const noexcept;
941 inline bool starts_with(char32_t ch) const noexcept;
942
943 inline bool ends_with(std::u32string_view sv) const noexcept;
944 inline bool ends_with(const char32_t* s) const;
945 inline bool ends_with(const std::u32string& s) const;
946 inline bool ends_with(const String& s) const;
947
948 inline bool ends_with(char ch) const noexcept;
949 inline bool ends_with(wchar_t ch) const noexcept;
950 inline bool ends_with(char8_t ch) const noexcept;
951 inline bool ends_with(char16_t ch) const noexcept;
952 inline bool ends_with(char32_t ch) const noexcept;
953#else
954 inline bool starts_with(const String& s) const;
955 inline bool ends_with(const String& s) const;
956#endif
957 };
958
960
961 inline bool operator==(const String& left, const String& right)
962 {
963 return left.m_string == right.m_string;
964 }
965
966 inline bool operator!=(const String& left, const String& right)
967 {
968 return left.m_string != right.m_string;
969 }
970
971 inline bool operator<(const String& left, const String& right)
972 {
973 return left.m_string < right.m_string;
974 }
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 String operator+(const String& left, const String& right)
992 {
993 return {left.m_string + right.m_string};
994 }
995 inline String operator+(String&& left, String&& right)
996 {
997 return {std::move(left.m_string) + std::move(right.m_string)};
998 }
999 inline String operator+(String&& left, const String& right)
1000 {
1001 return {std::move(left.m_string) + right.m_string};
1002 }
1003 inline String operator+(const String& left, String&& right)
1004 {
1005 return {left.m_string + std::move(right.m_string)};
1006 }
1007
1008 // We don't provide operator<< implmentations for basic_ostream<charX_t> streams because
1009 // even clang 15 can't compile them when using libc++.
1010 // We could define them for VS, GCC and for clang with libstdc++, but there is no real use for them.
1011 TGUI_API std::ostream& operator<<(std::ostream& os, const String& str);
1012 TGUI_API std::wostream& operator<<(std::wostream& os, const String& str);
1013
1014
1015 // UTF-8 function are defined in the header so that they can be enabled/disabled based on
1016 // the compiler settings without having to recompile TGUI with a different c++ standard.
1017#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201811L)
1018 inline String::String(const std::u8string& str) :
1019 m_string(utf::convertUtf8toUtf32(str.begin(), str.end()))
1020 {
1021 }
1022
1023 inline String::String(char8_t utfChar)
1024 : m_string(1, static_cast<char32_t>(utfChar))
1025 {
1026 }
1027
1028 inline String::String(const char8_t* str)
1029 : String{utf::convertUtf8toUtf32(str, str + std::char_traits<char8_t>::length(str))}
1030 {
1031 }
1032
1033 inline String::String(std::size_t count, char8_t ch)
1034 : m_string(count, static_cast<char32_t>(ch))
1035 {
1036 }
1037
1038 inline String::String(const std::u8string& str, std::size_t pos)
1039 : String{std::u8string(str, pos)}
1040 {
1041 }
1042
1043 inline String::String(const std::u8string& str, std::size_t pos, std::size_t count)
1044 : String{std::u8string(str, pos, count)}
1045 {
1046 }
1047
1048 inline String::String(const char8_t* str, std::size_t count)
1049 : String{std::u8string{str, count}}
1050 {
1051 }
1052
1053 inline String::String(std::initializer_list<char8_t> chars)
1054 : String(std::u8string(chars.begin(), chars.end()))
1055 {
1056 }
1057
1058 inline String::String(std::u8string::const_iterator first, std::u8string::const_iterator last)
1059 : String{std::u8string(first, last)}
1060 {
1061 }
1062
1063 inline String::operator std::u8string() const
1064 {
1065 return utf::convertUtf32toUtf8(m_string);
1066 }
1067
1068 inline std::u8string String::toUtf8() const
1069 {
1070 return utf::convertUtf32toUtf8(m_string);
1071 }
1072
1073 inline String& String::assign(const std::u8string& str, std::size_t pos, std::size_t count)
1074 {
1075 m_string.assign(String{str, pos, count}.m_string);
1076 return *this;
1077 }
1078
1079 inline String& String::assign(const char8_t* str, std::size_t count)
1080 {
1081 m_string.assign(String{str, count}.m_string);
1082 return *this;
1083 }
1084
1085 inline String& String::assign(std::size_t count, char8_t ch)
1086 {
1087 m_string.assign(count, static_cast<char32_t>(ch));
1088 return *this;
1089 }
1090
1091 inline String& String::assign(std::initializer_list<char8_t> chars)
1092 {
1093 m_string.assign(String{chars}.m_string);
1094 return *this;
1095 }
1096
1097 inline String& String::assign(std::u8string::const_iterator first, std::u8string::const_iterator last)
1098 {
1099 m_string.assign(String{first, last}.m_string);
1100 return *this;
1101 }
1102
1103 inline String& String::insert(std::size_t index, std::size_t count, char8_t ch)
1104 {
1105 m_string.insert(index, count, static_cast<char32_t>(ch));
1106 return *this;
1107 }
1108
1109 inline String& String::insert(std::size_t index, const std::u8string& str, std::size_t pos, std::size_t count)
1110 {
1111 m_string.insert(index, String{str, pos, count}.m_string);
1112 return *this;
1113 }
1114
1115 inline String& String::insert(std::size_t index, const char8_t* str, std::size_t count)
1116 {
1117 m_string.insert(index, String{str, count}.m_string);
1118 return *this;
1119 }
1120
1121 inline String::iterator String::insert(String::const_iterator pos, char8_t ch)
1122 {
1123 return m_string.insert(pos, static_cast<char32_t>(ch));
1124 }
1125
1126 inline String::iterator String::insert(String::const_iterator pos, std::size_t count, char8_t ch)
1127 {
1128 return m_string.insert(pos, count, static_cast<char32_t>(ch));
1129 }
1130
1131 inline String::iterator String::insert(String::const_iterator pos, std::initializer_list<char8_t> chars)
1132 {
1133 const std::u32string tmpStr(utf::convertUtf8toUtf32(chars.begin(), chars.end()));
1134 return m_string.insert(pos, tmpStr.begin(), tmpStr.end());
1135 }
1136
1137 inline String::iterator String::insert(String::const_iterator pos, std::u8string::const_iterator first, std::u8string::const_iterator last)
1138 {
1139 const std::u32string tmpStr(utf::convertUtf8toUtf32(first, last));
1140 return m_string.insert(pos, tmpStr.begin(), tmpStr.end());
1141 }
1142
1143 inline String& String::append(std::size_t count, char8_t ch)
1144 {
1145 m_string.append(count, static_cast<char32_t>(ch));
1146 return *this;
1147 }
1148
1149 inline String& String::append(const std::u8string& str, std::size_t pos, std::size_t count)
1150 {
1151 m_string.append(String{str, pos, count}.m_string);
1152 return *this;
1153 }
1154
1155 inline String& String::append(const char8_t* str, std::size_t count)
1156 {
1157 m_string.append(String{str, count}.m_string);
1158 return *this;
1159 }
1160
1161 inline String& String::append(std::initializer_list<char8_t> chars)
1162 {
1163 m_string.append(String{chars}.m_string);
1164 return *this;
1165 }
1166
1167 inline String& String::append(std::u8string::const_iterator first, std::u8string::const_iterator last)
1168 {
1169 m_string.append(String{first, last}.m_string);
1170 return *this;
1171 }
1172
1173 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
1174 {
1175 return m_string.compare(pos1, count1, String{str, pos2, count2}.m_string);
1176 }
1177
1178 inline int String::compare(std::size_t pos1, std::size_t count1, const char8_t* s, std::size_t count2) const
1179 {
1180 return m_string.compare(pos1, count1, String{s, count2}.m_string);
1181 }
1182
1183 inline String& String::replace(std::size_t pos, std::size_t count, const std::u8string& str, std::size_t pos2, std::size_t count2)
1184 {
1185 m_string.replace(pos, count, String{str, pos2, count2}.m_string);
1186 return *this;
1187 }
1188
1189 inline String& String::replace(const_iterator first, const_iterator last, std::u8string::const_iterator first2, std::u8string::const_iterator last2)
1190 {
1191 m_string.replace(first, last, String{first2, last2}.m_string);
1192 return *this;
1193 }
1194
1195 inline String& String::replace(std::size_t pos, std::size_t count, const char8_t* cstr, std::size_t count2)
1196 {
1197 m_string.replace(pos, count, String{cstr, count2}.m_string);
1198 return *this;
1199 }
1200
1201 inline String& String::replace(const_iterator first, const_iterator last, const char8_t* cstr, std::size_t count2)
1202 {
1203 m_string.replace(first, last, String{cstr, count2}.m_string);
1204 return *this;
1205 }
1206
1207 inline String& String::replace(std::size_t pos, std::size_t count, std::size_t count2, char8_t ch)
1208 {
1209 m_string.replace(pos, count, String(count2, ch).m_string);
1210 return *this;
1211 }
1212
1213 inline String& String::replace(const_iterator first, const_iterator last, std::size_t count2, char8_t ch)
1214 {
1215 m_string.replace(first, last, String(count2, ch).m_string);
1216 return *this;
1217 }
1218
1219 inline String& String::replace(const_iterator first, const_iterator last, std::initializer_list<char8_t> chars)
1220 {
1221 m_string.replace(first, last, String{chars}.m_string);
1222 return *this;
1223 }
1224
1225 inline void String::resize(std::size_t count, char8_t ch)
1226 {
1227 m_string.resize(count, static_cast<char32_t>(ch));
1228 }
1229
1230 inline bool String::contains(char8_t c) const noexcept
1231 {
1232 return contains(static_cast<char32_t>(c));
1233 }
1234
1235 inline std::size_t String::find(const char8_t* s, std::size_t pos, std::size_t count) const
1236 {
1237 return m_string.find(String{s, count}.m_string, pos);
1238 }
1239
1240 inline std::size_t String::find(char8_t ch, std::size_t pos) const noexcept
1241 {
1242 return m_string.find(static_cast<char32_t>(ch), pos);
1243 }
1244
1245 inline std::size_t String::find_first_of(const char8_t* s, std::size_t pos, std::size_t count) const
1246 {
1247 return m_string.find_first_of(String{s, count}.m_string, pos);
1248 }
1249
1250 inline std::size_t String::find_first_of(char8_t ch, std::size_t pos) const noexcept
1251 {
1252 return m_string.find_first_of(static_cast<char32_t>(ch), pos);
1253 }
1254
1255 inline std::size_t String::find_first_not_of(const char8_t* s, std::size_t pos, std::size_t count) const
1256 {
1257 return m_string.find_first_not_of(String{s, count}.m_string, pos);
1258 }
1259
1260 inline std::size_t String::find_first_not_of(char8_t ch, std::size_t pos) const noexcept
1261 {
1262 return m_string.find_first_not_of(static_cast<char32_t>(ch), pos);
1263 }
1264
1265 inline std::size_t String::rfind(const char8_t* s, std::size_t pos, std::size_t count) const
1266 {
1267 return m_string.rfind(String{s, count}.m_string, pos);
1268 }
1269
1270 inline std::size_t String::rfind(char8_t ch, std::size_t pos) const noexcept
1271 {
1272 return m_string.rfind(static_cast<char32_t>(ch), pos);
1273 }
1274
1275 inline std::size_t String::find_last_of(const char8_t* s, std::size_t pos, std::size_t count) const
1276 {
1277 return m_string.find_last_of(String{s, count}.m_string, pos);
1278 }
1279
1280 inline std::size_t String::find_last_of(char8_t ch, std::size_t pos) const noexcept
1281 {
1282 return m_string.find_last_of(static_cast<char32_t>(ch), pos);
1283 }
1284
1285 inline std::size_t String::find_last_not_of(const char8_t* s, std::size_t pos, std::size_t count) const
1286 {
1287 return m_string.find_last_not_of(String{s, count}.m_string, pos);
1288 }
1289
1290 inline std::size_t String::find_last_not_of(char8_t ch, std::size_t pos) const noexcept
1291 {
1292 return m_string.find_last_not_of(static_cast<char8_t>(ch), pos);
1293 }
1294#endif
1295
1296#if TGUI_COMPILED_WITH_CPP_VER >= 17 && defined(__cpp_lib_starts_ends_with) && defined(__cpp_lib_char8_t) && (__cpp_lib_starts_ends_with >= 201711L) && (__cpp_lib_char8_t >= 201811L)
1297 inline bool String::starts_with(std::u32string_view sv) const noexcept
1298 {
1299 return m_string.starts_with(sv);
1300 }
1301
1302 inline bool String::starts_with(const char32_t* s) const
1303 {
1304 return m_string.starts_with(s);
1305 }
1306
1307 inline bool String::starts_with(const std::u32string& s) const
1308 {
1309 return m_string.starts_with(s);
1310 }
1311
1312 inline bool String::starts_with(const String& s) const
1313 {
1314 return m_string.starts_with(s.m_string);
1315 }
1316
1317 inline bool String::starts_with(char ch) const noexcept
1318 {
1319 return m_string.starts_with(static_cast<char32_t>(ch));
1320 }
1321
1322 inline bool String::starts_with(wchar_t ch) const noexcept
1323 {
1324 return m_string.starts_with(static_cast<char32_t>(ch));
1325 }
1326
1327 inline bool String::starts_with(char8_t ch) const noexcept
1328 {
1329 return m_string.starts_with(static_cast<char32_t>(ch));
1330 }
1331
1332 inline bool String::starts_with(char16_t ch) const noexcept
1333 {
1334 return m_string.starts_with(static_cast<char32_t>(ch));
1335 }
1336
1337 inline bool String::starts_with(char32_t ch) const noexcept
1338 {
1339 return m_string.starts_with(ch);
1340 }
1341
1342 inline bool String::ends_with(std::u32string_view sv) const noexcept
1343 {
1344 return m_string.ends_with(sv);
1345 }
1346
1347 inline bool String::ends_with(const char32_t* s) const
1348 {
1349 return m_string.ends_with(s);
1350 }
1351
1352 inline bool String::ends_with(const std::u32string& s) const
1353 {
1354 return m_string.ends_with(s);
1355 }
1356
1357 inline bool String::ends_with(const String& s) const
1358 {
1359 return m_string.ends_with(s.m_string);
1360 }
1361
1362 inline bool String::ends_with(char ch) const noexcept
1363 {
1364 return m_string.ends_with(static_cast<char32_t>(ch));
1365 }
1366
1367 inline bool String::ends_with(wchar_t ch) const noexcept
1368 {
1369 return m_string.ends_with(static_cast<char32_t>(ch));
1370 }
1371
1372 inline bool String::ends_with(char8_t ch) const noexcept
1373 {
1374 return m_string.ends_with(static_cast<char32_t>(ch));
1375 }
1376
1377 inline bool String::ends_with(char16_t ch) const noexcept
1378 {
1379 return m_string.ends_with(static_cast<char32_t>(ch));
1380 }
1381
1382 inline bool String::ends_with(char32_t ch) const noexcept
1383 {
1384 return m_string.ends_with(ch);
1385 }
1386#else
1387 inline bool String::starts_with(const String& s) const
1388 {
1389 if (s.length() <= length())
1390 return compare(0, s.length(), s) == 0;
1391 else
1392 return false;
1393 }
1394
1395 inline bool String::ends_with(const String& s) const
1396 {
1397 if (s.length() <= length())
1398 return compare(length() - s.length(), s.length(), s) == 0;
1399 else
1400 return false;
1401 }
1402#endif
1403
1405
1406#if TGUI_COMPILED_WITH_CPP_VER >= 17
1407 using StringView = std::u32string_view;
1408 using CharStringView = std::string_view;
1409
1410 // Allow using operator ""sv
1411 // Note that this only affects code placed inside the tgui namespace.
1412 using namespace std::literals::string_view_literals;
1413#else
1414 using StringView = const String&;
1415 using CharStringView = const std::string&;
1416#endif
1417}
1418
1420
1421#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.
bool equalIgnoreCase(const String &other) const
Compares this string to another and checks if they are equal if ASCII letters would have been lowerca...
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 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.
static String fromNumberRounded(T value, unsigned int decimals)
Construct the string from a floating point number, keeping only a certain amount of decimals behind t...
Definition: String.hpp:302
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)