PLCnext API Documentation 25.0.2.69
BasicString.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
7#include <string>
8#include <vector>
9#include <algorithm>
10#include <memory>
11#include <iostream>
12#include <initializer_list>
13#include "boost/algorithm/string/replace.hpp"
14#include "Arp/System/Core/BasicFormatter.hxx"
15#include "Arp/System/Core/Impl/BasicStringFormatExceptionHandler.hpp"
16
17#ifndef ARP_USE_ARP_SYSTEM_CORE
18
19// nothing to include here, included by Arp.hpp
20
21#else
22
23#ifndef ARP_INSIDE_ARP_H
24 #error Never include 'BasicString.hxx' directly, just include 'Arp.h'
25#endif
26
27namespace Arp
28{
29
31
34
37template<class C, class Alloc = std::allocator<C>>
38class BasicString
39{
40public: // usings
41 using Allocator = Alloc;
42 using AllocatorTraits = std::allocator_traits<Alloc>;
43 using CharType = C;
44 using SelfType = BasicString<CharType, Allocator>;
45 using BaseString = std::basic_string<CharType, std::char_traits<CharType>, Allocator>;
46 using StdString = std::basic_string<CharType, std::char_traits<CharType>, Allocator>;
47 using Tokens = std::vector<SelfType>;
48 using Bytes = std::vector<byte>;
49
50public: // policy typedefs
51 using allocator_type = Allocator;
52 using value_type = CharType;
53 using size_type = typename BaseString::size_type;
54 using difference_type = typename BaseString::difference_type;
55 using reference = typename BaseString::reference;
56 using const_reference = typename BaseString::const_reference;
57 using pointer = typename AllocatorTraits::pointer;
58 using const_pointer = typename AllocatorTraits::const_pointer;
59 using iterator = typename BaseString::iterator;
60 using const_iterator = typename BaseString::const_iterator;
61 using reverse_iterator = typename BaseString::reverse_iterator;
62 using const_reverse_iterator = typename BaseString::const_reverse_iterator;
63
64private: // usings
65 using BasicFormatterType = BasicFormatter<CharType, Allocator>;
66
67public: // construction/destruction
69 BasicString() = default;
70
73 BasicString(const SelfType& arg) = default;
74
78 BasicString(const SelfType& arg, const Allocator& alloc)
79 : baseString(arg.baseString, alloc)
80 {
81 }
82
85 explicit BasicString(const Allocator& alloc)
86 : baseString(alloc)
87 {
88 }
89
94 BasicString(const SelfType& arg, size_type offset, size_type count = NPos)
95 : baseString(arg.baseString, offset, count)
96 {
97 }
98
104 BasicString(const SelfType& arg, size_type offset, size_type count, const Allocator& alloc)
105 : baseString(arg.baseString, offset, count, alloc)
106 {
107 }
108
112 BasicString(const CharType* pChars, size_type count)
113 : baseString(pChars, count)
114 {
115 }
116
121 BasicString(const CharType* pChars, size_type count, const Allocator& alloc)
122 : baseString(pChars, count, alloc)
123 {
124 }
125
128 BasicString(const CharType* pChars)
129 : baseString(pChars)
130 {
131 }
132
135 BasicString(const char8u* pChars)
136 : BasicString(reinterpret_cast<const char*>(pChars))
137 {
138 }
139
143 BasicString(const CharType* pChars, const Allocator& alloc)
144 : baseString(pChars, alloc)
145 {
146 }
147
151 BasicString(size_type count, CharType c)
152 : baseString(count, c)
153 {
154 }
155
160 BasicString(size_type count, CharType c, const Allocator& alloc)
161 : baseString(count, c, alloc)
162 {
163 }
164
167 BasicString(SelfType&& arg) noexcept = default;
168
172 BasicString(SelfType&& arg, const Allocator& alloc)
173 : baseString(std::move(arg.baseString), alloc)
174 {
175 }
176
180 BasicString(std::initializer_list<CharType> arg, const Allocator& alloc = Allocator())
181 : baseString(arg, alloc)
182 {
183 }
184
189 BasicString(iterator first, iterator last, const Allocator& alloc = Allocator())
190 : baseString(first, last, alloc)
191 {
192 }
193
198 BasicString(const_iterator first, const_iterator last, const Allocator& alloc = Allocator())
199 : baseString(first, last, alloc)
200 {
201 }
202
206 explicit BasicString(const Bytes& bytes, const Allocator& alloc = Allocator())
207 : baseString(reinterpret_cast<const char*>(bytes.data()), reinterpret_cast<const char*>(bytes.data() + bytes.size()), alloc)
208 {
209 }
210
213 BasicString(const BaseString& arg)
214 : baseString(arg)
215 {
216 }
217
220 BasicString(BaseString&& arg)
221 : baseString(std::move(arg))
222 {
223 }
224
226 ~BasicString() = default;
227
228public: // static fields
233 static const size_type NPos = size_type(-1);
237 static const SelfType Empty;
241 static const SelfType NewLine;
242
243public: // assignment operator
247 SelfType& operator=(SelfType&& right) noexcept = default;
248
252 SelfType& operator=(std::initializer_list<CharType> right)
253 {
254 this->baseString = right;
255 return (*this);
256 }
257
261 SelfType& operator=(const SelfType& right) = default;
262
266 SelfType& operator=(const CharType* right)
267 {
268 this->baseString = right;
269 return (*this);
270 }
271
275 SelfType& operator=(CharType c)
276 {
277 this->baseString = c;
278 return (*this);
279 }
280
281public: // append operator
285 SelfType& operator+=(std::initializer_list<CharType> right)
286 {
287 this->baseString += right;
288 return (*this);
289 }
290
294 SelfType& operator+=(const SelfType& right)
295 {
296 this->baseString += right.baseString;
297 return (*this);
298 }
299
303 SelfType& operator+=(const CharType* right)
304 {
305 this->baseString += right;
306 return (*this);
307 }
308
312 SelfType& operator+=(CharType c)
313 {
314 this->baseString += c;
315 return (*this);
316 }
317
318public: // assign operations
319
323 SelfType& Assign(SelfType&& arg)
324 {
325 this->baseString = std::move(arg.baseString);
326 return *this;
327 }
328
332 SelfType& Assign(std::initializer_list<CharType> arg)
333 {
334 this->baseString.assign(arg);
335 return *this;
336 }
337
341 SelfType& Assign(const SelfType& arg)
342 {
343 this->baseString.assign(arg.baseString);
344 return *this;
345 }
346
351 SelfType& Assign(const SelfType& arg, size_type offset, size_type count = NPos)
352 {
353 this->baseString.assign(arg.baseString, offset, count);
354 return *this;
355 }
356
360 SelfType& Assign(const BaseString& arg)
361 {
362 this->baseString.assign(arg);
363 return *this;
364 }
365
369 SelfType& Assign(BaseString&& arg)
370 {
371 this->baseString.assign(std::move(arg));
372 return *this;
373 }
374
378 SelfType& Assign(const CharType* pChars, size_type count)
379 {
380 this->baseString.assign(pChars, count);
381 return *this;
382 }
383
386 SelfType& Assign(const CharType* pChars)
387 {
388 this->baseString.assign(pChars);
389 return *this;
390 }
391
395 SelfType& Assign(size_type count, CharType c)
396 {
397 this->baseString.assign(count, c);
398 return *this;
399 }
400
404 SelfType& Assign(iterator first, iterator last)
405 {
406 this->baseString.assign(first, last);
407 return *this;
408 }
409
413 SelfType& Assign(const_iterator first, const_iterator last)
414 {
415 this->baseString.assign(first, last);
416 return *this;
417 }
418
422 SelfType& Assign(const_pointer first, const_pointer last)
423 {
424 this->baseString.assign(first, last);
425 return *this;
426 }
427
428public: // append operations
429
433 SelfType& Append(std::initializer_list<CharType> arg)
434 {
435 this->baseString.append(arg);
436 return *this;
437 }
438
442 SelfType& Append(const SelfType& arg)
443 {
444 this->baseString.append(arg.baseString);
445 return *this;
446 }
447
452 SelfType& Append(const SelfType& arg, size_type offset, size_type count = NPos)
453 {
454 this->baseString.append(arg.baseString, offset, count);
455 return *this;
456 }
457
461 SelfType& Append(const CharType* pChars, size_type count)
462 {
463 this->baseString.append(pChars, count);
464 return *this;
465 }
466
469 SelfType& Append(const CharType* pChars)
470 {
471 this->baseString.append(pChars);
472 return *this;
473 }
474
478 SelfType& Append(size_type count, CharType c)
479 {
480 this->baseString.append(count, c);
481 return *this;
482 }
483
487 SelfType& Append(iterator first, iterator last)
488 {
489 this->baseString.append(first, last);
490 return *this;
491 }
492
496 SelfType& Append(const_iterator first, const_iterator last)
497 {
498 this->baseString.append(first, last);
499 return *this;
500 }
501
505 SelfType& Append(const_pointer first, const_pointer last)
506 {
507 this->baseString.append(first, last);
508 return *this;
509 }
510
511public: // insert operations
512
517 iterator Insert(const_iterator where, std::initializer_list<CharType> arg)
518 {
519 return this->baseString.insert(where, arg);
520 }
521
526 SelfType& Insert(size_type offset, const SelfType& arg)
527 {
528 this->baseString.insert(offset, arg.baseString);
529 return *this;
530 }
531
538 SelfType& Insert(size_type offset, const SelfType& arg, size_type argOffset, size_type count = NPos)
539 {
540 this->baseString.insert(offset, arg.baseString, argOffset, count);
541 return *this;
542 }
543
549 SelfType& Insert(size_type offset, const CharType* pChars, size_type count)
550 {
551 this->baseString.insert(offset, pChars, count);
552 return *this;
553 }
554
559 SelfType& Insert(size_type offset, const CharType* pChars)
560 {
561 this->baseString.insert(offset, pChars);
562 return *this;
563 }
564
570 SelfType& Insert(size_type offset, size_type count, CharType c)
571 {
572 this->baseString.insert(offset, count, c);
573 return *this;
574 }
575
580 iterator Insert(const_iterator where, CharType c)
581 {
582 return this->baseString.insert(where, c);
583 }
584
590 iterator Insert(const_iterator where, size_type count, CharType c)
591 {
592 return this->baseString.insert(where, count, c);
593 }
594
600 iterator Insert(const_iterator where, iterator first, iterator last)
601 {
602 return this->baseString.insert(where, first, last);
603 }
604
610 iterator Insert(const_iterator where, const_iterator first, const_iterator last)
611 {
612 return this->baseString.insert(where, first, last);
613 }
614
620 iterator Insert(const_iterator where, const_pointer first, const_pointer last)
621 {
622 return this->baseString.insert(where, first, last);
623 }
624
625public: // erase operations
626
630 SelfType& Erase(size_type offset = 0)
631 {
632 this->baseString.erase(offset);
633 return (*this);
634 }
635
640 SelfType& Erase(size_type offset, size_type count)
641 {
642 this->baseString.erase(offset, count);
643 return (*this);
644 }
645
649 iterator Erase(const_iterator where)
650 {
651 return this->baseString.erase(where);
652 }
653
658 iterator Erase(const_iterator first, const_iterator last)
659 {
660 return this->baseString.erase(first, last);
661 }
662
663public: // replace operation
664
670 SelfType& Replace(const_iterator first, const_iterator last, std::initializer_list<CharType> chars)
671 {
672 this->baseString.replace(first, last, chars);
673 return *this;
674 }
675
681 SelfType& Replace(size_type offset, size_type length, const SelfType& arg)
682 {
683 this->baseString.replace(offset, length, arg.baseString);
684 return (*this);
685 }
686
694 SelfType& Replace(size_type offset, size_type length, const SelfType& arg, size_type offsetArg, size_type count = NPos)
695 {
696 this->baseString.replace(offset, length, arg.baseString, offsetArg, count);
697 return (*this);
698 }
699
706 SelfType& Replace(size_type offset, size_type length, const CharType* pChars, size_type count)
707 {
708 this->baseString.replace(offset, length, pChars, offset, count);
709 return (*this);
710 }
711
717 SelfType& Replace(size_type offset, size_type length, const CharType* pChars)
718 {
719 this->baseString.replace(offset, length, pChars);
720 return (*this);
721 }
722
729 SelfType& Replace(size_type offset, size_type length, size_type count, CharType c)
730 {
731 this->baseString.replace(offset, length, count, c);
732 return (*this);
733 }
734
740 SelfType& Replace(const_iterator first, const_iterator last, const SelfType& arg)
741 {
742 this->baseString.replace(first, last, arg.baseString);
743 return (*this);
744 }
745
752 SelfType& Replace(const_iterator first, const_iterator last, const CharType* pChars, size_type count)
753 {
754 this->baseString.replace(first, last, pChars, count);
755 return (*this);
756 }
757
763 SelfType& Replace(const_iterator first, const_iterator last, const CharType* pChars)
764 {
765 this->baseString.replace(first, last, pChars);
766 return (*this);
767 }
768
775 SelfType& Replace(const_iterator first, const_iterator last, size_type count, CharType c)
776 {
777 this->baseString.replace(first, last, count, c);
778 return (*this);
779 }
780
787 SelfType& Replace(const_iterator first, const_iterator last, iterator first2, iterator last2)
788 {
789 this->baseString.replace(first, last, first2, last2);
790 return (*this);
791 }
792
799 SelfType& Replace(const_iterator first, const_iterator last, const_iterator first2, const_iterator last2)
800 {
801 this->baseString.replace(first, last, first2, last2);
802 return (*this);
803 }
804
811 SelfType& Replace(const_iterator first, const_iterator last, const_pointer first2, const_pointer last2)
812 {
813 this->baseString.replace(first, last, first2, last2);
814 return (*this);
815 }
816
823 SelfType& Replace(const_iterator first, const_iterator last, pointer first2, pointer last2)
824 {
825 this->baseString.replace(first, last, first2, last2);
826 return (*this);
827 }
828
829public: // replace_all operations
830
836 SelfType& ReplaceAll(const SelfType& pattern, const SelfType& replacement)
837 {
838 boost::replace_all(this->baseString, pattern.baseString, replacement.baseString);
839 return (*this);
840 }
841
842public: // support of range based for loops
843
847 iterator begin()
848 {
849 return this->baseString.begin();
850 }
851
855 const_iterator begin() const
856 {
857 return this->baseString.begin();
858 }
859
863 iterator end()
864 {
865 return this->baseString.end();
866 }
867
871 const_iterator end() const
872 {
873 return this->baseString.end();
874 }
875
876public: // container operations
877
880 iterator Begin()
881 {
882 return this->baseString.begin();
883 }
884
887 const_iterator Begin() const
888 {
889 return this->baseString.begin();
890 }
891
894 iterator End()
895 {
896 return this->baseString.end();
897 }
898
901 const_iterator End() const
902 {
903 return this->baseString.end();
904 }
905
908 reverse_iterator ReverseBegin()
909 {
910 return this->baseString.rbegin();
911 }
912
915 const_reverse_iterator ReverseBegin() const
916 {
917 return this->baseString.rbegin();
918 }
919
922 reverse_iterator ReverseEnd()
923 {
924 return this->baseString.rend();
925 }
926
929 const_reverse_iterator ReverseEnd() const
930 {
931 return this->baseString.rend();
932 }
933
936 const_iterator ConstBegin() const
937 {
938 return this->baseString.cbegin();
939 }
940
943 const_iterator ConstEnd() const
944 {
945 return this->baseString.cend();
946 }
947
950 const_reverse_iterator ConstReverseBegin() const
951 {
952 return this->baseString.crbegin();
953 }
954
957 const_reverse_iterator ConstReverseEnd() const
958 {
959 return this->baseString.crend();
960 }
961
963 void ShrinkToFit()
964 {
965 this->baseString.shrink_to_fit();
966 }
967
970 void PushBack(CharType c)
971 {
972 this->baseString.push_back(c);
973 }
974
977 void PopBack()
978 {
979 if(!this->IsEmpty())
980 {
981 this->baseString.pop_back();
982 }
983 }
984
988 reference Front()
989 {
990 return this->baseString.front();
991 }
992
996 const_reference Front() const
997 {
998 return this->baseString.front();
999 }
1000
1004 reference Back()
1005 {
1006 return this->baseString.back();
1007 }
1008
1012 const_reference Back() const
1013 {
1014 return this->baseString.back();
1015 }
1016
1021 reference At(size_type offset)
1022 {
1023 return this->baseString.at(offset);
1024 }
1025
1030 const_reference At(size_type offset) const
1031 {
1032 return this->baseString.at(offset);
1033 }
1034
1039 reference operator[](size_type offset)
1040 {
1041 return this->baseString[offset];
1042 }
1043
1048 const_reference operator[](size_type offset) const
1049 {
1050 return this->baseString[offset];
1051 }
1052
1053public: // Size/Length operations
1054
1062 size_type Length() const
1063 {
1064 return this->baseString.length();
1065 }
1066
1074 size_type Size() const
1075 {
1076 return this->baseString.size();
1077 }
1078
1080 size_type MaxSize() const
1081 {
1082 return this->baseString.max_size();
1083 }
1084
1092 size_type Capacity() const
1093 {
1094 return this->baseString.capacity();
1095 }
1096
1099 bool IsEmpty() const
1100 {
1101 return this->baseString.empty();
1102 }
1103
1110 void Resize(size_type newSize)
1111 {
1112 this->baseString.resize(newSize);
1113 }
1114
1122 void Resize(size_type newSize, CharType c)
1123 {
1124 this->baseString.resize(newSize, c);
1125 }
1126
1134 void Reserve(size_type newCapacity = 0)
1135 {
1136 this->baseString.reserve(newCapacity);
1137 }
1138
1140 void Clear()
1141 {
1142 this->baseString.clear();
1143 }
1144
1145public: // Find operations
1146
1151 size_type Find(const SelfType& pattern, size_type offset = 0) const
1152 {
1153 return this->baseString.find(pattern.baseString, offset);
1154 }
1155
1161 size_type Find(const CharType* pChars, size_type offset, size_type count) const
1162 {
1163 return this->baseString.find(pChars, offset, count);
1164 }
1165
1170 size_type Find(const CharType* pChars, size_type offset = 0) const
1171 {
1172 return this->baseString.find(pChars, offset);
1173 }
1174
1179 size_type Find(CharType c, size_type offset = 0) const
1180 {
1181 return this->baseString.find(c, offset);
1182 }
1183
1188 size_type ReverseFind(const SelfType& pattern, size_type offset = NPos) const
1189 {
1190 return this->baseString.rfind(pattern.baseString, offset);
1191 }
1192
1198 size_type ReverseFind(const CharType* pChars, size_type offset, size_type count) const
1199 {
1200 return this->baseString.rfind(pChars, offset, count);
1201 }
1202
1207 size_type ReverseFind(const CharType* pChars, size_type offset = NPos) const
1208 {
1209 return this->baseString.rfind(pChars, offset);
1210 }
1211
1216 size_type ReverseFind(CharType c, size_type offset = NPos) const
1217 {
1218 return this->baseString.rfind(c, offset);
1219 }
1220
1225 size_type FindFirstOf(const SelfType& chars, size_type offset = 0) const
1226 {
1227 return this->baseString.find_first_of(chars.baseString, offset);
1228 }
1229
1235 size_type FindFirstOf(const CharType* pChars, size_type offset, size_type count) const
1236 {
1237 return this->baseString.find_first_of(pChars, offset, count);
1238 }
1239
1244 size_type FindFirstOf(const CharType* pChars, size_type offset = 0) const
1245 {
1246 return this->baseString.find_first_of(pChars, offset);
1247 }
1248
1254 size_type FindFirstOf(CharType c, size_type offset = 0) const
1255 {
1256 return this->baseString.find_first_of(c, offset);
1257 }
1258
1263 size_type FindLastOf(const SelfType& chars, size_type pos = NPos) const
1264 {
1265 return this->baseString.find_last_of(chars.baseString, pos);
1266 }
1267
1273 size_type FindLastOf(const CharType* pChars, size_type pos, size_type count) const
1274 {
1275 return this->baseString.find_last_of(pChars, pos, count);
1276 }
1277
1282 size_type FindLastOf(const CharType* pChars, size_type pos = NPos) const
1283 {
1284 return this->baseString.find_last_of(pChars, pos);
1285 }
1286
1292 size_type FindLastOf(CharType c, size_type pos = NPos) const
1293 {
1294 return this->baseString.find_last_of(c, pos);
1295 }
1296
1301 size_type FindFirstNotOf(const SelfType& chars, size_type offset = 0) const
1302 {
1303 return this->baseString.find_first_not_of(chars.baseString, offset);
1304 }
1305
1311 size_type FindFirstNotOf(const CharType* pChars, size_type offset, size_type count) const
1312 {
1313 return this->baseString.find_first_not_of(pChars, offset, count);
1314 }
1315
1320 size_type FindFirstNotOf(const CharType *pChars, size_type offset = 0) const
1321 {
1322 return this->baseString.find_first_not_of(pChars, offset);
1323 }
1324
1330 size_type FindFirstNotOf(CharType c, size_type offset = 0) const
1331 {
1332 return this->baseString.find_first_not_of(c, offset);
1333 }
1334
1339 size_type FindLastNotOf(const SelfType& chars, size_type pos = NPos) const
1340 {
1341 return this->baseString.find_last_not_of(chars.baseString, pos);
1342 }
1343
1349 size_type FindLastNotOf(const CharType *pChars, size_type pos, size_type count) const
1350 {
1351 return this->baseString.find_last_not_of(pChars, pos, count);
1352 }
1353
1358 size_type FindLastNotOf(const CharType *pChars, size_type pos = NPos) const
1359 {
1360 return this->baseString.find_last_not_of(pChars, pos);
1361 }
1362
1368 size_type FindLastNotOf(CharType c, size_type pos = NPos) const
1369 {
1370 return this->baseString.find_last_not_of(c, pos);
1371 }
1372
1373public: // Compare operations
1374
1382 int Compare(const SelfType& other) const
1383 {
1384 return this->baseString.compare(other.baseString);
1385 }
1386
1396 int Compare(size_type offset, size_type count, const SelfType& other) const
1397 {
1398 return this->baseString.compare(offset, count, other.baseString);
1399 }
1400
1412 int Compare(size_type offset, size_type count, const SelfType& other, size_type offsetOther, size_type countOther = NPos) const
1413 {
1414 return this->baseString.compare(offset, count, other.baseString, offsetOther, countOther);
1415 }
1416
1424 int Compare(const CharType *pOther) const
1425 {
1426 return this->baseString.compare(pOther);
1427 }
1428
1438 int Compare(size_type offset, size_type count, const CharType *pOther) const
1439 {
1440 return this->baseString.compare(offset, count, pOther);
1441 }
1442
1453 int Compare(size_type offset, size_type count, const CharType *pOther, size_type countOther) const
1454 {
1455 return this->baseString.compare(offset, count, pOther, countOther);
1456 }
1457
1458public: // misc operations (none std)
1459
1463 bool StartWith(const CharType *pChars)const
1464 {
1465 return this->Find(pChars) == 0;
1466 }
1467
1471 bool StartWith(const SelfType& pattern)const
1472 {
1473 return this->Find(pattern) == 0;
1474 }
1475
1479 bool EndWith(const CharType* pChars)const
1480 {
1481 return this->EndWith(SelfType(pChars));
1482 }
1483
1487 bool EndWith(const SelfType& pattern)const
1488 {
1489 size_t thisLength = this->baseString.length();
1490 size_t patternLength = pattern.baseString.length();
1491
1492 if (thisLength < patternLength)
1493 {
1494 return false;
1495 }
1496 // else
1497 return (this->baseString.compare(thisLength - patternLength, patternLength, pattern.baseString) == 0);
1498 }
1499
1500public: // Format operations
1501
1506 template<typename... Args>
1507 static SelfType Format(const SelfType& format, const Args& ... args)
1508 {
1509 return Format(format.CStr(), args...);
1510 }
1511
1516 template<typename... Args>
1517 static SelfType Format(const char* format, const Args& ... args)
1518 {
1519 return BasicFormatterType::FormatCommon(&BasicStringFormatExceptionHandler::Invoke, format, args...);
1520 }
1521
1522public: // Misc operations
1523
1526 ARP_DEPRECATED("Use GetStdString() instead.")
1527 const BaseString& GetBaseString()const
1528 {
1529 return this->baseString;
1530 }
1531
1534 const StdString& GetStdString()const
1535 {
1536 return this->baseString;
1537 }
1538
1541 const CharType* CStr() const
1542 {
1543 return this->baseString.c_str();
1544 }
1545
1548 operator const CharType* () const
1549 {
1550 return this->baseString.data();
1551 }
1552
1555 operator const BaseString& () const
1556 {
1557 return this->baseString;
1558 }
1559
1564 SelfType Substr(size_type offset = 0, size_type count = NPos) const
1565 {
1566 return SelfType(this->baseString.substr(offset, count));
1567 }
1568
1571 Allocator GetAllocator() const
1572 {
1573 return this->baseString.get_allocator();
1574 }
1575
1578 void Swap(SelfType& other)
1579 {
1580 this->baseString.swap(other.baseString);
1581 }
1582
1585 Bytes ToBytes()const
1586 {
1587 return Bytes(reinterpret_cast<const byte*>(this->CStr()), reinterpret_cast<const byte*>(this->CStr() + this->Size()));
1588 }
1589
1592 SelfType TrimLeft()const
1593 {
1594 auto left = std::find_if(this->baseString.begin(), this->baseString.end(), [](char c)
1595 {
1596 return !std::isspace<char>(c, std::locale::classic());
1597 });
1598 return SelfType(left, this->baseString.end());
1599 }
1600
1601 SelfType TrimLeft(char trim)const
1602 {
1603 auto left = std::find_if(this->baseString.begin(), this->baseString.end(), [trim](char c)
1604 {
1605 return c != trim;
1606 });
1607 return SelfType(left, this->baseString.end());
1608 }
1609
1610 SelfType TrimRight()const
1611 {
1612 auto right = std::find_if(this->baseString.rbegin(), this->baseString.rend(), [](char c)
1613 {
1614 return !std::isspace<char>(c, std::locale::classic());
1615 });
1616 return SelfType(this->baseString.begin(), right.base());
1617 }
1618
1619 SelfType TrimRight(char trim)const
1620 {
1621 auto right = std::find_if(this->baseString.rbegin(), this->baseString.rend(), [trim](char c)
1622 {
1623 return c != trim;
1624 });
1625 return SelfType(this->baseString.begin(), right.base());
1626 }
1627
1630 SelfType Trim()const
1631 {
1632 auto left = std::find_if(this->baseString.begin(), this->baseString.end(), [](char c)
1633 {
1634 return !std::isspace<char>(c, std::locale::classic());
1635 });
1636
1637 // check if string only consists of whitespaces
1638 if (left == this->baseString.end())
1639 {
1640 return Empty;
1641 }
1642
1643 auto right = std::find_if(this->baseString.rbegin(), this->baseString.rend(), [](char c)
1644 {
1645 return !std::isspace<char>(c, std::locale::classic());
1646 });
1647 return SelfType(left, right.base());
1648 }
1649
1650 SelfType Trim(char trim)const
1651 {
1652 auto left = std::find_if(this->baseString.begin(), this->baseString.end(), [trim](char c)
1653 {
1654 return c != trim;
1655 });
1656
1657 // check if string only consists of whitespaces
1658 if (left == this->baseString.end())
1659 {
1660 return Empty;
1661 }
1662
1663 auto right = std::find_if(this->baseString.rbegin(), this->baseString.rend(), [trim](char c)
1664 {
1665 return c != trim;
1666 });
1667 return SelfType(left, right.base());
1668 }
1669
1670public: // Split operations
1671
1677 Tokens Split(char delimiter, bool trimTokens = true, bool removeEmptyTokens = true)const
1678 {
1679 char delimiters[] = { delimiter };
1680 return this->Split(delimiters, 1, trimTokens, removeEmptyTokens);
1681 }
1682
1689 Tokens Split(const char delimiters[], size_t delimitersCount, bool trimTokens = true, bool removeEmptyTokens = true)const
1690 {
1691 Tokens tokens;
1692
1693 size_t last = 0;
1694 size_t length = this->Length();
1695
1696 for (size_t first = 0; first < length; first = last + 1)
1697 {
1698 size_t position = this->FindFirstOf(delimiters, first, delimitersCount);
1699 last = (position != NPos) ? position : this->Length();
1700
1701 SelfType token = this->Substr(first, last - first);
1702 if (trimTokens)
1703 {
1704 token = token.Trim();
1705 }
1706 if (!removeEmptyTokens || !token.IsEmpty())
1707 {
1708 tokens.push_back(token);
1709 }
1710 }
1711
1712 if (!removeEmptyTokens && (this->FindLastOf(delimiters, NPos, delimitersCount) == (length - 1)))
1713 {
1714 tokens.push_back(Empty);
1715 }
1716
1717 return tokens;
1718 }
1719
1725 Tokens SplitByWord(const SelfType& delimiter, bool trimTokens = true, bool removeEmptyTokens = true)const
1726 {
1727 Tokens tokens;
1728
1729 size_t last = 0;
1730 size_t length = this->Length();
1731 size_t delimiterLength = delimiter.Length();
1732
1733 for (size_t first = 0; first < length; first = last + delimiterLength)
1734 {
1735 size_t position = this->Find(delimiter, first);
1736 last = (position != NPos) ? position : length;
1737
1738 SelfType token = this->Substr(first, last - first);
1739 if (trimTokens)
1740 {
1741 token = token.Trim();
1742 }
1743 if (!token.IsEmpty() || !removeEmptyTokens)
1744 {
1745 tokens.push_back(token);
1746 }
1747 }
1748
1749 if (!removeEmptyTokens && this->EndWith(delimiter))
1750 {
1751 tokens.push_back(Empty);
1752 }
1753
1754 return tokens;
1755 }
1756
1757
1758 // warning 4996 occurs, to avoid use _SCL_SECURE_NO_WARNINGS
1759 //size_type Copy(CharType* pChars, size_type count, size_type offset = 0) const
1760 //{
1761 // return this->baseString.copy(pChars, count, offset);
1762 //}
1763
1764private: // fields
1765 BaseString baseString;
1766};
1767
1769// initializing of static fields
1770template <class CharType, class Alloc>
1771const BasicString<CharType, Alloc> BasicString<CharType, Alloc>::Empty;
1772
1773template <class CharType, class Alloc>
1774const BasicString<CharType, Alloc> BasicString<CharType, Alloc>::NewLine((CharType)'\n', (CharType)'\r');
1775
1777// inline global operators and functions of class BasicString<CharType, Alloc>
1778
1782template<class CharType, class Alloc>
1783inline void swap(BasicString<CharType, Alloc>& left, BasicString<CharType, Alloc>& right)noexcept
1784{
1785 left.Swap(right);
1786}
1787
1792template<class CharType, class Alloc>
1793inline std::ostream& operator<<(std::ostream& os, const BasicString<CharType, Alloc>& right)
1794{
1795 os << right.GetStdString();
1796 return os;
1797}
1798
1803template<class CharType, class Alloc>
1804inline std::istream& operator>>(std::istream& is, BasicString<CharType, Alloc>& right)
1805{
1806 std::basic_string<CharType, std::char_traits<CharType>, Alloc> baseString;
1807 is >> baseString;
1808 right.Assign(baseString);
1809 return is;
1810}
1811
1816template<class CharType, class Alloc>
1817inline BasicString<CharType, Alloc> operator+(
1818 const BasicString<CharType, Alloc>& left,
1819 const BasicString<CharType, Alloc>& right)
1820{
1821 return left.GetStdString() + right.GetStdString();
1822}
1823
1828template<class CharType, class Alloc>
1829inline BasicString<CharType, Alloc> operator+(
1830 const CharType* left,
1831 const BasicString<CharType, Alloc>& right)
1832{
1833 return left + right.GetStdString();
1834}
1835
1840template<class CharType, class Alloc>
1841inline BasicString<CharType, Alloc> operator+(
1842 const CharType left,
1843 const BasicString<CharType, Alloc>& right)
1844{
1845 return left + right.GetStdString();
1846}
1847
1852template<class CharType, class Alloc>
1853inline BasicString<CharType, Alloc> operator+(
1854 const BasicString<CharType, Alloc>& left,
1855 const CharType* right)
1856{
1857 return left.GetStdString() + right;
1858}
1859
1864template<class CharType, class Alloc>
1865inline BasicString<CharType, Alloc> operator+(
1866 const BasicString<CharType, Alloc>& left,
1867 const CharType right)
1868{
1869 return left.GetStdString() + right;
1870}
1871
1876template<class CharType, class Alloc>
1877inline BasicString<CharType, Alloc> operator+(
1878 const BasicString<CharType, Alloc>& left,
1879 BasicString<CharType, Alloc>&& right)
1880{
1881 return left.GetStdString() + right.GetStdString();
1882}
1883
1888template<class CharType, class Alloc>
1889inline BasicString<CharType, Alloc> operator+(
1890 BasicString<CharType, Alloc>&& left,
1891 const BasicString<CharType, Alloc>& right)
1892{
1893 return (std::move(left.Append(right)));
1894}
1895
1900template<class CharType, class Alloc>
1901inline BasicString<CharType, Alloc> operator+(
1902 BasicString<CharType, Alloc>&& left,
1903 BasicString<CharType, Alloc>&& right)
1904{
1905 return left.GetStdString() + right.GetStdString();
1906}
1907
1912template<class CharType, class Alloc>
1913inline BasicString<CharType, Alloc> operator+(
1914 const CharType* left,
1915 BasicString<CharType, Alloc>&& right)
1916{
1917 return left + right.GetStdString();
1918}
1919
1924template<class CharType, class Alloc>
1925inline BasicString<CharType, Alloc> operator+(
1926 const CharType left,
1927 BasicString<CharType, Alloc>&& right)
1928{
1929 return left + right.GetStdString();
1930}
1931
1936template<class CharType, class Alloc>
1937inline BasicString<CharType, Alloc> operator+(
1938 BasicString<CharType, Alloc>&& left,
1939 const CharType* right)
1940{
1941 return left.GetStdString() + right;
1942}
1943
1948template<class CharType, class Alloc>
1949inline BasicString<CharType, Alloc> operator+(
1950 BasicString<CharType, Alloc>&& left,
1951 const CharType right)
1952{
1953 return left.GetStdString() + right;
1954}
1955
1960template<class CharType, class Alloc>
1961inline bool operator==(
1962 const BasicString<CharType, Alloc>& left,
1963 const BasicString<CharType, Alloc>& right)
1964{
1965 return left.GetStdString() == right.GetStdString();
1966}
1967
1972template<class CharType, class Alloc>
1973inline bool operator==(
1974 const CharType* left,
1975 const BasicString<CharType, Alloc>& right)
1976{
1977 return left == right.GetStdString();
1978}
1979
1984template<class CharType, class Alloc>
1985inline bool operator==(
1986 const BasicString<CharType, Alloc>& left,
1987 const CharType* right)
1988{
1989 return left.GetStdString() == right;
1990}
1991
1996template<class CharType, class Alloc>
1997inline bool operator!=(
1998 const CharType *left,
1999 const BasicString<CharType, Alloc>& right)
2000{
2001 return (!(left == right));
2002}
2003
2008template<class CharType, class Alloc>
2009inline bool operator!=(
2010 const BasicString<CharType, Alloc>& left,
2011 const CharType* right)
2012{
2013 return (!(left == right));
2014}
2015
2020template<class CharType, class Alloc>
2021inline bool operator<(
2022 const BasicString<CharType, Alloc>& left,
2023 const BasicString<CharType, Alloc>& right)
2024{
2025 return left.GetStdString() < right.GetStdString();
2026}
2027
2032template<class CharType, class Alloc>
2033inline bool operator<(
2034 const CharType* left,
2035 const BasicString<CharType, Alloc>& right)
2036{
2037 return left < right.GetStdString();
2038}
2039
2044template<class CharType, class Alloc>
2045inline bool operator<(
2046 const BasicString<CharType, Alloc>& left,
2047 const CharType* right)
2048{
2049 return left.GetStdString() < right;
2050}
2051
2056template<class CharType, class Alloc>
2057inline bool operator>(
2058 const CharType* left,
2059 const BasicString<CharType, Alloc>& right)
2060{
2061 return (right < left);
2062}
2063
2068template<class CharType, class Alloc>
2069inline bool operator>(
2070 const BasicString<CharType, Alloc>& left,
2071 const CharType* right)
2072{
2073 return (right < left);
2074}
2075
2080template<class CharType, class Alloc>
2081inline bool operator<=(
2082 const CharType* left,
2083 const BasicString<CharType, Alloc>& right)
2084{
2085 return (!(right < left));
2086}
2087
2092template<class CharType, class Alloc>
2093inline bool operator<=(
2094 const BasicString<CharType, Alloc>& left,
2095 const CharType* right)
2096{
2097 return (!(right < left));
2098}
2099
2104template<class CharType, class Alloc>
2105inline bool operator>=(
2106 const CharType* left,
2107 const BasicString<CharType, Alloc>& right)
2108{
2109 return (!(left < right));
2110}
2111
2116template<class CharType, class Alloc>
2117inline bool operator>=(
2118 const BasicString<CharType, Alloc>& left,
2119 const CharType* right)
2120{
2121 return (!(left < right));
2122}
2123
2129template<class CharType, class Alloc>
2130inline auto operator<=>(const BasicString<CharType, Alloc>& left, const BasicString<CharType, Alloc>& right)
2131{
2132 return left.GetStdString() <=> right.GetStdString();
2133}
2134
2135} // end of namesapce Arp
2136
2138// template specialization of BasicString<C,Alloc> formatter
2139template<class C, class Alloc>
2140struct fmt::formatter<Arp::BasicString<C, Alloc>> : public fmt::ostream_formatter {};
2141
2143// standard template specializations of class BasicString<C,Alloc>
2144namespace std
2145{
2146
2150template<class C, class Alloc>
2151struct hash<Arp::BasicString<C, Alloc>>
2152{
2153private:
2154 typedef typename Arp::BasicString<C, Alloc>::BaseString BaseString;
2155
2156public:
2158 typedef Arp::BasicString<C, Alloc> argument_type;
2160 typedef size_t result_type;
2161
2162public:
2166 result_type operator()(const argument_type& key) const
2167 {
2168 return std::hash<BaseString>()(key.GetStdString());
2169 }
2170};
2171
2173
2174} // end of namespace std
2175
2176
2177#endif // ndef ARP_USE_ARP_SYSTEM_CORE
const StdString & GetStdString(void) const
Gets the std::string of this string.
Definition: String.ipp:1434
char8_t char8u
The Arp UTF8 character type of 1 byte size.
Definition: PrimitiveTypes.hpp:47
@ Empty
No sink assigned to session yet.
@ Append
Opens the file if it exists and seeks to the end. Otherwise, creates a new file.
@ Length
Specifies the size of the file in bytes as System.Int64.
Root namespace for the PLCnext API
class ARP_DEPRECATED("Use Arp::Enum<T> instead.") EnumStrings
Deprecated! The class implements an adapter for enums to define the string literals of the enum entri...
Definition: EnumStrings.hxx:38
Namespace of the C++ standard library
Definition: BasicStringFormatExceptionHandler.hpp:16