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