Embedded Template Library 1.0
Loading...
Searching...
No Matches
basic_string.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2016 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_BASIC_STRING_INCLUDED
32#define ETL_BASIC_STRING_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "iterator.h"
37#include "functional.h"
38#include "alignment.h"
39#include "array.h"
40#include "type_traits.h"
41#include "error_handler.h"
42#include "integral_limits.h"
43#include "exception.h"
44#include "memory.h"
45#include "binary.h"
46#include "flags.h"
47#include "string_utilities.h"
48
49#include <stddef.h>
50#include <stdint.h>
51#include <string.h>
52
53#if ETL_USING_LIBC_WCHAR_H
54 #include <wchar.h>
55#endif
56
57#if ETL_USING_STL && ETL_USING_CPP17
58 #include <string_view>
59#endif
60
61#if ETL_USING_STD_OSTREAM
62 #include <ostream>
63#endif
64
65#include "private/minmax_push.h"
66
67//*****************************************************************************
71//*****************************************************************************
72
73// Forward declaration of string_view
74namespace etl
75{
76 template <typename T, typename TTraits>
78}
79
80namespace etl
81{
82 //***************************************************************************
85 //***************************************************************************
86 class string_exception : public etl::exception
87 {
88 public:
89
90 string_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
91 : exception(reason_, file_name_, line_number_)
92 {
93 }
94 };
95
96 //***************************************************************************
99 //***************************************************************************
100 class string_empty : public etl::string_exception
101 {
102 public:
103
104 string_empty(string_type file_name_, numeric_type line_number_)
105 : string_exception(ETL_ERROR_TEXT("string:empty", ETL_BASIC_STRING_FILE_ID"A"), file_name_, line_number_)
106 {
107 }
108 };
109
110 //***************************************************************************
113 //***************************************************************************
114 class string_out_of_bounds : public etl::string_exception
115 {
116 public:
117
118 string_out_of_bounds(string_type file_name_, numeric_type line_number_)
119 : string_exception(ETL_ERROR_TEXT("string:bounds", ETL_BASIC_STRING_FILE_ID"B"), file_name_, line_number_)
120 {
121 }
122 };
123
124 //***************************************************************************
127 //***************************************************************************
128 class string_iterator : public etl::string_exception
129 {
130 public:
131
132 string_iterator(string_type file_name_, numeric_type line_number_)
133 : string_exception(ETL_ERROR_TEXT("string:iterator", ETL_BASIC_STRING_FILE_ID"C"), file_name_, line_number_)
134 {
135 }
136 };
137
138 //***************************************************************************
141 //***************************************************************************
142 class string_truncation : public etl::string_exception
143 {
144 public:
145
146 string_truncation(string_type file_name_, numeric_type line_number_)
147 : string_exception(ETL_ERROR_TEXT("string:truncation", ETL_BASIC_STRING_FILE_ID"D"), file_name_, line_number_)
148 {
149 }
150 };
151
152 //***************************************************************************
155 //***************************************************************************
157 {
158 //*************************************************************************
159 template <typename T = void>
161 {
162 public:
163
164 typedef size_t size_type;
165
166 static ETL_CONSTANT uint_least8_t IS_TRUNCATED = etl::bit<0>::value;
167 static ETL_CONSTANT uint_least8_t CLEAR_AFTER_USE = etl::bit<1>::value;
168
169 static ETL_CONSTANT size_type npos = etl::integral_limits<size_type>::max;
170 };
171
172 template <typename T>
173 ETL_CONSTANT uint_least8_t string_base_statics<T>::IS_TRUNCATED;
174
175 template <typename T>
176 ETL_CONSTANT uint_least8_t string_base_statics<T>::CLEAR_AFTER_USE;
177
178 template <typename T>
179 ETL_CONSTANT typename string_base_statics<T>::size_type string_base_statics<T>::npos;
180 }
181
182 //***************************************************************************
184 {
185 public:
186
187 typedef size_t size_type;
188
189 //*************************************************************************
192 //*************************************************************************
193 size_type size() const
194 {
195 return current_size;
196 }
197
198 //*************************************************************************
201 //*************************************************************************
202 size_type length() const
203 {
204 return current_size;
205 }
206
207 //*************************************************************************
210 //*************************************************************************
211 bool empty() const
212 {
213 return (current_size == 0);
214 }
215
216 //*************************************************************************
219 //*************************************************************************
220 bool full() const
221 {
222 return current_size == CAPACITY;
223 }
224
225 //*************************************************************************
228 //*************************************************************************
229 size_type capacity() const
230 {
231 return CAPACITY;
232 }
233
234 //*************************************************************************
237 //*************************************************************************
238 size_type max_size() const
239 {
240 return CAPACITY;
241 }
242
243 //*************************************************************************
246 //*************************************************************************
247 size_type available() const
248 {
249 return max_size() - size();
250 }
251
252 //*************************************************************************
255 //*************************************************************************
256 bool is_truncated() const
257 {
258#if ETL_HAS_STRING_TRUNCATION_CHECKS
259 return flags.test<IS_TRUNCATED>();
260#else
261 return false;
262#endif
263 }
264
265 //*************************************************************************
269 //*************************************************************************
270 ETL_DEPRECATED
271 bool truncated() const
272 {
273 return is_truncated();
274 }
275
276#if ETL_HAS_STRING_TRUNCATION_CHECKS
277 //*************************************************************************
279 //*************************************************************************
281 {
282 flags.set<IS_TRUNCATED, false>();
283 }
284#endif
285
286#if ETL_HAS_STRING_CLEAR_AFTER_USE
287 //*************************************************************************
289 //*************************************************************************
291 {
292 flags.set<CLEAR_AFTER_USE>();
293 }
294#endif
295
296 //*************************************************************************
298 //*************************************************************************
299 bool is_secure() const
300 {
301#if ETL_HAS_STRING_CLEAR_AFTER_USE
302 return flags.test<CLEAR_AFTER_USE>();
303#else
304 return false;
305#endif
306 }
307
308 protected:
309
310 //*************************************************************************
312 //*************************************************************************
313 string_base(size_type max_size_)
314 : current_size(0)
315 , CAPACITY(max_size_)
316 {
317 }
318
319#if ETL_HAS_STRING_TRUNCATION_CHECKS
320 //*************************************************************************
322 //*************************************************************************
323 void set_truncated(bool status)
324 {
325 flags.set<IS_TRUNCATED>(status);
326 }
327#endif
328
329 //*************************************************************************
331 //*************************************************************************
333 {
334 }
335
336 size_type current_size;
337 const size_type CAPACITY;
338
339#if ETL_HAS_STRING_TRUNCATION_CHECKS || ETL_HAS_STRING_CLEAR_AFTER_USE
341#endif
342 };
343
344 //***************************************************************************
348 //***************************************************************************
349 template <typename T>
351 {
352 public:
353
354 typedef ibasic_string<T> interface_type;
355
356 typedef T value_type;
357 typedef T& reference;
358 typedef const T& const_reference;
359 typedef T* pointer;
360 typedef const T* const_pointer;
361 typedef T* iterator;
362 typedef const T* const_iterator;
363 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
364 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
365
366 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
367
368 //*********************************************************************
371 //*********************************************************************
372 iterator begin()
373 {
374 return &p_buffer[0];
375 }
376
377 //*********************************************************************
380 //*********************************************************************
381 const_iterator begin() const
382 {
383 return &p_buffer[0];
384 }
385
386 //*********************************************************************
389 //*********************************************************************
390 iterator end()
391 {
392 return &p_buffer[current_size];
393 }
394
395 //*********************************************************************
398 //*********************************************************************
399 const_iterator end() const
400 {
401 return &p_buffer[current_size];
402 }
403
404 //*********************************************************************
407 //*********************************************************************
408 const_iterator cbegin() const
409 {
410 return &p_buffer[0];
411 }
412
413 //*********************************************************************
416 //*********************************************************************
417 const_iterator cend() const
418 {
419 return &p_buffer[current_size];
420 }
421
422 //*********************************************************************
425 //*********************************************************************
426 reverse_iterator rbegin()
427 {
428 return reverse_iterator(end());
429 }
430
431 //*********************************************************************
434 //*********************************************************************
435 const_reverse_iterator rbegin() const
436 {
437 return const_reverse_iterator(end());
438 }
439
440 //*********************************************************************
443 //*********************************************************************
444 reverse_iterator rend()
445 {
446 return reverse_iterator(begin());
447 }
448
449 //*********************************************************************
452 //*********************************************************************
453 const_reverse_iterator rend() const
454 {
455 return const_reverse_iterator(begin());
456 }
457
458 //*********************************************************************
461 //*********************************************************************
462 const_reverse_iterator crbegin() const
463 {
464 return const_reverse_iterator(cend());
465 }
466
467 //*********************************************************************
470 //*********************************************************************
471 const_reverse_iterator crend() const
472 {
473 return const_reverse_iterator(cbegin());
474 }
475
476 //*********************************************************************
480 //*********************************************************************
481 void resize(size_type new_size)
482 {
483 resize(new_size, 0);
484 }
485
486 //*********************************************************************
490 //*********************************************************************
491 void resize(size_type new_size, T value)
492 {
493 if (new_size > CAPACITY)
494 {
495#if ETL_HAS_STRING_TRUNCATION_CHECKS
496 set_truncated(true);
497
498#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
499 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
500#endif
501#endif
502 }
503
504 new_size = etl::min(new_size, CAPACITY);
505
506 // Size up?
507 if (new_size > current_size)
508 {
509 etl::fill(p_buffer + current_size, p_buffer + new_size, value);
510 }
511
512 current_size = new_size;
513 p_buffer[new_size] = 0;
514 cleanup();
515 }
516
517 //*********************************************************************
519 //*********************************************************************
520 template <typename TOperation>
521 void resize_and_overwrite(size_type new_size, TOperation operation)
522 {
523 if (new_size > CAPACITY)
524 {
525 ETL_ASSERT_FAIL(ETL_ERROR(string_out_of_bounds));
526 }
527
528 current_size = operation(p_buffer, new_size);
529 p_buffer[current_size] = '\0';
530 cleanup();
531 }
532
533 //*********************************************************************
537 //*********************************************************************
538 void uninitialized_resize(size_type new_size)
539 {
540 new_size = etl::min(new_size, CAPACITY);
541
542 current_size = new_size;
543 p_buffer[new_size] = 0;
544 }
545
546 //*********************************************************************
550 //*********************************************************************
551 void fill(T value)
552 {
553 etl::fill(begin(), end(), value);
554 }
555
556 //*********************************************************************
560 //*********************************************************************
561 reference operator [](size_type i)
562 {
563 ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(string_out_of_bounds));
564 return p_buffer[i];
565 }
566
567 //*********************************************************************
571 //*********************************************************************
572 const_reference operator [](size_type i) const
573 {
574 ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(string_out_of_bounds));
575 return p_buffer[i];
576 }
577
578 //*********************************************************************
583 //*********************************************************************
584 reference at(size_type i)
585 {
586 ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds));
587 return p_buffer[i];
588 }
589
590 //*********************************************************************
595 //*********************************************************************
596 const_reference at(size_type i) const
597 {
598 ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds));
599 return p_buffer[i];
600 }
601
602 //*********************************************************************
605 //*********************************************************************
606 reference front()
607 {
608 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
609 return p_buffer[0];
610 }
611
612 //*********************************************************************
615 //*********************************************************************
616 const_reference front() const
617 {
618 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
619 return p_buffer[0];
620 }
621
622 //*********************************************************************
625 //*********************************************************************
626 reference back()
627 {
628 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
629 return p_buffer[size() - 1];
630 }
631
632 //*********************************************************************
635 //*********************************************************************
636 const_reference back() const
637 {
638 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
639 return p_buffer[size() - 1];
640 }
641
642 //*********************************************************************
645 //*********************************************************************
646 pointer data()
647 {
648 return p_buffer;
649 }
650
651 //*********************************************************************
654 //*********************************************************************
655 ETL_CONSTEXPR const_pointer data() const
656 {
657 return p_buffer;
658 }
659
660 //*********************************************************************
663 //*********************************************************************
664 pointer data_end()
665 {
666 return p_buffer + current_size;
667 }
668
669 //*********************************************************************
672 //*********************************************************************
673 const_pointer data_end() const
674 {
675 return p_buffer + current_size;
676 }
677
678 //*********************************************************************
682 //*********************************************************************
683 void assign(const etl::ibasic_string<T>& other)
684 {
685 if (&other != this)
686 {
687 clear();
688 append_impl(begin(), other.begin(), other.end(), other.is_truncated(), other.is_secure());
689 }
690 }
691
692 //*********************************************************************
698 //*********************************************************************
699 void assign(const etl::ibasic_string<T>& other, size_type subposition, size_type sublength)
700 {
701 if (&other != this)
702 {
703 clear();
704
705 if (sublength == npos)
706 {
707 sublength = other.size() - subposition;
708 }
709
710 ETL_ASSERT(subposition <= other.size(), ETL_ERROR(string_out_of_bounds));
711
712 append_impl(begin(), other.begin() + subposition, other.begin() + subposition + sublength, other.is_truncated(), other.is_secure());
713 }
714 }
715
716 //*********************************************************************
722 //*********************************************************************
723 template <typename TIterator>
724 void assign(TIterator first, TIterator last)
725 {
726 append_impl(begin(), first, last, false, false);
727 }
728
729 //*********************************************************************
733 //*********************************************************************
734 void assign(const_pointer str)
735 {
736 append_impl(begin(), str, false, false);
737 }
738
739 //*********************************************************************
744 //*********************************************************************
745 void assign(const_pointer str, size_type n)
746 {
747 append_impl(begin(), str, str + n, false, false);
748 }
749
750 //*********************************************************************
752 //*********************************************************************
753 template <typename TOtherTraits>
755 {
756 append_impl(begin(), view.begin(), view.end(), false, false);
757 }
758
759 //*********************************************************************
764 //*********************************************************************
765 void assign(size_type n, T c)
766 {
767 clear();
768
769#if ETL_HAS_STRING_TRUNCATION_CHECKS
771
772#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
773 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
774#endif
775#endif
776
777 n = etl::min(n, CAPACITY);
778
779 etl::fill_n(begin(), n, c);
780 current_size = n;
781 p_buffer[current_size] = 0;
782 }
783
784 //*************************************************************************
786 //*************************************************************************
787 void clear()
788 {
789 initialise();
790 cleanup();
791 }
792
793 //*********************************************************************
797 //*********************************************************************
798 void push_back(T value)
799 {
800 if (current_size != CAPACITY)
801 {
802 p_buffer[current_size++] = value;
803 p_buffer[current_size] = 0;
804 }
805 else
806 {
807#if ETL_HAS_STRING_TRUNCATION_CHECKS
808 set_truncated(true);
809
810#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
811 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
812#endif
813#endif
814 }
815 }
816
817 //*************************************************************************
820 //*************************************************************************
821 void pop_back()
822 {
823 if (current_size != 0)
824 {
825 p_buffer[--current_size] = 0;
826 }
827 }
828
829 //*********************************************************************
832 //*********************************************************************
834 {
835 append_impl(end(), str.begin(), str.end(), str.is_truncated(), str.is_secure());
836
837 return *this;
838 }
839
840 //*********************************************************************
845 //*********************************************************************
846 ibasic_string& append(const ibasic_string& str, size_type subposition, size_type sublength = npos)
847 {
848 if (sublength == npos)
849 {
850 sublength = str.size() - subposition;
851 }
852
853 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
854
855 append_impl(end(), str.begin() + subposition, str.begin() + subposition + sublength, str.is_truncated(), str.is_secure());
856
857 return *this;
858 }
859
860 //*********************************************************************
864 //*********************************************************************
865 template <class TIterator>
866 ibasic_string& append(TIterator first, TIterator last)
867 {
868 append_impl(end(), first, last, false, false);
869
870 return *this;
871 }
872
873 //*********************************************************************
876 //*********************************************************************
877 ibasic_string& append(const_pointer str)
878 {
879 append_impl(end(), str, false, false);
880
881 return *this;
882 }
883
884 //*********************************************************************
888 //*********************************************************************
889 ibasic_string& append(const_pointer str, size_type n)
890 {
891 append_impl(end(), str, str + n, false, false);
892
893 return *this;
894 }
895
896 //*********************************************************************
899 //*********************************************************************
900 template <typename TOtherTraits>
902 {
903 append_impl(end(), view.begin(), view.end(), false, false);
904
905 return *this;
906 }
907
908 //*********************************************************************
912 //*********************************************************************
913 ibasic_string& append(size_type n, T c)
914 {
915 size_type free_space = CAPACITY - current_size;
916
917#if ETL_HAS_STRING_TRUNCATION_CHECKS
918 set_truncated(n > free_space);
919
920#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
921 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
922#endif
923#endif
924
925 n = etl::min(n, size_t(free_space));
926
927 etl::fill_n(end(), n, c);
928 current_size += n;
929 p_buffer[current_size] = 0;
930
931 return *this;
932 }
933
934 //*********************************************************************
938 //*********************************************************************
939 iterator insert(const_iterator position, T value)
940 {
941 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
942
943 // Quick hack, as iterators are pointers.
944 iterator insert_position = to_iterator(position);
945
947 {
948 // Not full yet.
949 if (position != end())
950 {
951 // Insert in the middle.
952 ++current_size;
953 etl::mem_move(insert_position, end() - 1, insert_position + 1);
954 *insert_position = value;
955 }
956 else
957 {
958 // Insert at the end.
959 *insert_position = value;
960 ++current_size;
961 }
962 }
963 else
964 {
965 // Already full.
966 if (position != end())
967 {
968 // Insert in the middle.
969 etl::mem_move(insert_position, end() - 1, insert_position + 1);
970 *insert_position = value;
971 }
972
973#if ETL_HAS_STRING_TRUNCATION_CHECKS
974 set_truncated(true);
975
976#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
977 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
978#endif
979#endif
980 }
981
982 p_buffer[current_size] = 0;
983
984 return insert_position;
985 }
986
987 //*********************************************************************
992 //*********************************************************************
993 iterator insert(const_iterator position, size_type n, T value)
994 {
995 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
996
997 iterator position_ = to_iterator(position);
998
999 if (n == 0)
1000 {
1001 return position_;
1002 }
1003
1004 // Quick hack, as iterators are pointers.
1005 iterator insert_position = to_iterator(position);
1006 const size_type start = etl::distance(cbegin(), position);
1007
1008 // No effect.
1009 if (start >= CAPACITY)
1010 {
1011#if ETL_HAS_STRING_TRUNCATION_CHECKS
1012 set_truncated(true);
1013
1014#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1015 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1016#endif
1017#endif
1018 return to_iterator(position);;
1019 }
1020
1021 // Fills the string to the end?
1022 if ((start + n) >= CAPACITY)
1023 {
1024 if ((current_size + n) > CAPACITY)
1025 {
1026#if ETL_HAS_STRING_TRUNCATION_CHECKS
1027 set_truncated(true);
1028
1029#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1030 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1031#endif
1032#endif
1033 }
1034
1036 etl::fill(insert_position, end(), value);
1037 }
1038 else
1039 {
1040 // Lets do some shifting.
1041 const size_type shift_amount = n;
1042 const size_type to_position = start + shift_amount;
1043 const size_type remaining_characters = current_size - start;
1044 const size_type max_shift_characters = CAPACITY - start - shift_amount;
1045 const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters);
1046
1047 // Will the string truncate?
1048 if ((start + shift_amount + remaining_characters) > CAPACITY)
1049 {
1051
1052#if ETL_HAS_STRING_TRUNCATION_CHECKS
1053 set_truncated(true);
1054
1055#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1056 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1057#endif
1058#endif
1059 }
1060 else
1061 {
1062 current_size += shift_amount;
1063 }
1064
1065 etl::mem_move(insert_position, insert_position + characters_to_shift, begin() + to_position);
1066 etl::fill(insert_position, insert_position + shift_amount, value);
1067 }
1068
1069 p_buffer[current_size] = 0;
1070
1071 return position_;
1072 }
1073
1074 //*********************************************************************
1080 //*********************************************************************
1081 template <typename TIterator>
1082 iterator insert(const_iterator position, TIterator first, TIterator last)
1083 {
1084 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
1085 ETL_ASSERT_CHECK_EXTRA(first <= last, ETL_ERROR(string_iterator));
1086
1087 iterator position_ = to_iterator(position);
1088
1089 if (first == last)
1090 {
1091 return position_;
1092 }
1093
1094 const size_type start = etl::distance(begin(), position_);
1095 const size_type n = etl::distance(first, last);
1096
1097 // No effect.
1098 if (start >= CAPACITY)
1099 {
1100#if ETL_HAS_STRING_TRUNCATION_CHECKS
1101 set_truncated(true);
1102
1103#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1104 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1105#endif
1106#endif
1107 return position_;
1108 }
1109
1110 // Fills the string to the end?
1111 if ((start + n) >= CAPACITY)
1112 {
1113 if (((current_size + n) > CAPACITY))
1114 {
1115#if ETL_HAS_STRING_TRUNCATION_CHECKS
1116 set_truncated(true);
1117
1118#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1119 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1120#endif
1121#endif
1122 }
1123
1125
1126 position_ = copy_characters(first, etl::distance(position_, end()), position_);
1127 }
1128 else
1129 {
1130 // Lets do some shifting.
1131 const size_type shift_amount = n;
1132 const size_type to_position = start + shift_amount;
1133 const size_type remaining_characters = current_size - start;
1134 const size_type max_shift_characters = CAPACITY - start - shift_amount;
1135 const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters);
1136
1137 // Will the string truncate?
1138 if ((start + shift_amount + remaining_characters) > CAPACITY)
1139 {
1141
1142#if ETL_HAS_STRING_TRUNCATION_CHECKS
1143 set_truncated(true);
1144
1145#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1146 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1147#endif
1148#endif
1149 }
1150 else
1151 {
1152 current_size += shift_amount;
1153 }
1154
1155 etl::mem_move(position_, position_ + characters_to_shift, begin() + to_position);
1156 //etl::copy_backward(position_, position_ + characters_to_shift, begin() + to_position + characters_to_shift);
1157
1158 position_ = copy_characters(first, etl::distance(first, last), position_);
1159 }
1160
1161 p_buffer[current_size] = 0;
1162
1163 return position_;
1164 }
1165
1166 //*********************************************************************
1171 //*********************************************************************
1172 template <typename TOtherTraits>
1173 iterator insert(const_iterator position, const etl::basic_string_view<T, TOtherTraits>& view)
1174 {
1175 return insert(position, view.begin(), view.end());
1176 }
1177
1178 //*********************************************************************
1182 //*********************************************************************
1183 etl::ibasic_string<T>& insert(size_type position, const etl::ibasic_string<T>& str)
1184 {
1185 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1186
1187 insert(begin() + position, str.cbegin(), str.cend());
1188
1189#if ETL_HAS_STRING_TRUNCATION_CHECKS
1190 if (str.is_truncated())
1191 {
1192 set_truncated(true);
1193
1194#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1195 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1196#endif
1197 }
1198#endif
1199
1200 return *this;
1201 }
1202
1203 //*********************************************************************
1207 //*********************************************************************
1208 template <typename TOtherTraits>
1210 {
1211 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1212
1213 insert(begin() + position, view.cbegin(), view.cend());
1214
1215 return *this;
1216 }
1217
1218 //*********************************************************************
1224 //*********************************************************************
1225 etl::ibasic_string<T>& insert(size_type position, const etl::ibasic_string<T>& str, size_type subposition, size_type sublength)
1226 {
1227 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1228 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1229
1230 if ((sublength == npos) || (subposition + sublength > str.size()))
1231 {
1232 sublength = str.size() - subposition;
1233 }
1234
1235 insert(begin() + position, str.cbegin() + subposition, str.cbegin() + subposition + sublength);
1236
1237#if ETL_HAS_STRING_TRUNCATION_CHECKS
1238 if (str.is_truncated())
1239 {
1240 set_truncated(true);
1241
1242#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1243 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1244#endif
1245 }
1246#endif
1247
1248 return *this;
1249 }
1250
1251 //*********************************************************************
1257 //*********************************************************************
1258 template <typename TOtherTraits>
1259 etl::ibasic_string<T>& insert(size_type position, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition, size_type sublength)
1260 {
1261 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1262 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1263
1264 if ((sublength == npos) || (subposition + sublength > view.size()))
1265 {
1266 sublength = view.size() - subposition;
1267 }
1268
1269 insert(begin() + position, view.cbegin() + subposition, view.cbegin() + subposition + sublength);
1270
1271 return *this;
1272 }
1273
1274 //*********************************************************************
1278 //*********************************************************************
1279 etl::ibasic_string<T>& insert(size_type position, const_pointer s)
1280 {
1281 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1282
1283 insert(begin() + position, s, s + etl::strlen(s));
1284 return *this;
1285 }
1286
1287 //*********************************************************************
1292 //*********************************************************************
1293 etl::ibasic_string<T>& insert(size_type position, const_pointer s, size_type n)
1294 {
1295 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1296
1297 insert(begin() + position, s, s + n);
1298 return *this;
1299 }
1300
1301 //*********************************************************************
1306 //*********************************************************************
1307 etl::ibasic_string<T>& insert(size_type position, size_type n, value_type c)
1308 {
1309 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1310
1311 insert(begin() + position, n, c);
1312 return *this;
1313 }
1314
1315 //*********************************************************************
1320 //*********************************************************************
1321 etl::ibasic_string<T>& erase(size_type position, size_type length_ = npos)
1322 {
1323 ETL_ASSERT_CHECK_EXTRA(position <= size(), ETL_ERROR(string_out_of_bounds));
1324
1325 // Limit the length.
1326 length_ = etl::min(length_, size() - position);
1327
1328 erase(begin() + position, begin() + position + length_);
1329
1330 return *this;
1331 }
1332
1333 //*********************************************************************
1337 //*********************************************************************
1338 iterator erase(iterator i_element)
1339 {
1340 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1341
1342 etl::mem_move(i_element + 1, end(), i_element);
1343 p_buffer[--current_size] = 0;
1344
1345 return i_element;
1346 }
1347
1348 //*********************************************************************
1352 //*********************************************************************
1353 iterator erase(const_iterator i_element)
1354 {
1355 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1356
1357 iterator i_element_(to_iterator(i_element));
1358
1359 etl::mem_move(i_element + 1, end(), i_element_);
1360 p_buffer[--current_size] = 0;
1361
1362 return i_element_;
1363 }
1364
1365 //*********************************************************************
1372 //*********************************************************************
1373 iterator erase(const_iterator first, const_iterator last)
1374 {
1375 ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(string_out_of_bounds));
1376
1377 iterator first_ = to_iterator(first);
1378 iterator last_ = to_iterator(last);
1379
1380 if (first_ == last_)
1381 {
1382 return first_;
1383 }
1384
1385 etl::mem_move(last_, end(), first_);
1386 size_type n_delete = etl::distance(first_, last_);
1387
1388 current_size -= n_delete;
1389 p_buffer[current_size] = 0;
1390 cleanup();
1391
1392 return first_;
1393 }
1394
1395 //*********************************************************************
1397 //*********************************************************************
1398 const_pointer c_str() const
1399 {
1400 return p_buffer;
1401 }
1402
1403 //*********************************************************************
1408 //*********************************************************************
1409 size_type copy(pointer dest, size_type count, size_type pos = 0) const
1410 {
1411 if (pos < size())
1412 {
1413 if (count != npos)
1414 {
1415 count = etl::min(count, size() - pos);
1416 }
1417 else
1418 {
1419 count = size() - pos;
1420 }
1421
1422 etl::mem_move(p_buffer + pos, count, dest);
1423
1424 return count;
1425 }
1426 else
1427 {
1428 return 0U;
1429 }
1430 }
1431
1432 //*********************************************************************
1436 //*********************************************************************
1437 size_type find(const ibasic_string<T>& str, size_type pos = 0) const
1438 {
1439 return find_impl(str.begin(), str.end(), str.size(), pos);
1440 }
1441
1442 //*********************************************************************
1446 //*********************************************************************
1447 template <typename TOtherTraits>
1448 size_type find(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = 0) const
1449 {
1450 return find_impl(view.begin(), view.end(), view.size(), pos);
1451 }
1452
1453 //*********************************************************************
1457 //*********************************************************************
1458 size_type find(const_pointer s, size_type pos = 0) const
1459 {
1460 size_t sz = etl::strlen(s);
1461
1462 return find_impl(s, s + sz, sz, pos);
1463 }
1464
1465 //*********************************************************************
1470 //*********************************************************************
1471 size_type find(const_pointer s, size_type pos, size_type n) const
1472 {
1473 size_t sz = etl::strlen(s);
1474
1475 return find_impl(s, s + n, sz, pos);
1476 }
1477
1478 //*********************************************************************
1482 //*********************************************************************
1483 size_type find(T c, size_type position = 0) const
1484 {
1485 const_iterator i = etl::find(begin() + position, end(), c);
1486
1487 if (i != end())
1488 {
1489 return etl::distance(begin(), i);
1490 }
1491 else
1492 {
1493 return npos;
1494 }
1495 }
1496
1497 //*********************************************************************
1501 //*********************************************************************
1502 size_type rfind(const ibasic_string<T>& str, size_type position = npos) const
1503 {
1504 return rfind_impl(str.rbegin(), str.rend(), str.size(), position);
1505 }
1506
1507 //*********************************************************************
1511 //*********************************************************************
1512 template <typename TOtherTraits>
1513 size_type rfind(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = 0) const
1514 {
1515 return rfind_impl(view.rbegin(), view.rend(), view.size(), pos);
1516 }
1517
1518 //*********************************************************************
1522 //*********************************************************************
1523 size_type rfind(const_pointer s, size_type position = npos) const
1524 {
1525 size_type len = etl::strlen(s);
1526
1527 const_reverse_iterator srbegin(s + len);
1528 const_reverse_iterator srend(s);
1529
1530 return rfind_impl(srbegin, srend, len, position);
1531 }
1532
1533 //*********************************************************************
1537 //*********************************************************************
1538 size_type rfind(const_pointer s, size_type position, size_type length_) const
1539 {
1540 const_reverse_iterator srbegin(s + length_);
1541 const_reverse_iterator srend(s);
1542
1543 return rfind_impl(srbegin, srend, length_, position);
1544 }
1545
1546 //*********************************************************************
1550 //*********************************************************************
1551 size_type rfind(T c, size_type position = npos) const
1552 {
1553 if (position >= size())
1554 {
1555 position = size();
1556 }
1557
1558 position = size() - position;
1559
1560 const_reverse_iterator i = etl::find(rbegin() + position, rend(), c);
1561
1562 if (i != rend())
1563 {
1564 return size() - etl::distance(rbegin(), i) - 1;
1565 }
1566 else
1567 {
1568 return npos;
1569 }
1570 }
1571
1572 //*********************************************************************
1574 //*********************************************************************
1575 bool contains(const etl::ibasic_string<T>& str) const
1576 {
1577 return find(str) != npos;
1578 }
1579
1580 //*********************************************************************
1582 //*********************************************************************
1583 template <typename TOtherTraits>
1585 {
1586 return find(view) != npos;
1587 }
1588
1589 //*********************************************************************
1591 //*********************************************************************
1592 bool contains(const_pointer s) const
1593 {
1594 return find(s) != npos;
1595 }
1596
1597 //*********************************************************************
1599 //*********************************************************************
1600 bool contains(value_type c) const
1601 {
1602 return find(c) != npos;
1603 }
1604
1605 //*********************************************************************
1607 //*********************************************************************
1608 bool starts_with(const etl::ibasic_string<T>& str) const
1609 {
1610 return compare(0, str.size(), str) == 0;
1611 }
1612
1613 //*********************************************************************
1615 //*********************************************************************
1616 template <typename TOtherTraits>
1618 {
1619 return compare(0, view.size(), view) == 0;
1620 }
1621
1622 //*********************************************************************
1624 //*********************************************************************
1625 bool starts_with(const_pointer s) const
1626 {
1627 size_t len = etl::strlen(s);
1628
1629 return compare(0, len, s, len) == 0;
1630 }
1631
1632 //*********************************************************************
1634 //*********************************************************************
1635 bool starts_with(value_type c) const
1636 {
1637 return !empty() && (front() == c);
1638 }
1639
1640 //*********************************************************************
1642 //*********************************************************************
1643 bool ends_with(const etl::ibasic_string<T>& str) const
1644 {
1645 if (str.size() > size())
1646 {
1647 return false;
1648 }
1649
1650 return compare(size() - str.size(), str.size(), str) == 0;
1651 }
1652
1653 //*********************************************************************
1655 //*********************************************************************
1656 template <typename TOtherTraits>
1658 {
1659 if (view.size() > size())
1660 {
1661 return false;
1662 }
1663
1664 return compare(size() - view.size(), view.size(), view) == 0;
1665 }
1666
1667 //*********************************************************************
1669 //*********************************************************************
1670 bool ends_with(const_pointer s) const
1671 {
1672 size_t len = etl::strlen(s);
1673
1674 if (len > size())
1675 {
1676 return false;
1677 }
1678
1679 return compare(size() - len, len, s, len) == 0;
1680 }
1681
1682 //*********************************************************************
1684 //*********************************************************************
1685 bool ends_with(value_type c) const
1686 {
1687 return !empty() && (back() == c);
1688 }
1689
1690 //*********************************************************************
1695 //*********************************************************************
1696 ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str)
1697 {
1698 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1699
1700 // Limit the length.
1701 length_ = etl::min(length_, size() - position);
1702
1703 return replace_impl(begin() + position, begin() + position + length_, str.begin(), str.size(), str.is_truncated());
1704 }
1705
1706 //*********************************************************************
1711 //*********************************************************************
1712 template <typename TOtherTraits>
1713 ibasic_string& replace(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view)
1714 {
1715 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1716
1717 // Limit the length.
1718 length_ = etl::min(length_, size() - position);
1719
1720 return replace_impl(begin() + position, begin() + position + length_, view.begin(), view.size(), false);
1721 }
1722
1723 //*********************************************************************
1728 //*********************************************************************
1729 ibasic_string& replace(const_iterator first, const_iterator last, const ibasic_string& str)
1730 {
1731 return replace_impl(first, last, str.begin(), str.size(), str.is_truncated());
1732 }
1733
1734 //*********************************************************************
1739 //*********************************************************************
1740 template <typename TOtherTraits>
1741 ibasic_string& replace(const_iterator first, const_iterator last, const etl::basic_string_view<T, TOtherTraits>& view)
1742 {
1743 return replace_impl(first, last, view.begin(), view.size(), false);
1744 }
1745
1746 //*********************************************************************
1748 //*********************************************************************
1749 ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength)
1750 {
1751 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1752 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1753
1754 // Limit the lengths.
1755 length_ = etl::min(length_, size() - position);
1756 sublength = etl::min(sublength, str.size() - subposition);
1757
1758 return replace_impl(begin() + position, begin() + position + length_, str.begin() + subposition, sublength, str.is_truncated());
1759 }
1760
1761 //*********************************************************************
1763 //*********************************************************************
1764 template <typename TOtherTraits>
1765 ibasic_string& replace(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition, size_type sublength)
1766 {
1767 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1768 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1769
1770 // Limit the lengths.
1771 length_ = etl::min(length_, size() - position);
1772 sublength = etl::min(sublength, view.size() - subposition);
1773
1774 return replace_impl(begin() + position, begin() + position + length_, view.begin() + subposition, sublength, false);
1775 }
1776
1777 //*********************************************************************
1779 //*********************************************************************
1780 ibasic_string& replace(size_type position, size_type length_, const_pointer s)
1781 {
1782 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1783
1784 // Limit the length.
1785 length_ = etl::min(length_, size() - position);
1786
1787 return replace_impl(begin() + position, begin() + position + length_, s, etl::strlen(s), false);
1788 }
1789
1790 //*********************************************************************
1798 //*********************************************************************
1799 ibasic_string& replace(const_iterator first, const_iterator last, const_pointer s, size_type n)
1800 {
1801 return replace_impl(first, last, s, n, false);
1802 }
1803
1804 //*********************************************************************
1806 //*********************************************************************
1807 template <typename TIterator>
1809 replace(const_iterator first, const_iterator last, TIterator s)
1810 {
1811 return replace_impl(first, last, s, etl::strlen(s), false);
1812 }
1813
1814 //*********************************************************************
1816 //*********************************************************************
1817 template <size_t Size>
1818 ibasic_string& replace(const_iterator first, const_iterator last, const value_type (&literal)[Size])
1819 {
1820 return replace_impl(first, last, literal, Size, false);
1821 }
1822
1823 //*********************************************************************
1825 //*********************************************************************
1826 ibasic_string& replace(size_type position, size_type length_, const_pointer s, size_type n)
1827 {
1828 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1829
1830 // Limit the length.
1831 length_ = etl::min(length_, size() - position);
1832
1833 return replace_impl(begin() + position, begin() + position + length_, s, n, false);
1834 }
1835
1836 //*********************************************************************
1838 //*********************************************************************
1839 ibasic_string& replace(size_type position, size_type length_, size_type n, value_type c)
1840 {
1841 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1842
1843 // Limit the length.
1844 length_ = etl::min(length_, size() - position);
1845
1846 // Erase the bit we want to replace.
1847 erase(position, length_);
1848
1849 // Insert the new stuff.
1850 insert(position, n, c);
1851
1852 return *this;
1853 }
1854
1855 //*********************************************************************
1857 //*********************************************************************
1858 ibasic_string& replace(const_iterator first, const_iterator last, size_type n, value_type c)
1859 {
1860 // Quick hack, as iterators are pointers.
1861 iterator first_ = to_iterator(first);
1862 iterator last_ = to_iterator(last);
1863
1864 // Erase the bit we want to replace.
1865 erase(first_, last_);
1866
1867 // Insert the new stuff.
1868 insert(first_, n, c);
1869
1870 return *this;
1871 }
1872
1873 //*********************************************************************
1875 //*********************************************************************
1876 template <typename TIterator>
1877 ibasic_string& replace(const_iterator first, const_iterator last, TIterator first_replace, TIterator last_replace)
1878 {
1879 // Quick hack, as iterators are pointers.
1880 iterator first_ = to_iterator(first);
1881 iterator last_ = to_iterator(last);
1882
1883 // Erase the bit we want to replace.
1884 erase(first_, last_);
1885
1886 // Insert the new stuff.
1887 insert(first_, first_replace, last_replace);
1888
1889 return *this;
1890 }
1891
1892 //*************************************************************************
1894 //*************************************************************************
1895 int compare(const ibasic_string& str) const
1896 {
1897 return compare(p_buffer,
1898 p_buffer + size(),
1899 str.p_buffer,
1900 str.p_buffer + str.size());
1901 }
1902
1903 //*************************************************************************
1905 //*************************************************************************
1906 template <typename TOtherTraits>
1908 {
1909 return compare(p_buffer,
1910 p_buffer + size(),
1911 view.data(),
1912 view.data() + view.size());
1913 }
1914
1915 //*************************************************************************
1917 //*************************************************************************
1918 int compare(size_type position, size_type length_, const ibasic_string& str) const
1919 {
1920 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1921
1922 // Limit the length.
1923 length_ = etl::min(length_, size() - position);
1924
1925 return compare(p_buffer + position,
1926 p_buffer + position + length_,
1927 str.p_buffer,
1928 str.p_buffer + str.size());
1929 }
1930
1931 //*************************************************************************
1933 //*************************************************************************
1934 template <typename TOtherTraits>
1935 int compare(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view) const
1936 {
1937 return compare(p_buffer + position,
1938 p_buffer + position + length_,
1939 view.data(),
1940 view.data() + view.size());
1941 }
1942
1943 //*************************************************************************
1945 //*************************************************************************
1946 int compare(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength) const
1947 {
1948 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1949 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1950
1951 // Limit the lengths.
1952 length_ = etl::min(length_, size() - position);
1953 sublength = etl::min(sublength, str.size() - subposition);
1954
1955 return compare(p_buffer + position,
1956 p_buffer + position + length_,
1957 str.p_buffer + subposition,
1958 str.p_buffer + subposition + sublength);
1959 }
1960
1961 //*************************************************************************
1963 //*************************************************************************
1964 template <typename TOtherTraits>
1965 int compare(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition, size_type sublength) const
1966 {
1967 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1968 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1969
1970 // Limit the lengths.
1971 length_ = etl::min(length_, size() - position);
1972 sublength = etl::min(sublength, view.size() - subposition);
1973
1974 return compare(p_buffer + position,
1975 p_buffer + position + length_,
1976 view.data() + subposition,
1977 view.data() + subposition + sublength);
1978 }
1979
1980 //*************************************************************************
1982 //*************************************************************************
1983 int compare(const value_type* s) const
1984 {
1985 return compare(p_buffer,
1986 p_buffer + size(),
1987 s,
1988 s + etl::strlen(s));
1989 }
1990
1991 //*************************************************************************
1993 //*************************************************************************
1994 int compare(size_type position, size_type length_, const_pointer s) const
1995 {
1996 return compare(p_buffer + position,
1997 p_buffer + position + length_,
1998 s,
1999 s + etl::strlen(s));
2000 }
2001
2002 //*************************************************************************
2004 //*************************************************************************
2005 int compare(size_type position, size_type length_, const_pointer s, size_type n) const
2006 {
2007 return compare(p_buffer + position,
2008 p_buffer + position + length_,
2009 s,
2010 s + n);
2011 }
2012
2013 //*********************************************************************
2017 //*********************************************************************
2018 size_type find_first_of(const ibasic_string<T>& str, size_type position = 0) const
2019 {
2020 return find_first_of(str.c_str(), position, str.size());
2021 }
2022
2023 //*********************************************************************
2027 //*********************************************************************
2028 size_type find_first_of(const_pointer s, size_type position = 0) const
2029 {
2030 return find_first_of(s, position, etl::strlen(s));
2031 }
2032
2033 //*********************************************************************
2037 //*********************************************************************
2038 template <typename TOtherTraits>
2039 size_type find_first_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = 0) const
2040 {
2041 return find_first_of(view.data(), position, view.size());
2042 }
2043
2044 //*********************************************************************
2049 //*********************************************************************
2050 size_type find_first_of(const_pointer s, size_type position, size_type n) const
2051 {
2052 if (position < size())
2053 {
2054 for (size_type i = position; i < size(); ++i)
2055 {
2056 for (size_type j = 0; j < n; ++j)
2057 {
2058 if (p_buffer[i] == s[j])
2059 {
2060 return i;
2061 }
2062 }
2063 }
2064 }
2065
2066 return npos;
2067 }
2068
2069 //*********************************************************************
2073 //*********************************************************************
2074 size_type find_first_of(value_type c, size_type position = 0) const
2075 {
2076 if (position < size())
2077 {
2078 for (size_type i = position; i < size(); ++i)
2079 {
2080 if (p_buffer[i] == c)
2081 {
2082 return i;
2083 }
2084 }
2085 }
2086
2087 return npos;
2088 }
2089
2090 //*********************************************************************
2094 //*********************************************************************
2095 size_type find_last_of(const ibasic_string<T>& str, size_type position = npos) const
2096 {
2097 return find_last_of(str.c_str(), position, str.size());
2098 }
2099
2100 //*********************************************************************
2104 //*********************************************************************
2105 size_type find_last_of(const_pointer s, size_type position = npos) const
2106 {
2107 return find_last_of(s, position, etl::strlen(s));
2108 }
2109
2110 //*********************************************************************
2114 //*********************************************************************
2115 template <typename TOtherTraits>
2116 size_type find_last_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = npos) const
2117 {
2118 return find_last_of(view.data(), position, view.size());
2119 }
2120
2121 //*********************************************************************
2126 //*********************************************************************
2127 size_type find_last_of(const_pointer s, size_type position, size_type n) const
2128 {
2129 if (empty())
2130 {
2131 return npos;
2132 }
2133
2134 position = etl::min(position, size() - 1);
2135
2136 const_reverse_iterator it = rbegin() + size() - position - 1;
2137
2138 while (it != rend())
2139 {
2140 for (size_type j = 0; j < n; ++j)
2141 {
2142 if (p_buffer[position] == s[j])
2143 {
2144 return position;
2145 }
2146 }
2147
2148 ++it;
2149 --position;
2150 }
2151
2152 return npos;
2153 }
2154
2155 //*********************************************************************
2159 //*********************************************************************
2160 size_type find_last_of(value_type c, size_type position = npos) const
2161 {
2162 if (empty())
2163 {
2164 return npos;
2165 }
2166
2167 position = etl::min(position, size() - 1);
2168
2169 const_reverse_iterator it = rbegin() + size() - position - 1;
2170
2171 while (it != rend())
2172 {
2173 if (p_buffer[position] == c)
2174 {
2175 return position;
2176 }
2177
2178 ++it;
2179 --position;
2180 }
2181
2182 return npos;
2183 }
2184
2185 //*********************************************************************
2189 //*********************************************************************
2190 size_type find_first_not_of(const ibasic_string<T>& str, size_type position = 0) const
2191 {
2192 return find_first_not_of(str.c_str(), position, str.size());
2193 }
2194
2195 //*********************************************************************
2199 //*********************************************************************
2200 size_type find_first_not_of(const_pointer s, size_type position = 0) const
2201 {
2202 return find_first_not_of(s, position, etl::strlen(s));
2203 }
2204
2205 //*********************************************************************
2209 //*********************************************************************
2210 template <typename TOtherTraits>
2211 size_type find_first_not_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = 0) const
2212 {
2213 return find_first_not_of(view.data(), position, view.size());
2214 }
2215
2216 //*********************************************************************
2221 //*********************************************************************
2222 size_type find_first_not_of(const_pointer s, size_type position, size_type n) const
2223 {
2224 if (position < size())
2225 {
2226 for (size_type i = position; i < size(); ++i)
2227 {
2228 bool found = false;
2229
2230 for (size_type j = 0; j < n; ++j)
2231 {
2232 if (p_buffer[i] == s[j])
2233 {
2234 found = true;
2235 }
2236 }
2237
2238 if (!found)
2239 {
2240 return i;
2241 }
2242 }
2243 }
2244
2245 return npos;
2246 }
2247
2248 //*********************************************************************
2252 //*********************************************************************
2253 size_type find_first_not_of(value_type c, size_type position = 0) const
2254 {
2255 if (position < size())
2256 {
2257 for (size_type i = position; i < size(); ++i)
2258 {
2259 if (*(p_buffer + i) != c)
2260 {
2261 return i;
2262 }
2263 }
2264 }
2265
2266 return npos;
2267 }
2268
2269 //*********************************************************************
2273 //*********************************************************************
2274 size_type find_last_not_of(const ibasic_string<T>& str, size_type position = npos) const
2275 {
2276 return find_last_not_of(str.c_str(), position, str.size());
2277 }
2278
2279 //*********************************************************************
2283 //*********************************************************************
2284 size_type find_last_not_of(const_pointer s, size_type position = npos) const
2285 {
2286 return find_last_not_of(s, position, etl::strlen(s));
2287 }
2288
2289 //*********************************************************************
2293 //*********************************************************************
2294 template <typename TOtherTraits>
2295 size_type find_last_not_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = npos) const
2296 {
2297 return find_last_not_of(view.data(), position, view.size());
2298 }
2299
2300 //*********************************************************************
2305 //*********************************************************************
2306 size_type find_last_not_of(const_pointer s, size_type position, size_type n) const
2307 {
2308 if (empty())
2309 {
2310 return npos;
2311 }
2312
2313 position = etl::min(position, size() - 1);
2314
2315 const_reverse_iterator it = rbegin() + size() - position - 1;
2316
2317 while (it != rend())
2318 {
2319 bool found = false;
2320
2321 for (size_type j = 0; j < n; ++j)
2322 {
2323 if (p_buffer[position] == s[j])
2324 {
2325 found = true;
2326 }
2327 }
2328
2329 if (!found)
2330 {
2331 return position;
2332 }
2333
2334 ++it;
2335 --position;
2336 }
2337
2338 return npos;
2339 }
2340
2341 //*********************************************************************
2342 //
2343 //*********************************************************************
2344 size_type find_last_not_of(value_type c, size_type position = npos) const
2345 {
2346 if (empty())
2347 {
2348 return npos;
2349 }
2350
2351 position = etl::min(position, size() - 1);
2352
2353 const_reverse_iterator it = rbegin() + size() - position - 1;
2354
2355 while (it != rend())
2356 {
2357 if (p_buffer[position] != c)
2358 {
2359 return position;
2360 }
2361
2362 ++it;
2363 --position;
2364 }
2365
2366 return npos;
2367 }
2368
2369 //*************************************************************************
2371 //*************************************************************************
2373 {
2374 if (&rhs != this)
2375 {
2376 assign(rhs);
2377 }
2378
2379 return *this;
2380 }
2381
2382 //*************************************************************************
2384 //*************************************************************************
2385 ibasic_string& operator = (const_pointer rhs)
2386 {
2387 assign(rhs);
2388
2389 return *this;
2390 }
2391
2392 //*************************************************************************
2394 //*************************************************************************
2395 template <typename TOtherTraits>
2397 {
2398 assign(view);
2399
2400 return *this;
2401 }
2402
2403 //*************************************************************************
2405 //*************************************************************************
2407 {
2408 append(rhs);
2409
2410 return *this;
2411 }
2412
2413 //*************************************************************************
2415 //*************************************************************************
2416 template <typename TOtherTraits>
2418 {
2419 append(rhs);
2420
2421 return *this;
2422 }
2423
2424 //*************************************************************************
2426 //*************************************************************************
2427 ibasic_string& operator += (const_pointer rhs)
2428 {
2429 append(rhs);
2430
2431 return *this;
2432 }
2433
2434 //*************************************************************************
2436 //*************************************************************************
2438 {
2439 append(size_type(1), rhs);
2440
2441 return *this;
2442 }
2443
2444#if ETL_HAS_ISTRING_REPAIR
2445 //*************************************************************************
2447 //*************************************************************************
2448 virtual void repair() = 0;
2449#endif
2450
2451 //*********************************************************************
2453 //*********************************************************************
2455 {
2456#if ETL_HAS_STRING_TRUNCATION_CHECKS
2457 set_truncated(false);
2458#endif
2459 etl::mem_set(&p_buffer[current_size], &p_buffer[CAPACITY + 1U], char(0));
2460 }
2461
2462 //*********************************************************************
2466 //*********************************************************************
2468 {
2469#if ETL_HAS_STRING_TRUNCATION_CHECKS
2470 set_truncated(p_buffer[CAPACITY] != T(0));
2471#endif
2472
2473 p_buffer[CAPACITY] = T(0); // Ensure a terminating null.
2474 current_size = etl::strlen(p_buffer);
2475 }
2476
2477 protected:
2478
2479 //*********************************************************************
2481 //*********************************************************************
2482 ibasic_string(T* p_buffer_, size_type MAX_SIZE_)
2483 : string_base(MAX_SIZE_),
2484 p_buffer(p_buffer_)
2485 {
2486 }
2487
2488 //*********************************************************************
2490 //*********************************************************************
2492 {
2493 current_size = 0U;
2494 p_buffer[0] = 0;
2495#if ETL_HAS_STRING_TRUNCATION_CHECKS
2496 set_truncated(false);
2497#endif
2498 }
2499
2500 //*************************************************************************
2502 //*************************************************************************
2503 void repair_buffer(T* p_buffer_)
2504 {
2505 p_buffer = p_buffer_;
2506 }
2507
2508 private:
2509
2510 //*********************************************************************
2514 //*********************************************************************
2515 ibasic_string& replace_impl(const_iterator first, const_iterator last, const_pointer s, size_type length, bool other_truncated)
2516 {
2517 // Trivial no-op cases
2518 if ((first == last) && (s == ETL_NULLPTR || length == 0U))
2519 {
2520 return *this;
2521 }
2522
2523 // Invalid range?
2524 if (first > last)
2525 {
2526 return *this;
2527 }
2528
2529 // Quick hack, as iterators are pointers.
2530 iterator first_ = to_iterator(first);
2531 iterator last_ = to_iterator(last);
2532
2533 // If source pointer is inside our current buffer we take the safe
2534 // (legacy) path to preserve correct semantics for overlapping self use.
2535 const bool source_overlaps = (s != ETL_NULLPTR) &&
2536 (s >= p_buffer) &&
2537 (s < p_buffer + current_size);
2538
2539 if (source_overlaps)
2540 {
2541 // Legacy behaviour (may be slightly less efficient, but correct).
2542 // Erase range then insert up to 'length' characters from 's'.
2543 erase(first_, last_);
2544
2545 if (s != ETL_NULLPTR && length != 0U)
2546 {
2547 // 'insert' can truncate & set flags.
2548 insert(p_buffer + (first_ - p_buffer), s, s + length);
2549 }
2550
2551 return *this;
2552 }
2553
2554 // Calculate the remove parameters.
2555 const size_type remove_index = size_type(first_ - p_buffer);
2556 const size_type remove_length = size_type(last_ - first_);
2557 const size_type free_space = CAPACITY - remove_index; // Free space is the space from the remove index to the end of the buffer.
2558
2559 size_type insert_length = (s == ETL_NULLPTR) ? 0U : length;
2560
2561 // Limit the insert length to the available free space.
2562 if (insert_length > free_space)
2563 {
2564 insert_length = free_space;
2565 }
2566
2567 // Calculate the tail parameters.
2568 size_type tail_index = remove_index + remove_length;
2569 size_type tail_length = current_size - tail_index;
2570 size_type tail_space = free_space - insert_length;
2571
2572#if ETL_HAS_STRING_TRUNCATION_CHECKS
2573 set_truncated((insert_length != length) || (tail_space < tail_length) || is_truncated() || other_truncated);
2574#endif
2575
2576 // The some or all of tail may be erased if the space remaining for it is smaller than the tail length.
2577 if (tail_space < tail_length)
2578 {
2579 tail_length = tail_space;
2580 }
2581
2582 // Three cases: same size, grow, shrink.
2583 if (insert_length == remove_length)
2584 {
2585 // Size unchanged: simple overwrite.
2586 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2587 }
2588 else if (insert_length > remove_length)
2589 {
2590 // Grow: shift tail right then copy.
2591 // Shift tail (backwards to handle overlap safely).
2592 etl::mem_move(&p_buffer[tail_index], tail_length, &p_buffer[remove_index + insert_length]);
2593
2594 // Copy new data.
2595 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2596 }
2597 else // insert_length < remove_length
2598 {
2599 // Shrink: overwrite then shift tail left.
2600 // Copy new data.
2601 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2602
2603 // Move tail left.
2604 etl::mem_copy(&p_buffer[tail_index], tail_length, &p_buffer[remove_index + insert_length]);
2605 }
2606
2607 current_size = remove_index + insert_length + tail_length;
2608 p_buffer[current_size] = value_type(0);
2609
2610 cleanup();
2611
2612 return *this;
2613 }
2614
2615 //*************************************************************************
2617 //*************************************************************************
2618 static int compare(const_pointer first1, const_pointer last1,
2619 const_pointer first2, const_pointer last2)
2620 {
2621 typedef typename etl::make_unsigned<value_type>::type type;
2622
2623 difference_type length1 = etl::distance(first1, last1);
2624 difference_type length2 = etl::distance(first2, last2);
2625 difference_type compare_length = etl::min(length1, length2);
2626
2627 // First compare the string characters.
2628 while (compare_length != 0)
2629 {
2630 if (static_cast<type>(*first1) < static_cast<type>(*first2))
2631 {
2632 // Compared character is lower.
2633 return -1;
2634 }
2635 else if (static_cast<type>(*first1) > static_cast<type>(*first2))
2636 {
2637 // Compared character is higher.
2638 return 1;
2639 }
2640
2641 ++first1;
2642 ++first2;
2643 --compare_length;
2644 }
2645
2646 // Then compare the string lengths.
2647 if (length1 < length2)
2648 {
2649 // First string is shorter.
2650 return -1;
2651 }
2652
2653 if (length1 > length2)
2654 {
2655 // First string is longer.
2656 return 1;
2657 }
2658
2659 // Strings are the same length.
2660 return 0;
2661 }
2662
2663 //*************************************************************************
2665 //*************************************************************************
2666 void cleanup()
2667 {
2668#if ETL_HAS_STRING_CLEAR_AFTER_USE
2669 if (is_secure())
2670 {
2671 etl::memory_clear_range(&p_buffer[current_size], &p_buffer[CAPACITY]);
2672 }
2673#endif
2674 }
2675
2676 //*************************************************************************
2678 //*************************************************************************
2680
2681 //*************************************************************************
2683 //*************************************************************************
2684 T* p_buffer;
2685
2686 //*************************************************************************
2688 //*************************************************************************
2689#if defined(ETL_POLYMORPHIC_STRINGS) || defined(ETL_POLYMORPHIC_CONTAINERS) || defined(ETL_ISTRING_REPAIR_ENABLE)
2690 public:
2691 virtual
2692#else
2693 protected:
2694#endif
2696 {
2697#if ETL_HAS_STRING_CLEAR_AFTER_USE
2698 if (is_secure())
2699 {
2700 clear();
2701 }
2702#endif
2703 }
2704
2705 protected:
2706
2707 //*************************************************************************
2709 //*************************************************************************
2710 iterator to_iterator(const_iterator itr) const
2711 {
2712 return const_cast<iterator>(itr);
2713 }
2714
2715 //*************************************************************************
2717 //*************************************************************************
2718 bool is_within_buffer(const_pointer ptr) const
2719 {
2720 return (ptr >= p_buffer) && (ptr <= (p_buffer + CAPACITY));
2721 }
2722
2723 private:
2724
2725 //*********************************************************************
2728 //*********************************************************************
2729 template <typename TIterator1>
2730 static
2732 copy_characters(TIterator1 from, size_t n, iterator to)
2733 {
2734 etl::mem_move(from, n, to);
2735
2736 return to + n;
2737 }
2738
2739 //*********************************************************************
2742 //*********************************************************************
2743 template <typename TIterator1>
2744 static
2746 copy_characters(TIterator1 from, size_t n, iterator to)
2747 {
2748 size_t count = 0;
2749
2750 while (count != n)
2751 {
2752 *to++ = *from++;
2753 ++count;
2754 }
2755
2756 return to;
2757 }
2758
2759 //*********************************************************************
2761 //*********************************************************************
2762 template <typename TIterator>
2763 void append_impl(iterator position, TIterator first, TIterator last, bool truncated, bool secure)
2764 {
2765 difference_type start = etl::distance(p_buffer, position);
2766 difference_type count = etl::distance(first, last);
2767 difference_type free_space = etl::distance(position, p_buffer + CAPACITY);
2768
2769#if ETL_IS_DEBUG_BUILD
2770 ETL_ASSERT(count >= 0, ETL_ERROR(string_iterator));
2771#endif
2772
2773#if ETL_HAS_STRING_TRUNCATION_CHECKS
2774 set_truncated((count > free_space) || this->is_truncated() || truncated);
2775
2776#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2777 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
2778#endif
2779#else
2780 (void)truncated;
2781#endif
2782
2783#if ETL_HAS_STRING_CLEAR_AFTER_USE
2784 if (secure)
2785 {
2786 set_secure();
2787 }
2788#else
2789 (void)secure;
2790#endif
2791
2792 // Limit the actual distance to the capacity.
2793 count = etl::min(count, free_space);
2794 copy_characters(first, size_t(count), position);
2795 current_size = size_t(start + count);
2796 p_buffer[current_size] = 0;
2797
2798 cleanup();
2799 }
2800
2801 //*********************************************************************
2803 //*********************************************************************
2804 void append_impl(iterator position, const_pointer src, bool truncated, bool secure)
2805 {
2806 if (src == ETL_NULLPTR)
2807 {
2808 clear();
2809 return;
2810 }
2811
2812 difference_type start = etl::distance(p_buffer, position);
2813 difference_type free_space = etl::distance(position, p_buffer + CAPACITY);
2814
2815 pointer dst = position;
2816 size_t length = get_string_length(src);
2817 size_t count = (length < size_t(free_space)) ? length : size_t(free_space);
2818 etl::mem_move(src, count, dst);
2819
2820 truncated |= (src[count] != 0);
2821 current_size = size_t(start) + count;
2822 p_buffer[current_size] = 0;
2823
2824#if ETL_HAS_STRING_TRUNCATION_CHECKS
2826#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2827 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
2828#endif
2829#else
2830 (void)truncated;
2831#endif
2832
2833#if ETL_HAS_STRING_CLEAR_AFTER_USE
2834 if (secure)
2835 {
2836 set_secure();
2837 }
2838#else
2839 (void)secure;
2840#endif
2841
2842 cleanup();
2843 }
2844
2845 //*************************************************************************
2847 //*************************************************************************
2848 template <typename TIterator>
2849 size_type find_impl(TIterator first, TIterator last, size_type sz, size_type pos = 0) const
2850 {
2851 if ((pos + sz) > size())
2852 {
2853 return npos;
2854 }
2855
2856 const_iterator iposition = etl::search(begin() + pos, end(), first, last);
2857
2858 if (iposition == end())
2859 {
2860 return npos;
2861 }
2862 else
2863 {
2864 return etl::distance(begin(), iposition);
2865 }
2866 }
2867
2868 //*************************************************************************
2870 //*************************************************************************
2871 template <typename TIterator>
2872 size_type rfind_impl(TIterator rfirst, TIterator rlast, size_type sz, size_type pos = 0) const
2873 {
2874 if (sz > size())
2875 {
2876 return npos;
2877 }
2878
2879 if (pos >= size())
2880 {
2881 pos = size();
2882 }
2883
2884 pos = size() - pos;
2885
2886 const_reverse_iterator iposition = etl::search(rbegin() + pos, rend(), rfirst, rlast);
2887
2888 if (iposition == rend())
2889 {
2890 return npos;
2891 }
2892 else
2893 {
2894 return size() - sz - etl::distance(rbegin(), iposition);
2895 }
2896 }
2897
2898 //*********************************************************************
2900 //*********************************************************************
2901 template <typename U>
2902 static
2903 typename etl::enable_if<sizeof(U) == sizeof(char), size_t>::type
2904 get_string_length(const U* str)
2905 {
2906 return ::strlen(reinterpret_cast<const char*>(str));
2907 }
2908
2909#if ETL_USING_LIBC_WCHAR_H
2910 //*********************************************************************
2912 //*********************************************************************
2913 template <typename U>
2914 static
2915 typename etl::enable_if<sizeof(U) == sizeof(wchar_t), size_t>::type
2916 get_string_length(const U* str)
2917 {
2918 return ::wcslen(reinterpret_cast<const wchar_t*>(str));
2919 }
2920#endif
2921
2922 //*********************************************************************
2924 //*********************************************************************
2925 template <typename U>
2926 static
2927#if ETL_USING_LIBC_WCHAR_H
2928 typename etl::enable_if<(sizeof(U) != sizeof(char)) && (sizeof(U) != sizeof(wchar_t)), size_t>::type
2929#else
2930 typename etl::enable_if<(sizeof(U) != sizeof(char)), size_t>::type
2931#endif
2932 get_string_length(const U* str)
2933 {
2934 if (str == ETL_NULLPTR)
2935 {
2936 return 0;
2937 }
2938
2939 const U* end = str;
2940
2941 while (*end++ != 0)
2942 {
2943 // Do nothing.
2944 }
2945
2946 return size_t(end - str) - 1;
2947 }
2948 };
2949
2950 //***************************************************************************
2956 //***************************************************************************
2957 template <typename T>
2959 {
2960 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
2961 }
2962
2963 //***************************************************************************
2969 //***************************************************************************
2970 template <typename T>
2971 bool operator ==(const etl::ibasic_string<T>& lhs, const T* rhs)
2972 {
2973 return (lhs.size() == etl::strlen(rhs)) && etl::equal(lhs.begin(), lhs.end(), rhs);
2974 }
2975
2976 //***************************************************************************
2982 //***************************************************************************
2983 template <typename T>
2984 bool operator ==(const T* lhs, const etl::ibasic_string<T>& rhs)
2985 {
2986 return (rhs.size() == etl::strlen(lhs)) && etl::equal(rhs.begin(), rhs.end(), lhs);
2987 }
2988
2989 //***************************************************************************
2995 //***************************************************************************
2996 template <typename T>
2998 {
2999 return !(lhs == rhs);
3000 }
3001
3002 //***************************************************************************
3008 //***************************************************************************
3009 template <typename T>
3010 bool operator !=(const etl::ibasic_string<T>& lhs, const T* rhs)
3011 {
3012 return !(lhs == rhs);
3013 }
3014
3015 //***************************************************************************
3021 //***************************************************************************
3022 template <typename T>
3023 bool operator !=(const T* lhs, const etl::ibasic_string<T>& rhs)
3024 {
3025 return !(lhs == rhs);
3026 }
3027
3028 //***************************************************************************
3034 //***************************************************************************
3035 template <typename T>
3037 {
3038 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
3039 }
3040
3041 //***************************************************************************
3047 //***************************************************************************
3048 template <typename T>
3049 bool operator <(const etl::ibasic_string<T>& lhs, const T* rhs)
3050 {
3051 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs, rhs + etl::strlen(rhs));
3052 }
3053
3054 //***************************************************************************
3060 //***************************************************************************
3061 template <typename T>
3062 bool operator <(const T* lhs, const etl::ibasic_string<T>& rhs)
3063 {
3064 return etl::lexicographical_compare(lhs, lhs + etl::strlen(lhs), rhs.begin(), rhs.end());
3065 }
3066
3067
3068 //***************************************************************************
3074 //***************************************************************************
3075 template <typename T>
3077 {
3078 return (rhs < lhs);
3079 }
3080
3081 //***************************************************************************
3087 //***************************************************************************
3088 template <typename T>
3089 bool operator >(const etl::ibasic_string<T>& lhs, const T* rhs)
3090 {
3091 return (rhs < lhs);
3092 }
3093
3094 //***************************************************************************
3100 //***************************************************************************
3101 template <typename T>
3102 bool operator >(const T* lhs, const etl::ibasic_string<T>& rhs)
3103 {
3104 return (rhs < lhs);
3105 }
3106
3107
3108 //***************************************************************************
3114 //***************************************************************************
3115 template <typename T>
3117 {
3118 return !(lhs > rhs);
3119 }
3120
3121 //***************************************************************************
3127 //***************************************************************************
3128 template <typename T>
3129 bool operator <=(const etl::ibasic_string<T>& lhs, const T* rhs)
3130 {
3131 return !(lhs > rhs);
3132 }
3133
3134 //***************************************************************************
3140 //***************************************************************************
3141 template <typename T>
3142 bool operator <=(const T* lhs, const etl::ibasic_string<T>& rhs)
3143 {
3144 return !(lhs > rhs);
3145 }
3146
3147
3148 //***************************************************************************
3154 //***************************************************************************
3155 template <typename T>
3157 {
3158 return !(lhs < rhs);
3159 }
3160
3161 //***************************************************************************
3167 //***************************************************************************
3168 template <typename T>
3169 bool operator >=(const etl::ibasic_string<T>& lhs, const T* rhs)
3170 {
3171 return !(lhs < rhs);
3172 }
3173
3174 //***************************************************************************
3180 //***************************************************************************
3181 template <typename T>
3182 bool operator >=(const T* lhs, const etl::ibasic_string<T>& rhs)
3183 {
3184 return !(lhs < rhs);
3185 }
3186
3187 //***************************************************************************
3193 //***************************************************************************
3194#if ETL_USING_STD_OSTREAM
3195 template <typename T>
3196 std::basic_ostream<T, std::char_traits<T> > &operator<<(std::basic_ostream<T, std::char_traits<T> > &os,
3197 const etl::ibasic_string<T>& str)
3198 {
3199 os.write(str.data(), str.size());
3200 return os;
3201 }
3202#endif
3203}
3204
3205#undef ETL_USING_WCHAR_T_H
3206
3207#include "private/minmax_pop.h"
3208
3209#endif
String view.
Definition string_view.h:104
ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:212
ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the array.
Definition string_view.h:280
ETL_CONSTEXPR const_reverse_iterator rend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the array.
Definition string_view.h:252
ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
Returns a const pointer to the first element of the internal storage.
Definition string_view.h:196
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:220
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:204
ETL_CONSTEXPR const_reverse_iterator rbegin() const ETL_NOEXCEPT
Returns a const reverse iterator to the reverse beginning of the array.
Definition string_view.h:236
Definition flags.h:53
Definition basic_string.h:351
int compare(size_type position, size_type length_, const ibasic_string &str) const
Compare position / length with string.
Definition basic_string.h:1918
ibasic_string & append(TIterator first, TIterator last)
Definition basic_string.h:866
size_type find_last_of(const_pointer s, size_type position=npos) const
Definition basic_string.h:2105
size_type rfind(const_pointer s, size_type position=npos) const
Definition basic_string.h:1523
ibasic_string & replace(const_iterator first, const_iterator last, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1741
etl::enable_if< etl::is_same< TIterator, const_pointer >::value, ibasic_string >::type & replace(const_iterator first, const_iterator last, TIterator s)
Replace characters from 'first' to 'last' with pointed to string.
Definition basic_string.h:1809
etl::ibasic_string< T > & insert(size_type position, const etl::ibasic_string< T > &str)
Definition basic_string.h:1183
ibasic_string & replace(const_iterator first, const_iterator last, const value_type(&literal)[Size])
Replace characters from 'first' 'last' with pointed to literal string.
Definition basic_string.h:1818
size_type find_last_not_of(const_pointer s, size_type position=npos) const
Definition basic_string.h:2284
size_type find(const_pointer s, size_type pos=0) const
Definition basic_string.h:1458
ibasic_string & operator=(const ibasic_string &rhs)
Assignment operator.
Definition basic_string.h:2372
ibasic_string & append(const ibasic_string &str, size_type subposition, size_type sublength=npos)
Definition basic_string.h:846
const_reverse_iterator rbegin() const
Definition basic_string.h:435
bool contains(const etl::ibasic_string< T > &str) const
Checks that the string is within this string.
Definition basic_string.h:1575
reference operator[](size_type i)
Definition basic_string.h:561
void assign(const etl::ibasic_string< T > &other, size_type subposition, size_type sublength)
Definition basic_string.h:699
etl::ibasic_string< T > & insert(size_type position, const etl::basic_string_view< T, TOtherTraits > &view, size_type subposition, size_type sublength)
Definition basic_string.h:1259
pointer data_end()
Definition basic_string.h:664
iterator erase(const_iterator first, const_iterator last)
Definition basic_string.h:1373
iterator insert(const_iterator position, TIterator first, TIterator last)
Definition basic_string.h:1082
bool is_within_buffer(const_pointer ptr) const
Checks if a pointer is within the buffer.
Definition basic_string.h:2718
bool contains(value_type c) const
Checks that character is within this string.
Definition basic_string.h:1600
size_type find_last_of(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:2095
size_type find_first_of(value_type c, size_type position=0) const
Definition basic_string.h:2074
bool starts_with(const etl::ibasic_string< T > &str) const
Checks that the string is the start of this string.
Definition basic_string.h:1608
size_type find(T c, size_type position=0) const
Definition basic_string.h:1483
ibasic_string & replace(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view, size_type subposition, size_type sublength)
Replace characters from 'position' of 'length' with 'view' from 'subposition' of 'sublength'.
Definition basic_string.h:1765
bool ends_with(value_type c) const
Checks that the character is the end of this string.
Definition basic_string.h:1685
void pop_back()
Definition basic_string.h:821
size_type rfind(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:1502
bool contains(const_pointer s) const
Checks that text is within this string.
Definition basic_string.h:1592
etl::ibasic_string< T > & insert(size_type position, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1209
void resize_and_overwrite(size_type new_size, TOperation operation)
Resizes the string and overwrites to data using the operation.
Definition basic_string.h:521
void initialize_free_space()
Clears the free space to string terminator value.
Definition basic_string.h:2454
ibasic_string & replace(size_type position, size_type length_, const_pointer s, size_type n)
Replace characters from 'position' of 'length' with 'n' characters from pointed to string.
Definition basic_string.h:1826
iterator to_iterator(const_iterator itr) const
Convert from const_iterator to iterator.
Definition basic_string.h:2710
ibasic_string & replace(size_type position, size_type length_, size_type n, value_type c)
Replace characters from 'position' of 'length' with 'n' copies of 'c'.
Definition basic_string.h:1839
ibasic_string & replace(const_iterator first, const_iterator last, const ibasic_string &str)
Definition basic_string.h:1729
size_type find_first_of(const ibasic_string< T > &str, size_type position=0) const
Definition basic_string.h:2018
size_type find_first_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=0) const
Definition basic_string.h:2039
const_reference back() const
Definition basic_string.h:636
void assign(const_pointer str, size_type n)
Definition basic_string.h:745
const_iterator begin() const
Definition basic_string.h:381
size_type find_last_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2127
bool ends_with(const etl::basic_string_view< T, TOtherTraits > &view) const
Checks that the view is the end of this string.
Definition basic_string.h:1657
reverse_iterator rbegin()
Definition basic_string.h:426
ibasic_string & replace(const_iterator first, const_iterator last, TIterator first_replace, TIterator last_replace)
Replace characters from 'first' of 'last' with characters from 'first_replace' to 'last_replace'.
Definition basic_string.h:1877
void resize(size_type new_size)
Definition basic_string.h:481
size_type find_last_not_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2306
ibasic_string & replace(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1713
size_type find_first_not_of(const_pointer s, size_type position=0) const
Definition basic_string.h:2200
size_type rfind(T c, size_type position=npos) const
Definition basic_string.h:1551
etl::ibasic_string< T > & erase(size_type position, size_type length_=npos)
Definition basic_string.h:1321
int compare(const value_type *s) const
Compare with C string.
Definition basic_string.h:1983
int compare(size_type position, size_type length_, const_pointer s) const
Compare position / length with C string.
Definition basic_string.h:1994
iterator insert(const_iterator position, size_type n, T value)
Definition basic_string.h:993
ibasic_string & append(const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:901
const_reference at(size_type i) const
Definition basic_string.h:596
void assign(const etl::basic_string_view< T, TOtherTraits > &view)
Assigns values to the string from a view.
Definition basic_string.h:754
void clear()
Clears the string.
Definition basic_string.h:787
int compare(size_type position, size_type length_, const ibasic_string &str, size_type subposition, size_type sublength) const
Compare position / length with string / subposition / sublength.
Definition basic_string.h:1946
reverse_iterator rend()
Definition basic_string.h:444
size_type find_last_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=npos) const
Definition basic_string.h:2116
iterator erase(iterator i_element)
Definition basic_string.h:1338
ibasic_string & append(const_pointer str, size_type n)
Definition basic_string.h:889
const_reverse_iterator crend() const
Definition basic_string.h:471
bool contains(const etl::basic_string_view< T, TOtherTraits > &view) const
Checks that the view is within this string.
Definition basic_string.h:1584
reference at(size_type i)
Definition basic_string.h:584
size_type rfind(const etl::basic_string_view< T, TOtherTraits > &view, size_type pos=0) const
Definition basic_string.h:1513
bool starts_with(value_type c) const
Checks that the character is the start of this string.
Definition basic_string.h:1635
int compare(const etl::basic_string_view< T, TOtherTraits > &view) const
Compare with etl::basic_string_view.
Definition basic_string.h:1907
~ibasic_string()
Destructor.
Definition basic_string.h:2695
size_type find(const_pointer s, size_type pos, size_type n) const
Definition basic_string.h:1471
size_type find_first_of(const_pointer s, size_type position=0) const
Definition basic_string.h:2028
ibasic_string & replace(size_type position, size_type length_, const ibasic_string &str, size_type subposition, size_type sublength)
Replace characters from 'position' of 'length' with 'str' from 'subposition' of 'sublength'.
Definition basic_string.h:1749
iterator begin()
Definition basic_string.h:372
iterator end()
Definition basic_string.h:390
ibasic_string & replace(const_iterator first, const_iterator last, size_type n, value_type c)
Replace characters from 'first' of 'last' with 'n' copies of 'c'.
Definition basic_string.h:1858
ibasic_string & replace(const_iterator first, const_iterator last, const_pointer s, size_type n)
Definition basic_string.h:1799
void assign(TIterator first, TIterator last)
Definition basic_string.h:724
etl::ibasic_string< T > & insert(size_type position, const etl::ibasic_string< T > &str, size_type subposition, size_type sublength)
Definition basic_string.h:1225
size_type find(const ibasic_string< T > &str, size_type pos=0) const
Definition basic_string.h:1437
void push_back(T value)
Definition basic_string.h:798
size_type find_first_not_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2222
const_reverse_iterator crbegin() const
Definition basic_string.h:462
iterator insert(const_iterator position, T value)
Definition basic_string.h:939
etl::ibasic_string< T > & insert(size_type position, const_pointer s, size_type n)
Definition basic_string.h:1293
ibasic_string & replace(size_type position, size_type length_, const ibasic_string &str)
Definition basic_string.h:1696
ibasic_string(T *p_buffer_, size_type MAX_SIZE_)
Constructor.
Definition basic_string.h:2482
bool ends_with(const_pointer s) const
Checks that the string is the end of this string.
Definition basic_string.h:1670
etl::ibasic_string< T > & insert(size_type position, size_type n, value_type c)
Definition basic_string.h:1307
const_reverse_iterator rend() const
Definition basic_string.h:453
size_type find_last_not_of(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:2274
size_type find(const etl::basic_string_view< T, TOtherTraits > &view, size_type pos=0) const
Definition basic_string.h:1448
const_pointer data_end() const
Definition basic_string.h:673
void assign(const etl::ibasic_string< T > &other)
Definition basic_string.h:683
const_iterator cend() const
Definition basic_string.h:417
const_pointer c_str() const
Return a pointer to a C string.
Definition basic_string.h:1398
void resize(size_type new_size, T value)
Definition basic_string.h:491
ETL_CONSTEXPR const_pointer data() const
Definition basic_string.h:655
const_reference front() const
Definition basic_string.h:616
pointer data()
Definition basic_string.h:646
size_type find_first_not_of(value_type c, size_type position=0) const
Definition basic_string.h:2253
ibasic_string & append(const_pointer str)
Definition basic_string.h:877
ibasic_string & append(size_type n, T c)
Definition basic_string.h:913
size_type find_first_not_of(const ibasic_string< T > &str, size_type position=0) const
Definition basic_string.h:2190
size_type find_last_of(value_type c, size_type position=npos) const
Definition basic_string.h:2160
size_type copy(pointer dest, size_type count, size_type pos=0) const
Definition basic_string.h:1409
ibasic_string & append(const ibasic_string &str)
Definition basic_string.h:833
size_type find_last_not_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=npos) const
Definition basic_string.h:2295
ibasic_string & replace(size_type position, size_type length_, const_pointer s)
Replace characters from 'position' of 'length' with pointed to string.
Definition basic_string.h:1780
reference front()
Definition basic_string.h:606
reference back()
Definition basic_string.h:626
bool starts_with(const_pointer s) const
Checks that the string is the start of this string.
Definition basic_string.h:1625
const_iterator cbegin() const
Definition basic_string.h:408
size_type find_first_not_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=0) const
Definition basic_string.h:2211
int compare(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view, size_type subposition, size_type sublength) const
Compare position / length with etl::basic_string_view. / subposition / sublength.
Definition basic_string.h:1965
void assign(size_type n, T c)
Definition basic_string.h:765
void initialise()
Initialise the string.
Definition basic_string.h:2491
bool starts_with(const etl::basic_string_view< T, TOtherTraits > &view) const
Checks that the view is the start of this string.
Definition basic_string.h:1617
ibasic_string & operator+=(const ibasic_string &rhs)
+= operator.
Definition basic_string.h:2406
void trim_to_terminator()
Definition basic_string.h:2467
void uninitialized_resize(size_type new_size)
Definition basic_string.h:538
int compare(size_type position, size_type length_, const_pointer s, size_type n) const
Compare position / length with C string / n.
Definition basic_string.h:2005
size_type rfind(const_pointer s, size_type position, size_type length_) const
Definition basic_string.h:1538
bool ends_with(const etl::ibasic_string< T > &str) const
Checks that the string is the end of this string.
Definition basic_string.h:1643
size_type find_first_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2050
int compare(const ibasic_string &str) const
Compare with string.
Definition basic_string.h:1895
const_iterator end() const
Definition basic_string.h:399
iterator erase(const_iterator i_element)
Definition basic_string.h:1353
int compare(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view) const
Compare position / length with etl::basic_string_view.
Definition basic_string.h:1935
etl::ibasic_string< T > & insert(size_type position, const_pointer s)
Definition basic_string.h:1279
void assign(const_pointer str)
Definition basic_string.h:734
void fill(T value)
Definition basic_string.h:551
void repair_buffer(T *p_buffer_)
Fix the internal pointers after a low level memory copy.
Definition basic_string.h:2503
iterator insert(const_iterator position, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1173
Definition basic_string.h:184
void set_secure()
Sets the 'secure' flag to the requested state.
Definition basic_string.h:290
bool is_secure() const
Gets the 'secure' state flag.
Definition basic_string.h:299
const size_type CAPACITY
The maximum number of elements in the string.
Definition basic_string.h:337
bool full() const
Definition basic_string.h:220
~string_base()
Destructor.
Definition basic_string.h:332
ETL_DEPRECATED bool truncated() const
Definition basic_string.h:271
void set_truncated(bool status)
Sets the 'truncated' flag.
Definition basic_string.h:323
size_type max_size() const
Definition basic_string.h:238
string_base(size_type max_size_)
Constructor.
Definition basic_string.h:313
void clear_truncated()
Clears the 'truncated' flag.
Definition basic_string.h:280
size_type length() const
Definition basic_string.h:202
size_type current_size
The current number of elements in the string.
Definition basic_string.h:336
size_type available() const
Definition basic_string.h:247
bool empty() const
Definition basic_string.h:211
size_type capacity() const
Definition basic_string.h:229
bool is_truncated() const
Definition basic_string.h:256
size_type size() const
Definition basic_string.h:193
Definition basic_string.h:87
Definition basic_string.h:129
Definition basic_string.h:115
Definition basic_string.h:143
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
Definition exception.h:47
Definition integral_limits.h:516
void memory_clear_range(volatile T *begin, size_t n)
Definition memory.h:2018
enable_if
Definition type_traits_generator.h:1254
is_pointer
Definition type_traits_generator.h:1164
remove_pointer
Definition type_traits_generator.h:951
Definition basic_string.h:157
bitset_ext
Definition absolute.h:39
T * mem_move(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2339
std::basic_ostream< T, std::char_traits< T > > & operator<<(std::basic_ostream< T, std::char_traits< T > > &os, const etl::ibasic_string< T > &str)
Definition basic_string.h:3196
etl::enable_if< etl::is_pointer< TPointer >::value &&!etl::is_const< TPointer >::value &&etl::is_integral< T >::value &&sizeof(T)==1, TPointer >::type mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
Definition memory.h:2445
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1190
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1202
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
T * mem_copy(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2289
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:287
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1163
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1178
iterator
Definition iterator.h:399