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 "alignment.h"
37#include "array.h"
38#include "binary.h"
39#include "error_handler.h"
40#include "exception.h"
41#include "flags.h"
42#include "functional.h"
43#include "integral_limits.h"
44#include "iterator.h"
45#include "memory.h"
46#include "string_utilities.h"
47#include "type_traits.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 } // namespace private_basic_string
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 size_type current_size;
335 const size_type CAPACITY;
336
337#if ETL_HAS_STRING_TRUNCATION_CHECKS || ETL_HAS_STRING_CLEAR_AFTER_USE
339#endif
340 };
341
342 //***************************************************************************
347 //***************************************************************************
348 template <typename T>
350 {
351 public:
352
353 typedef ibasic_string<T> interface_type;
354
355 typedef T value_type;
356 typedef T& reference;
357 typedef const T& const_reference;
358 typedef T* pointer;
359 typedef const T* const_pointer;
360 typedef T* iterator;
361 typedef const T* const_iterator;
362 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
363 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
364
365 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
366
367 //*********************************************************************
370 //*********************************************************************
371 iterator begin()
372 {
373 return &p_buffer[0];
374 }
375
376 //*********************************************************************
379 //*********************************************************************
380 const_iterator begin() const
381 {
382 return &p_buffer[0];
383 }
384
385 //*********************************************************************
388 //*********************************************************************
389 iterator end()
390 {
391 return &p_buffer[current_size];
392 }
393
394 //*********************************************************************
397 //*********************************************************************
398 const_iterator end() const
399 {
400 return &p_buffer[current_size];
401 }
402
403 //*********************************************************************
406 //*********************************************************************
407 const_iterator cbegin() const
408 {
409 return &p_buffer[0];
410 }
411
412 //*********************************************************************
415 //*********************************************************************
416 const_iterator cend() const
417 {
418 return &p_buffer[current_size];
419 }
420
421 //*********************************************************************
424 //*********************************************************************
425 reverse_iterator rbegin()
426 {
427 return reverse_iterator(end());
428 }
429
430 //*********************************************************************
433 //*********************************************************************
434 const_reverse_iterator rbegin() const
435 {
436 return const_reverse_iterator(end());
437 }
438
439 //*********************************************************************
442 //*********************************************************************
443 reverse_iterator rend()
444 {
445 return reverse_iterator(begin());
446 }
447
448 //*********************************************************************
451 //*********************************************************************
452 const_reverse_iterator rend() const
453 {
454 return const_reverse_iterator(begin());
455 }
456
457 //*********************************************************************
460 //*********************************************************************
461 const_reverse_iterator crbegin() const
462 {
463 return const_reverse_iterator(cend());
464 }
465
466 //*********************************************************************
469 //*********************************************************************
470 const_reverse_iterator crend() const
471 {
472 return const_reverse_iterator(cbegin());
473 }
474
475 //*********************************************************************
479 //*********************************************************************
480 void resize(size_type new_size)
481 {
482 resize(new_size, 0);
483 }
484
485 //*********************************************************************
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 //*********************************************************************
584 //*********************************************************************
585 reference at(size_type i)
586 {
587 ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds));
588 return p_buffer[i];
589 }
590
591 //*********************************************************************
597 //*********************************************************************
598 const_reference at(size_type i) const
599 {
600 ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds));
601 return p_buffer[i];
602 }
603
604 //*********************************************************************
607 //*********************************************************************
608 reference front()
609 {
610 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
611 return p_buffer[0];
612 }
613
614 //*********************************************************************
617 //*********************************************************************
618 const_reference front() const
619 {
620 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
621 return p_buffer[0];
622 }
623
624 //*********************************************************************
627 //*********************************************************************
628 reference back()
629 {
630 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
631 return p_buffer[size() - 1];
632 }
633
634 //*********************************************************************
637 //*********************************************************************
638 const_reference back() const
639 {
640 ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
641 return p_buffer[size() - 1];
642 }
643
644 //*********************************************************************
647 //*********************************************************************
648 pointer data()
649 {
650 return p_buffer;
651 }
652
653 //*********************************************************************
656 //*********************************************************************
657 ETL_CONSTEXPR const_pointer data() const
658 {
659 return p_buffer;
660 }
661
662 //*********************************************************************
665 //*********************************************************************
666 pointer data_end()
667 {
668 return p_buffer + current_size;
669 }
670
671 //*********************************************************************
674 //*********************************************************************
675 const_pointer data_end() const
676 {
677 return p_buffer + current_size;
678 }
679
680 //*********************************************************************
684 //*********************************************************************
685 void assign(const etl::ibasic_string<T>& other)
686 {
687 if (&other != this)
688 {
689 clear();
690 append_impl(begin(), other.begin(), other.end(), other.is_truncated(), other.is_secure());
691 }
692 }
693
694 //*********************************************************************
700 //*********************************************************************
701 void assign(const etl::ibasic_string<T>& other, size_type subposition, size_type sublength)
702 {
703 if (&other != this)
704 {
705 clear();
706
707 if (sublength == npos)
708 {
709 sublength = other.size() - subposition;
710 }
711
712 ETL_ASSERT(subposition <= other.size(), ETL_ERROR(string_out_of_bounds));
713
714 append_impl(begin(), other.begin() + subposition, other.begin() + subposition + sublength, other.is_truncated(), other.is_secure());
715 }
716 }
717
718 //*********************************************************************
725 //*********************************************************************
726 template <typename TIterator>
727 void assign(TIterator first, TIterator last)
728 {
729 append_impl(begin(), first, last, false, false);
730 }
731
732 //*********************************************************************
736 //*********************************************************************
737 void assign(const_pointer str)
738 {
739 append_impl(begin(), str, false, false);
740 }
741
742 //*********************************************************************
747 //*********************************************************************
748 void assign(const_pointer str, size_type n)
749 {
750 append_impl(begin(), str, str + n, false, false);
751 }
752
753 //*********************************************************************
755 //*********************************************************************
756 template <typename TOtherTraits>
758 {
759 append_impl(begin(), view.begin(), view.end(), false, false);
760 }
761
762 //*********************************************************************
767 //*********************************************************************
768 void assign(size_type n, T c)
769 {
770 clear();
771
772#if ETL_HAS_STRING_TRUNCATION_CHECKS
774
775 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
776 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
777 #endif
778#endif
779
780 n = etl::min(n, CAPACITY);
781
782 etl::fill_n(begin(), n, c);
783 current_size = n;
784 p_buffer[current_size] = 0;
785 }
786
787 //*************************************************************************
789 //*************************************************************************
790 void clear()
791 {
792 initialise();
793 cleanup();
794 }
795
796 //*********************************************************************
800 //*********************************************************************
801 void push_back(T value)
802 {
803 if (current_size != CAPACITY)
804 {
805 p_buffer[current_size++] = value;
806 p_buffer[current_size] = 0;
807 }
808 else
809 {
810#if ETL_HAS_STRING_TRUNCATION_CHECKS
811 set_truncated(true);
812
813 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
814 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
815 #endif
816#endif
817 }
818 }
819
820 //*************************************************************************
823 //*************************************************************************
824 void pop_back()
825 {
826 if (current_size != 0)
827 {
828 p_buffer[--current_size] = 0;
829 }
830 }
831
832 //*********************************************************************
835 //*********************************************************************
837 {
838 append_impl(end(), str.begin(), str.end(), str.is_truncated(), str.is_secure());
839
840 return *this;
841 }
842
843 //*********************************************************************
848 //*********************************************************************
849 ibasic_string& append(const ibasic_string& str, size_type subposition, size_type sublength = npos)
850 {
851 if (sublength == npos)
852 {
853 sublength = str.size() - subposition;
854 }
855
856 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
857
858 append_impl(end(), str.begin() + subposition, str.begin() + subposition + sublength, str.is_truncated(), str.is_secure());
859
860 return *this;
861 }
862
863 //*********************************************************************
867 //*********************************************************************
868 template <class TIterator>
869 ibasic_string& append(TIterator first, TIterator last)
870 {
871 append_impl(end(), first, last, false, false);
872
873 return *this;
874 }
875
876 //*********************************************************************
879 //*********************************************************************
880 ibasic_string& append(const_pointer str)
881 {
882 append_impl(end(), str, false, false);
883
884 return *this;
885 }
886
887 //*********************************************************************
891 //*********************************************************************
892 ibasic_string& append(const_pointer str, size_type n)
893 {
894 append_impl(end(), str, str + n, false, false);
895
896 return *this;
897 }
898
899 //*********************************************************************
902 //*********************************************************************
903 template <typename TOtherTraits>
905 {
906 append_impl(end(), view.begin(), view.end(), false, false);
907
908 return *this;
909 }
910
911 //*********************************************************************
915 //*********************************************************************
916 ibasic_string& append(size_type n, T c)
917 {
918 size_type free_space = CAPACITY - current_size;
919
920#if ETL_HAS_STRING_TRUNCATION_CHECKS
921 set_truncated(n > free_space);
922
923 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
924 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
925 #endif
926#endif
927
928 n = etl::min(n, size_t(free_space));
929
930 etl::fill_n(end(), n, c);
931 current_size += n;
932 p_buffer[current_size] = 0;
933
934 return *this;
935 }
936
937 //*********************************************************************
941 //*********************************************************************
942 iterator insert(const_iterator position, T value)
943 {
944 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
945
946 // Quick hack, as iterators are pointers.
947 iterator insert_position = to_iterator(position);
948
950 {
951 // Not full yet.
952 if (position != end())
953 {
954 // Insert in the middle.
955 ++current_size;
956 etl::mem_move(insert_position, end() - 1, insert_position + 1);
957 *insert_position = value;
958 }
959 else
960 {
961 // Insert at the end.
962 *insert_position = value;
963 ++current_size;
964 }
965 }
966 else
967 {
968 // Already full.
969 if (position != end())
970 {
971 // Insert in the middle.
972 etl::mem_move(insert_position, end() - 1, insert_position + 1);
973 *insert_position = value;
974 }
975
976#if ETL_HAS_STRING_TRUNCATION_CHECKS
977 set_truncated(true);
978
979 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
980 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
981 #endif
982#endif
983 }
984
985 p_buffer[current_size] = 0;
986
987 return insert_position;
988 }
989
990 //*********************************************************************
995 //*********************************************************************
996 iterator insert(const_iterator position, size_type n, T value)
997 {
998 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
999
1000 iterator position_ = to_iterator(position);
1001
1002 if (n == 0)
1003 {
1004 return position_;
1005 }
1006
1007 // Quick hack, as iterators are pointers.
1008 iterator insert_position = to_iterator(position);
1009 const size_type start = static_cast<size_type>(etl::distance(cbegin(), position));
1010
1011 // No effect.
1012 if (start >= CAPACITY)
1013 {
1014#if ETL_HAS_STRING_TRUNCATION_CHECKS
1015 set_truncated(true);
1016
1017 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1018 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1019 #endif
1020#endif
1021 return to_iterator(position);
1022 }
1023
1024 // Fills the string to the end?
1025 if ((start + n) >= CAPACITY)
1026 {
1027 if ((current_size + n) > CAPACITY)
1028 {
1029#if ETL_HAS_STRING_TRUNCATION_CHECKS
1030 set_truncated(true);
1031
1032 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1033 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1034 #endif
1035#endif
1036 }
1037
1039 etl::fill(insert_position, end(), value);
1040 }
1041 else
1042 {
1043 // Lets do some shifting.
1044 const size_type shift_amount = n;
1045 const size_type to_position = start + shift_amount;
1046 const size_type remaining_characters = current_size - start;
1047 const size_type max_shift_characters = CAPACITY - start - shift_amount;
1048 const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters);
1049
1050 // Will the string truncate?
1051 if ((start + shift_amount + remaining_characters) > CAPACITY)
1052 {
1054
1055#if ETL_HAS_STRING_TRUNCATION_CHECKS
1056 set_truncated(true);
1057
1058 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1059 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1060 #endif
1061#endif
1062 }
1063 else
1064 {
1065 current_size += shift_amount;
1066 }
1067
1068 etl::mem_move(insert_position, insert_position + characters_to_shift, begin() + to_position);
1069 etl::fill(insert_position, insert_position + shift_amount, value);
1070 }
1071
1072 p_buffer[current_size] = 0;
1073
1074 return position_;
1075 }
1076
1077 //*********************************************************************
1084 //*********************************************************************
1085 template <typename TIterator>
1086 iterator insert(const_iterator position, TIterator first, TIterator last)
1087 {
1088 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
1089 ETL_ASSERT_CHECK_EXTRA(first <= last, ETL_ERROR(string_iterator));
1090
1091 iterator position_ = to_iterator(position);
1092
1093 if (first == last)
1094 {
1095 return position_;
1096 }
1097
1098 const size_type start = static_cast<size_type>(etl::distance(begin(), position_));
1099 const size_type n = static_cast<size_type>(etl::distance(first, last));
1100
1101 // No effect.
1102 if (start >= CAPACITY)
1103 {
1104#if ETL_HAS_STRING_TRUNCATION_CHECKS
1105 set_truncated(true);
1106
1107 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1108 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1109 #endif
1110#endif
1111 return position_;
1112 }
1113
1114 // Fills the string to the end?
1115 if ((start + n) >= CAPACITY)
1116 {
1117 if (((current_size + n) > CAPACITY))
1118 {
1119#if ETL_HAS_STRING_TRUNCATION_CHECKS
1120 set_truncated(true);
1121
1122 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1123 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1124 #endif
1125#endif
1126 }
1127
1129
1130 position_ = copy_characters(first, static_cast<size_t>(etl::distance(position_, end())), position_);
1131 }
1132 else
1133 {
1134 // Lets do some shifting.
1135 const size_type shift_amount = n;
1136 const size_type to_position = start + shift_amount;
1137 const size_type remaining_characters = current_size - start;
1138 const size_type max_shift_characters = CAPACITY - start - shift_amount;
1139 const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters);
1140
1141 // Will the string truncate?
1142 if ((start + shift_amount + remaining_characters) > CAPACITY)
1143 {
1145
1146#if ETL_HAS_STRING_TRUNCATION_CHECKS
1147 set_truncated(true);
1148
1149 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1150 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1151 #endif
1152#endif
1153 }
1154 else
1155 {
1156 current_size += shift_amount;
1157 }
1158
1159 etl::mem_move(position_, position_ + characters_to_shift, begin() + to_position);
1160 // etl::copy_backward(position_, position_ + characters_to_shift,
1161 // begin() + to_position + characters_to_shift);
1162
1163 position_ = copy_characters(first, static_cast<size_t>(etl::distance(first, last)), position_);
1164 }
1165
1166 p_buffer[current_size] = 0;
1167
1168 return position_;
1169 }
1170
1171 //*********************************************************************
1177 //*********************************************************************
1178 template <typename TOtherTraits>
1179 iterator insert(const_iterator position, const etl::basic_string_view<T, TOtherTraits>& view)
1180 {
1181 return insert(position, view.begin(), view.end());
1182 }
1183
1184 //*********************************************************************
1188 //*********************************************************************
1189 etl::ibasic_string<T>& insert(size_type position, const etl::ibasic_string<T>& str)
1190 {
1191 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1192
1193 insert(begin() + position, str.cbegin(), str.cend());
1194
1195#if ETL_HAS_STRING_TRUNCATION_CHECKS
1196 if (str.is_truncated())
1197 {
1198 set_truncated(true);
1199
1200 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1201 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1202 #endif
1203 }
1204#endif
1205
1206 return *this;
1207 }
1208
1209 //*********************************************************************
1213 //*********************************************************************
1214 template <typename TOtherTraits>
1216 {
1217 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1218
1219 insert(begin() + position, view.cbegin(), view.cend());
1220
1221 return *this;
1222 }
1223
1224 //*********************************************************************
1231 //*********************************************************************
1232 etl::ibasic_string<T>& insert(size_type position, const etl::ibasic_string<T>& str, size_type subposition, size_type sublength)
1233 {
1234 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1235 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1236
1237 if ((sublength == npos) || (subposition + sublength > str.size()))
1238 {
1239 sublength = str.size() - subposition;
1240 }
1241
1242 insert(begin() + position, str.cbegin() + subposition, str.cbegin() + subposition + sublength);
1243
1244#if ETL_HAS_STRING_TRUNCATION_CHECKS
1245 if (str.is_truncated())
1246 {
1247 set_truncated(true);
1248
1249 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
1250 ETL_ASSERT_FAIL(ETL_ERROR(string_truncation));
1251 #endif
1252 }
1253#endif
1254
1255 return *this;
1256 }
1257
1258 //*********************************************************************
1264 //*********************************************************************
1265 template <typename TOtherTraits>
1266 etl::ibasic_string<T>& insert(size_type position, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition, size_type sublength)
1267 {
1268 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1269 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1270
1271 if ((sublength == npos) || (subposition + sublength > view.size()))
1272 {
1273 sublength = view.size() - subposition;
1274 }
1275
1276 insert(begin() + position, view.cbegin() + subposition, view.cbegin() + subposition + sublength);
1277
1278 return *this;
1279 }
1280
1281 //*********************************************************************
1285 //*********************************************************************
1286 etl::ibasic_string<T>& insert(size_type position, const_pointer s)
1287 {
1288 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1289
1290 insert(begin() + position, s, s + etl::strlen(s));
1291 return *this;
1292 }
1293
1294 //*********************************************************************
1300 //*********************************************************************
1301 etl::ibasic_string<T>& insert(size_type position, const_pointer s, size_type n)
1302 {
1303 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1304
1305 insert(begin() + position, s, s + n);
1306 return *this;
1307 }
1308
1309 //*********************************************************************
1314 //*********************************************************************
1315 etl::ibasic_string<T>& insert(size_type position, size_type n, value_type c)
1316 {
1317 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1318
1319 insert(begin() + position, n, c);
1320 return *this;
1321 }
1322
1323 //*********************************************************************
1328 //*********************************************************************
1329 etl::ibasic_string<T>& erase(size_type position, size_type length_ = npos)
1330 {
1331 ETL_ASSERT_CHECK_EXTRA(position <= size(), ETL_ERROR(string_out_of_bounds));
1332
1333 // Limit the length.
1334 length_ = etl::min(length_, size() - position);
1335
1336 erase(begin() + position, begin() + position + length_);
1337
1338 return *this;
1339 }
1340
1341 //*********************************************************************
1346 //*********************************************************************
1347 iterator erase(iterator i_element)
1348 {
1349 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1350
1351 etl::mem_move(i_element + 1, end(), i_element);
1352 p_buffer[--current_size] = 0;
1353
1354 return i_element;
1355 }
1356
1357 //*********************************************************************
1362 //*********************************************************************
1363 iterator erase(const_iterator i_element)
1364 {
1365 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1366
1367 iterator i_element_(to_iterator(i_element));
1368
1369 etl::mem_move(i_element + 1, end(), i_element_);
1370 p_buffer[--current_size] = 0;
1371
1372 return i_element_;
1373 }
1374
1375 //*********************************************************************
1383 //*********************************************************************
1384 iterator erase(const_iterator first, const_iterator last)
1385 {
1386 ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(string_out_of_bounds));
1387
1388 iterator first_ = to_iterator(first);
1389 iterator last_ = to_iterator(last);
1390
1391 if (first_ == last_)
1392 {
1393 return first_;
1394 }
1395
1396 etl::mem_move(last_, end(), first_);
1397 size_type n_delete = static_cast<size_type>(etl::distance(first_, last_));
1398
1399 current_size -= n_delete;
1400 p_buffer[current_size] = 0;
1401 cleanup();
1402
1403 return first_;
1404 }
1405
1406 //*********************************************************************
1408 //*********************************************************************
1409 const_pointer c_str() const
1410 {
1411 return p_buffer;
1412 }
1413
1414 //*********************************************************************
1419 //*********************************************************************
1420 size_type copy(pointer dest, size_type count, size_type pos = 0) const
1421 {
1422 if (pos < size())
1423 {
1424 if (count != npos)
1425 {
1426 count = etl::min(count, size() - pos);
1427 }
1428 else
1429 {
1430 count = size() - pos;
1431 }
1432
1433 etl::mem_move(p_buffer + pos, count, dest);
1434
1435 return count;
1436 }
1437 else
1438 {
1439 return 0U;
1440 }
1441 }
1442
1443 //*********************************************************************
1447 //*********************************************************************
1448 size_type find(const ibasic_string<T>& str, size_type pos = 0) const
1449 {
1450 return find_impl(str.begin(), str.end(), str.size(), pos);
1451 }
1452
1453 //*********************************************************************
1457 //*********************************************************************
1458 template <typename TOtherTraits>
1459 size_type find(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = 0) const
1460 {
1461 return find_impl(view.begin(), view.end(), view.size(), pos);
1462 }
1463
1464 //*********************************************************************
1468 //*********************************************************************
1469 size_type find(const_pointer s, size_type pos = 0) const
1470 {
1471 size_t sz = etl::strlen(s);
1472
1473 return find_impl(s, s + sz, sz, pos);
1474 }
1475
1476 //*********************************************************************
1481 //*********************************************************************
1482 size_type find(const_pointer s, size_type pos, size_type n) const
1483 {
1484 size_t sz = etl::strlen(s);
1485
1486 return find_impl(s, s + n, sz, pos);
1487 }
1488
1489 //*********************************************************************
1493 //*********************************************************************
1494 size_type find(T c, size_type position = 0) const
1495 {
1496 const_iterator i = etl::find(begin() + position, end(), c);
1497
1498 if (i != end())
1499 {
1500 return static_cast<size_type>(etl::distance(begin(), i));
1501 }
1502 else
1503 {
1504 return npos;
1505 }
1506 }
1507
1508 //*********************************************************************
1512 //*********************************************************************
1513 size_type rfind(const ibasic_string<T>& str, size_type position = npos) const
1514 {
1515 return rfind_impl(str.rbegin(), str.rend(), str.size(), position);
1516 }
1517
1518 //*********************************************************************
1522 //*********************************************************************
1523 template <typename TOtherTraits>
1524 size_type rfind(const etl::basic_string_view<T, TOtherTraits>& view, size_type pos = 0) const
1525 {
1526 return rfind_impl(view.rbegin(), view.rend(), view.size(), pos);
1527 }
1528
1529 //*********************************************************************
1533 //*********************************************************************
1534 size_type rfind(const_pointer s, size_type position = npos) const
1535 {
1536 size_type len = etl::strlen(s);
1537
1538 const_reverse_iterator srbegin(s + len);
1539 const_reverse_iterator srend(s);
1540
1541 return rfind_impl(srbegin, srend, len, position);
1542 }
1543
1544 //*********************************************************************
1548 //*********************************************************************
1549 size_type rfind(const_pointer s, size_type position, size_type length_) const
1550 {
1551 const_reverse_iterator srbegin(s + length_);
1552 const_reverse_iterator srend(s);
1553
1554 return rfind_impl(srbegin, srend, length_, position);
1555 }
1556
1557 //*********************************************************************
1561 //*********************************************************************
1562 size_type rfind(T c, size_type position = npos) const
1563 {
1564 if (position >= size())
1565 {
1566 position = size();
1567 }
1568
1569 position = size() - position;
1570
1571 const_reverse_iterator i = etl::find(rbegin() + static_cast<difference_type>(position), rend(), c);
1572
1573 if (i != rend())
1574 {
1575 return size() - static_cast<size_type>(etl::distance(rbegin(), i)) - 1;
1576 }
1577 else
1578 {
1579 return npos;
1580 }
1581 }
1582
1583 //*********************************************************************
1585 //*********************************************************************
1586 bool contains(const etl::ibasic_string<T>& str) const
1587 {
1588 return find(str) != npos;
1589 }
1590
1591 //*********************************************************************
1593 //*********************************************************************
1594 template <typename TOtherTraits>
1596 {
1597 return find(view) != npos;
1598 }
1599
1600 //*********************************************************************
1602 //*********************************************************************
1603 bool contains(const_pointer s) const
1604 {
1605 return find(s) != npos;
1606 }
1607
1608 //*********************************************************************
1610 //*********************************************************************
1611 bool contains(value_type c) const
1612 {
1613 return find(c) != npos;
1614 }
1615
1616 //*********************************************************************
1618 //*********************************************************************
1619 bool starts_with(const etl::ibasic_string<T>& str) const
1620 {
1621 return compare(0, str.size(), str) == 0;
1622 }
1623
1624 //*********************************************************************
1626 //*********************************************************************
1627 template <typename TOtherTraits>
1629 {
1630 return compare(0, view.size(), view) == 0;
1631 }
1632
1633 //*********************************************************************
1635 //*********************************************************************
1636 bool starts_with(const_pointer s) const
1637 {
1638 size_t len = etl::strlen(s);
1639
1640 return compare(0, len, s, len) == 0;
1641 }
1642
1643 //*********************************************************************
1645 //*********************************************************************
1646 bool starts_with(value_type c) const
1647 {
1648 return !empty() && (front() == c);
1649 }
1650
1651 //*********************************************************************
1653 //*********************************************************************
1654 bool ends_with(const etl::ibasic_string<T>& str) const
1655 {
1656 if (str.size() > size())
1657 {
1658 return false;
1659 }
1660
1661 return compare(size() - str.size(), str.size(), str) == 0;
1662 }
1663
1664 //*********************************************************************
1666 //*********************************************************************
1667 template <typename TOtherTraits>
1669 {
1670 if (view.size() > size())
1671 {
1672 return false;
1673 }
1674
1675 return compare(size() - view.size(), view.size(), view) == 0;
1676 }
1677
1678 //*********************************************************************
1680 //*********************************************************************
1681 bool ends_with(const_pointer s) const
1682 {
1683 size_t len = etl::strlen(s);
1684
1685 if (len > size())
1686 {
1687 return false;
1688 }
1689
1690 return compare(size() - len, len, s, len) == 0;
1691 }
1692
1693 //*********************************************************************
1695 //*********************************************************************
1696 bool ends_with(value_type c) const
1697 {
1698 return !empty() && (back() == c);
1699 }
1700
1701 //*********************************************************************
1706 //*********************************************************************
1707 ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str)
1708 {
1709 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1710
1711 // Limit the length.
1712 length_ = etl::min(length_, size() - position);
1713
1714 return replace_impl(begin() + position, begin() + position + length_, str.begin(), str.size(), str.is_truncated());
1715 }
1716
1717 //*********************************************************************
1722 //*********************************************************************
1723 template <typename TOtherTraits>
1724 ibasic_string& replace(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view)
1725 {
1726 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1727
1728 // Limit the length.
1729 length_ = etl::min(length_, size() - position);
1730
1731 return replace_impl(begin() + position, begin() + position + length_, view.begin(), view.size(), false);
1732 }
1733
1734 //*********************************************************************
1739 //*********************************************************************
1740 ibasic_string& replace(const_iterator first, const_iterator last, const ibasic_string& str)
1741 {
1742 return replace_impl(first, last, str.begin(), str.size(), str.is_truncated());
1743 }
1744
1745 //*********************************************************************
1750 //*********************************************************************
1751 template <typename TOtherTraits>
1752 ibasic_string& replace(const_iterator first, const_iterator last, const etl::basic_string_view<T, TOtherTraits>& view)
1753 {
1754 return replace_impl(first, last, view.begin(), view.size(), false);
1755 }
1756
1757 //*********************************************************************
1760 //*********************************************************************
1761 ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength)
1762 {
1763 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1764 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1765
1766 // Limit the lengths.
1767 length_ = etl::min(length_, size() - position);
1768 sublength = etl::min(sublength, str.size() - subposition);
1769
1770 return replace_impl(begin() + position, begin() + position + length_, str.begin() + subposition, sublength, str.is_truncated());
1771 }
1772
1773 //*********************************************************************
1776 //*********************************************************************
1777 template <typename TOtherTraits>
1778 ibasic_string& replace(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition,
1779 size_type sublength)
1780 {
1781 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1782 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1783
1784 // Limit the lengths.
1785 length_ = etl::min(length_, size() - position);
1786 sublength = etl::min(sublength, view.size() - subposition);
1787
1788 return replace_impl(begin() + position, begin() + position + length_, view.begin() + subposition, sublength, false);
1789 }
1790
1791 //*********************************************************************
1793 //*********************************************************************
1794 ibasic_string& replace(size_type position, size_type length_, const_pointer s)
1795 {
1796 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1797
1798 // Limit the length.
1799 length_ = etl::min(length_, size() - position);
1800
1801 return replace_impl(begin() + position, begin() + position + length_, s, etl::strlen(s), false);
1802 }
1803
1804 //*********************************************************************
1812 //*********************************************************************
1813 ibasic_string& replace(const_iterator first, const_iterator last, const_pointer s, size_type n)
1814 {
1815 return replace_impl(first, last, s, n, false);
1816 }
1817
1818 //*********************************************************************
1820 //*********************************************************************
1821 template <typename TIterator>
1822 typename etl::enable_if<etl::is_same<TIterator, const_pointer>::value, ibasic_string>::type& replace(const_iterator first, const_iterator last,
1823 TIterator s)
1824 {
1825 return replace_impl(first, last, s, etl::strlen(s), false);
1826 }
1827
1828 //*********************************************************************
1830 //*********************************************************************
1831 template <size_t Size>
1832 ibasic_string& replace(const_iterator first, const_iterator last, const value_type (&literal)[Size])
1833 {
1834 return replace_impl(first, last, literal, Size, false);
1835 }
1836
1837 //*********************************************************************
1840 //*********************************************************************
1841 ibasic_string& replace(size_type position, size_type length_, const_pointer s, size_type n)
1842 {
1843 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1844
1845 // Limit the length.
1846 length_ = etl::min(length_, size() - position);
1847
1848 return replace_impl(begin() + position, begin() + position + length_, s, n, false);
1849 }
1850
1851 //*********************************************************************
1853 //*********************************************************************
1854 ibasic_string& replace(size_type position, size_type length_, size_type n, value_type c)
1855 {
1856 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1857
1858 // Limit the length.
1859 length_ = etl::min(length_, size() - position);
1860
1861 // Erase the bit we want to replace.
1862 erase(position, length_);
1863
1864 // Insert the new stuff.
1865 insert(position, n, c);
1866
1867 return *this;
1868 }
1869
1870 //*********************************************************************
1872 //*********************************************************************
1873 ibasic_string& replace(const_iterator first, const_iterator last, size_type n, value_type c)
1874 {
1875 // Quick hack, as iterators are pointers.
1876 iterator first_ = to_iterator(first);
1877 iterator last_ = to_iterator(last);
1878
1879 // Erase the bit we want to replace.
1880 erase(first_, last_);
1881
1882 // Insert the new stuff.
1883 insert(first_, n, c);
1884
1885 return *this;
1886 }
1887
1888 //*********************************************************************
1891 //*********************************************************************
1892 template <typename TIterator>
1893 ibasic_string& replace(const_iterator first, const_iterator last, TIterator first_replace, TIterator last_replace)
1894 {
1895 // Quick hack, as iterators are pointers.
1896 iterator first_ = to_iterator(first);
1897 iterator last_ = to_iterator(last);
1898
1899 // Erase the bit we want to replace.
1900 erase(first_, last_);
1901
1902 // Insert the new stuff.
1903 insert(first_, first_replace, last_replace);
1904
1905 return *this;
1906 }
1907
1908 //*************************************************************************
1910 //*************************************************************************
1911 int compare(const ibasic_string& str) const
1912 {
1913 return compare(p_buffer, p_buffer + size(), str.p_buffer, str.p_buffer + str.size());
1914 }
1915
1916 //*************************************************************************
1918 //*************************************************************************
1919 template <typename TOtherTraits>
1921 {
1922 return compare(p_buffer, p_buffer + size(), view.data(), view.data() + view.size());
1923 }
1924
1925 //*************************************************************************
1927 //*************************************************************************
1928 int compare(size_type position, size_type length_, const ibasic_string& str) const
1929 {
1930 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1931
1932 // Limit the length.
1933 length_ = etl::min(length_, size() - position);
1934
1935 return compare(p_buffer + position, p_buffer + position + length_, str.p_buffer, str.p_buffer + str.size());
1936 }
1937
1938 //*************************************************************************
1940 //*************************************************************************
1941 template <typename TOtherTraits>
1942 int compare(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view) const
1943 {
1944 return compare(p_buffer + position, p_buffer + position + length_, view.data(), view.data() + view.size());
1945 }
1946
1947 //*************************************************************************
1949 //*************************************************************************
1950 int compare(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength) const
1951 {
1952 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1953 ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds));
1954
1955 // Limit the lengths.
1956 length_ = etl::min(length_, size() - position);
1957 sublength = etl::min(sublength, str.size() - subposition);
1958
1959 return compare(p_buffer + position, p_buffer + position + length_, str.p_buffer + subposition, str.p_buffer + subposition + sublength);
1960 }
1961
1962 //*************************************************************************
1965 //*************************************************************************
1966 template <typename TOtherTraits>
1967 int compare(size_type position, size_type length_, const etl::basic_string_view<T, TOtherTraits>& view, size_type subposition,
1968 size_type sublength) const
1969 {
1970 ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds));
1971 ETL_ASSERT(subposition <= view.size(), ETL_ERROR(string_out_of_bounds));
1972
1973 // Limit the lengths.
1974 length_ = etl::min(length_, size() - position);
1975 sublength = etl::min(sublength, view.size() - subposition);
1976
1977 return compare(p_buffer + position, p_buffer + position + length_, view.data() + subposition, view.data() + subposition + sublength);
1978 }
1979
1980 //*************************************************************************
1982 //*************************************************************************
1983 int compare(const value_type* s) const
1984 {
1985 return compare(p_buffer, p_buffer + size(), s, s + etl::strlen(s));
1986 }
1987
1988 //*************************************************************************
1990 //*************************************************************************
1991 int compare(size_type position, size_type length_, const_pointer s) const
1992 {
1993 return compare(p_buffer + position, p_buffer + position + length_, s, s + etl::strlen(s));
1994 }
1995
1996 //*************************************************************************
1998 //*************************************************************************
1999 int compare(size_type position, size_type length_, const_pointer s, size_type n) const
2000 {
2001 return compare(p_buffer + position, p_buffer + position + length_, s, s + n);
2002 }
2003
2004 //*********************************************************************
2008 //*********************************************************************
2009 size_type find_first_of(const ibasic_string<T>& str, size_type position = 0) const
2010 {
2011 return find_first_of(str.c_str(), position, str.size());
2012 }
2013
2014 //*********************************************************************
2018 //*********************************************************************
2019 size_type find_first_of(const_pointer s, size_type position = 0) const
2020 {
2021 return find_first_of(s, position, etl::strlen(s));
2022 }
2023
2024 //*********************************************************************
2028 //*********************************************************************
2029 template <typename TOtherTraits>
2030 size_type find_first_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = 0) const
2031 {
2032 return find_first_of(view.data(), position, view.size());
2033 }
2034
2035 //*********************************************************************
2040 //*********************************************************************
2041 size_type find_first_of(const_pointer s, size_type position, size_type n) const
2042 {
2043 if (position < size())
2044 {
2045 for (size_type i = position; i < size(); ++i)
2046 {
2047 for (size_type j = 0; j < n; ++j)
2048 {
2049 if (p_buffer[i] == s[j])
2050 {
2051 return i;
2052 }
2053 }
2054 }
2055 }
2056
2057 return npos;
2058 }
2059
2060 //*********************************************************************
2064 //*********************************************************************
2065 size_type find_first_of(value_type c, size_type position = 0) const
2066 {
2067 if (position < size())
2068 {
2069 for (size_type i = position; i < size(); ++i)
2070 {
2071 if (p_buffer[i] == c)
2072 {
2073 return i;
2074 }
2075 }
2076 }
2077
2078 return npos;
2079 }
2080
2081 //*********************************************************************
2085 //*********************************************************************
2086 size_type find_last_of(const ibasic_string<T>& str, size_type position = npos) const
2087 {
2088 return find_last_of(str.c_str(), position, str.size());
2089 }
2090
2091 //*********************************************************************
2095 //*********************************************************************
2096 size_type find_last_of(const_pointer s, size_type position = npos) const
2097 {
2098 return find_last_of(s, position, etl::strlen(s));
2099 }
2100
2101 //*********************************************************************
2105 //*********************************************************************
2106 template <typename TOtherTraits>
2107 size_type find_last_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = npos) const
2108 {
2109 return find_last_of(view.data(), position, view.size());
2110 }
2111
2112 //*********************************************************************
2117 //*********************************************************************
2118 size_type find_last_of(const_pointer s, size_type position, size_type n) const
2119 {
2120 if (empty())
2121 {
2122 return npos;
2123 }
2124
2125 position = etl::min(position, size() - 1);
2126
2127 const_reverse_iterator it = rbegin() + static_cast<difference_type>(size() - position - 1);
2128
2129 while (it != rend())
2130 {
2131 for (size_type j = 0; j < n; ++j)
2132 {
2133 if (p_buffer[position] == s[j])
2134 {
2135 return position;
2136 }
2137 }
2138
2139 ++it;
2140 --position;
2141 }
2142
2143 return npos;
2144 }
2145
2146 //*********************************************************************
2150 //*********************************************************************
2151 size_type find_last_of(value_type c, size_type position = npos) const
2152 {
2153 if (empty())
2154 {
2155 return npos;
2156 }
2157
2158 position = etl::min(position, size() - 1);
2159
2160 const_reverse_iterator it = rbegin() + static_cast<difference_type>(size() - position - 1);
2161
2162 while (it != rend())
2163 {
2164 if (p_buffer[position] == c)
2165 {
2166 return position;
2167 }
2168
2169 ++it;
2170 --position;
2171 }
2172
2173 return npos;
2174 }
2175
2176 //*********************************************************************
2180 //*********************************************************************
2181 size_type find_first_not_of(const ibasic_string<T>& str, size_type position = 0) const
2182 {
2183 return find_first_not_of(str.c_str(), position, str.size());
2184 }
2185
2186 //*********************************************************************
2190 //*********************************************************************
2191 size_type find_first_not_of(const_pointer s, size_type position = 0) const
2192 {
2193 return find_first_not_of(s, position, etl::strlen(s));
2194 }
2195
2196 //*********************************************************************
2200 //*********************************************************************
2201 template <typename TOtherTraits>
2202 size_type find_first_not_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = 0) const
2203 {
2204 return find_first_not_of(view.data(), position, view.size());
2205 }
2206
2207 //*********************************************************************
2212 //*********************************************************************
2213 size_type find_first_not_of(const_pointer s, size_type position, size_type n) const
2214 {
2215 if (position < size())
2216 {
2217 for (size_type i = position; i < size(); ++i)
2218 {
2219 bool found = false;
2220
2221 for (size_type j = 0; j < n; ++j)
2222 {
2223 if (p_buffer[i] == s[j])
2224 {
2225 found = true;
2226 }
2227 }
2228
2229 if (!found)
2230 {
2231 return i;
2232 }
2233 }
2234 }
2235
2236 return npos;
2237 }
2238
2239 //*********************************************************************
2243 //*********************************************************************
2244 size_type find_first_not_of(value_type c, size_type position = 0) const
2245 {
2246 if (position < size())
2247 {
2248 for (size_type i = position; i < size(); ++i)
2249 {
2250 if (*(p_buffer + i) != c)
2251 {
2252 return i;
2253 }
2254 }
2255 }
2256
2257 return npos;
2258 }
2259
2260 //*********************************************************************
2264 //*********************************************************************
2265 size_type find_last_not_of(const ibasic_string<T>& str, size_type position = npos) const
2266 {
2267 return find_last_not_of(str.c_str(), position, str.size());
2268 }
2269
2270 //*********************************************************************
2274 //*********************************************************************
2275 size_type find_last_not_of(const_pointer s, size_type position = npos) const
2276 {
2277 return find_last_not_of(s, position, etl::strlen(s));
2278 }
2279
2280 //*********************************************************************
2284 //*********************************************************************
2285 template <typename TOtherTraits>
2286 size_type find_last_not_of(const etl::basic_string_view<T, TOtherTraits>& view, size_type position = npos) const
2287 {
2288 return find_last_not_of(view.data(), position, view.size());
2289 }
2290
2291 //*********************************************************************
2296 //*********************************************************************
2297 size_type find_last_not_of(const_pointer s, size_type position, size_type n) const
2298 {
2299 if (empty())
2300 {
2301 return npos;
2302 }
2303
2304 position = etl::min(position, size() - 1);
2305
2306 const_reverse_iterator it = rbegin() + static_cast<difference_type>(size() - position - 1);
2307
2308 while (it != rend())
2309 {
2310 bool found = false;
2311
2312 for (size_type j = 0; j < n; ++j)
2313 {
2314 if (p_buffer[position] == s[j])
2315 {
2316 found = true;
2317 }
2318 }
2319
2320 if (!found)
2321 {
2322 return position;
2323 }
2324
2325 ++it;
2326 --position;
2327 }
2328
2329 return npos;
2330 }
2331
2332 //*********************************************************************
2333 //
2334 //*********************************************************************
2335 size_type find_last_not_of(value_type c, size_type position = npos) const
2336 {
2337 if (empty())
2338 {
2339 return npos;
2340 }
2341
2342 position = etl::min(position, size() - 1);
2343
2344 const_reverse_iterator it = rbegin() + static_cast<difference_type>(size() - position - 1);
2345
2346 while (it != rend())
2347 {
2348 if (p_buffer[position] != c)
2349 {
2350 return position;
2351 }
2352
2353 ++it;
2354 --position;
2355 }
2356
2357 return npos;
2358 }
2359
2360 //*************************************************************************
2362 //*************************************************************************
2364 {
2365 if (&rhs != this)
2366 {
2367 assign(rhs);
2368 }
2369
2370 return *this;
2371 }
2372
2373 //*************************************************************************
2375 //*************************************************************************
2376 ibasic_string& operator=(const_pointer rhs)
2377 {
2378 assign(rhs);
2379
2380 return *this;
2381 }
2382
2383 //*************************************************************************
2385 //*************************************************************************
2386 template <typename TOtherTraits>
2388 {
2389 assign(view);
2390
2391 return *this;
2392 }
2393
2394 //*************************************************************************
2396 //*************************************************************************
2398 {
2399 append(rhs);
2400
2401 return *this;
2402 }
2403
2404 //*************************************************************************
2406 //*************************************************************************
2407 template <typename TOtherTraits>
2409 {
2410 append(rhs);
2411
2412 return *this;
2413 }
2414
2415 //*************************************************************************
2417 //*************************************************************************
2418 ibasic_string& operator+=(const_pointer rhs)
2419 {
2420 append(rhs);
2421
2422 return *this;
2423 }
2424
2425 //*************************************************************************
2427 //*************************************************************************
2429 {
2430 append(size_type(1), rhs);
2431
2432 return *this;
2433 }
2434
2435#if ETL_HAS_ISTRING_REPAIR
2436 //*************************************************************************
2438 //*************************************************************************
2439 virtual void repair() = 0;
2440#endif
2441
2442 //*********************************************************************
2444 //*********************************************************************
2446 {
2447#if ETL_HAS_STRING_TRUNCATION_CHECKS
2448 set_truncated(false);
2449#endif
2450 etl::mem_set(&p_buffer[current_size], &p_buffer[CAPACITY + 1U], char(0));
2451 }
2452
2453 //*********************************************************************
2457 //*********************************************************************
2459 {
2460#if ETL_HAS_STRING_TRUNCATION_CHECKS
2461 set_truncated(p_buffer[CAPACITY] != T(0));
2462#endif
2463
2464 p_buffer[CAPACITY] = T(0); // Ensure a terminating null.
2465 current_size = etl::strlen(p_buffer);
2466 }
2467
2468 protected:
2469
2470 //*********************************************************************
2472 //*********************************************************************
2473 ibasic_string(T* p_buffer_, size_type MAX_SIZE_)
2474 : string_base(MAX_SIZE_)
2475 , p_buffer(p_buffer_)
2476 {
2477 }
2478
2479 //*********************************************************************
2481 //*********************************************************************
2483 {
2484 current_size = 0U;
2485 p_buffer[0] = 0;
2486#if ETL_HAS_STRING_TRUNCATION_CHECKS
2487 set_truncated(false);
2488#endif
2489 }
2490
2491 //*************************************************************************
2493 //*************************************************************************
2494 void repair_buffer(T* p_buffer_)
2495 {
2496 p_buffer = p_buffer_;
2497 }
2498
2499 private:
2500
2501 //*********************************************************************
2505 //*********************************************************************
2506 ibasic_string& replace_impl(const_iterator first, const_iterator last, const_pointer s, size_type length, bool other_truncated)
2507 {
2508 // Trivial no-op cases
2509 if ((first == last) && (s == ETL_NULLPTR || length == 0U))
2510 {
2511 return *this;
2512 }
2513
2514 // Invalid range?
2515 if (first > last)
2516 {
2517 return *this;
2518 }
2519
2520 // Quick hack, as iterators are pointers.
2521 iterator first_ = to_iterator(first);
2522 iterator last_ = to_iterator(last);
2523
2524 // If source pointer is inside our current buffer we take the safe
2525 // (legacy) path to preserve correct semantics for overlapping self use.
2526 const bool source_overlaps = (s != ETL_NULLPTR) && (s >= p_buffer) && (s < p_buffer + current_size);
2527
2528 if (source_overlaps)
2529 {
2530 // Legacy behaviour (may be slightly less efficient, but correct).
2531 // Erase range then insert up to 'length' characters from 's'.
2532 erase(first_, last_);
2533
2534 if (s != ETL_NULLPTR && length != 0U)
2535 {
2536 // 'insert' can truncate & set flags.
2537 insert(p_buffer + (first_ - p_buffer), s, s + length);
2538 }
2539
2540 return *this;
2541 }
2542
2543 // Calculate the remove parameters.
2544 const size_type remove_index = size_type(first_ - p_buffer);
2545 const size_type remove_length = size_type(last_ - first_);
2546 const size_type free_space = CAPACITY - remove_index; // Free space is the space from the remove
2547 // index to the end of the buffer.
2548
2549 size_type insert_length = (s == ETL_NULLPTR) ? 0U : length;
2550
2551 // Limit the insert length to the available free space.
2552 if (insert_length > free_space)
2553 {
2554 insert_length = free_space;
2555 }
2556
2557 // Calculate the tail parameters.
2558 size_type tail_index = remove_index + remove_length;
2559 size_type tail_length = current_size - tail_index;
2560 size_type tail_space = free_space - insert_length;
2561
2562#if ETL_HAS_STRING_TRUNCATION_CHECKS
2563 set_truncated((insert_length != length) || (tail_space < tail_length) || is_truncated() || other_truncated);
2564#endif
2565
2566 // The some or all of tail may be erased if the space remaining for it is
2567 // smaller than the tail length.
2568 if (tail_space < tail_length)
2569 {
2570 tail_length = tail_space;
2571 }
2572
2573 // Three cases: same size, grow, shrink.
2574 if (insert_length == remove_length)
2575 {
2576 // Size unchanged: simple overwrite.
2577 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2578 }
2579 else if (insert_length > remove_length)
2580 {
2581 // Grow: shift tail right then copy.
2582 // Shift tail (backwards to handle overlap safely).
2583 etl::mem_move(&p_buffer[tail_index], tail_length, &p_buffer[remove_index + insert_length]);
2584
2585 // Copy new data.
2586 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2587 }
2588 else // insert_length < remove_length
2589 {
2590 // Shrink: overwrite then shift tail left.
2591 // Copy new data.
2592 etl::mem_copy(s, insert_length, &p_buffer[remove_index]);
2593
2594 // Move tail left.
2595 etl::mem_move(&p_buffer[tail_index], tail_length, &p_buffer[remove_index + insert_length]);
2596 }
2597
2598 current_size = remove_index + insert_length + tail_length;
2599 p_buffer[current_size] = value_type(0);
2600
2601 cleanup();
2602
2603 return *this;
2604 }
2605
2606 //*************************************************************************
2608 //*************************************************************************
2609 static int compare(const_pointer first1, const_pointer last1, const_pointer first2, const_pointer last2)
2610 {
2611 typedef typename etl::make_unsigned<value_type>::type type;
2612
2613 difference_type length1 = etl::distance(first1, last1);
2614 difference_type length2 = etl::distance(first2, last2);
2615 difference_type compare_length = etl::min(length1, length2);
2616
2617 // First compare the string characters.
2618 while (compare_length != 0)
2619 {
2620 if (static_cast<type>(*first1) < static_cast<type>(*first2))
2621 {
2622 // Compared character is lower.
2623 return -1;
2624 }
2625 else if (static_cast<type>(*first1) > static_cast<type>(*first2))
2626 {
2627 // Compared character is higher.
2628 return 1;
2629 }
2630
2631 ++first1;
2632 ++first2;
2633 --compare_length;
2634 }
2635
2636 // Then compare the string lengths.
2637 if (length1 < length2)
2638 {
2639 // First string is shorter.
2640 return -1;
2641 }
2642
2643 if (length1 > length2)
2644 {
2645 // First string is longer.
2646 return 1;
2647 }
2648
2649 // Strings are the same length.
2650 return 0;
2651 }
2652
2653 //*************************************************************************
2655 //*************************************************************************
2656 void cleanup()
2657 {
2658#if ETL_HAS_STRING_CLEAR_AFTER_USE
2659 if (is_secure())
2660 {
2661 etl::memory_clear_range(&p_buffer[current_size], &p_buffer[CAPACITY]);
2662 }
2663#endif
2664 }
2665
2666 //*************************************************************************
2668 //*************************************************************************
2670
2671 //*************************************************************************
2673 //*************************************************************************
2674 T* p_buffer;
2675
2676 //*************************************************************************
2678 //*************************************************************************
2679#if defined(ETL_POLYMORPHIC_STRINGS) || defined(ETL_POLYMORPHIC_CONTAINERS) || defined(ETL_ISTRING_REPAIR_ENABLE)
2680
2681 public:
2682
2683 virtual
2684#else
2685
2686 protected:
2687#endif
2689 {
2690#if ETL_HAS_STRING_CLEAR_AFTER_USE
2691 if (is_secure())
2692 {
2693 clear();
2694 }
2695#endif
2696 }
2697
2698 protected:
2699
2700 //*************************************************************************
2702 //*************************************************************************
2703 iterator to_iterator(const_iterator itr) const
2704 {
2705 return const_cast<iterator>(itr);
2706 }
2707
2708 //*************************************************************************
2710 //*************************************************************************
2711 bool is_within_buffer(const_pointer ptr) const
2712 {
2713 return (ptr >= p_buffer) && (ptr <= (p_buffer + CAPACITY));
2714 }
2715
2716 private:
2717
2718 //*********************************************************************
2721 //*********************************************************************
2722 template <typename TIterator1>
2723 static
2724 typename etl::enable_if< etl::is_pointer<typename etl::remove_reference<TIterator1>::type>::value
2727 copy_characters(TIterator1 from, size_t n, iterator to)
2728 {
2729 etl::mem_move(from, n, to);
2730
2731 return to + n;
2732 }
2733
2734 //*********************************************************************
2737 //*********************************************************************
2738 template <typename TIterator1>
2739 static
2740 typename etl::enable_if< !(etl::is_pointer<typename etl::remove_reference<TIterator1>::type>::value
2741 && sizeof(typename etl::remove_pointer< typename etl::remove_cvref<TIterator1>::type>::type) == sizeof(value_type)),
2742 iterator>::type
2743 copy_characters(TIterator1 from, size_t n, iterator to)
2744 {
2745 size_t count = 0;
2746
2747 while (count != n)
2748 {
2749 *to++ = static_cast<value_type>(*from++);
2750 ++count;
2751 }
2752
2753 return to;
2754 }
2755
2756 //*********************************************************************
2759 //*********************************************************************
2760 template <typename TIterator>
2761 typename etl::enable_if< !etl::is_pointer< typename etl::remove_reference<TIterator>::type>::value>::type
2762 append_impl(iterator position, TIterator first, TIterator last, bool truncated, bool secure)
2763 {
2764 difference_type start = etl::distance(p_buffer, position);
2765 difference_type count = etl::distance(first, last);
2766 difference_type free_space = etl::distance(position, p_buffer + CAPACITY);
2767
2768#if ETL_IS_DEBUG_BUILD
2769 ETL_ASSERT(count >= 0, ETL_ERROR(string_iterator));
2770#endif
2771
2772#if ETL_HAS_STRING_TRUNCATION_CHECKS
2773 set_truncated((count > free_space) || this->is_truncated() || truncated);
2774
2775 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2776 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
2777 #endif
2778#else
2779 (void)truncated;
2780#endif
2781
2782#if ETL_HAS_STRING_CLEAR_AFTER_USE
2783 if (secure)
2784 {
2785 set_secure();
2786 }
2787#else
2788 (void)secure;
2789#endif
2790
2791 // Limit the actual distance to the capacity.
2792 count = etl::min(count, free_space);
2793 copy_characters(first, size_t(count), position);
2794 current_size = size_t(start + count);
2795 p_buffer[current_size] = 0;
2796
2797 cleanup();
2798 }
2799
2800 //*********************************************************************
2802 //*********************************************************************
2803 void append_impl(iterator position, const_pointer src, bool truncated, bool secure)
2804 {
2805 if (src == ETL_NULLPTR)
2806 {
2807 clear();
2808 return;
2809 }
2810
2811 append_impl(position, src, get_string_length(src), truncated, secure);
2812 }
2813
2814 //*********************************************************************
2816 //*********************************************************************
2817 void append_impl(iterator position, const_pointer src, size_t length, bool truncated, bool secure)
2818 {
2819 size_t start = static_cast<size_t>(etl::distance(p_buffer, position));
2820 size_t free_space = static_cast<size_t>(etl::distance(position, p_buffer + CAPACITY));
2821 size_t count = etl::min(length, free_space);
2822
2823#if ETL_IS_DEBUG_BUILD
2824 ETL_ASSERT(start <= CAPACITY, ETL_ERROR(string_iterator));
2825#endif
2826
2827 etl::mem_move(src, count, position);
2828
2829 current_size = start + count;
2830 p_buffer[current_size] = 0;
2831
2832#if ETL_HAS_STRING_TRUNCATION_CHECKS
2833 set_truncated((length > free_space) || truncated);
2834 #if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2835 ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
2836 #endif
2837#else
2838 (void)truncated;
2839#endif
2840
2841#if ETL_HAS_STRING_CLEAR_AFTER_USE
2842 if (secure)
2843 {
2844 set_secure();
2845 }
2846#else
2847 (void)secure;
2848#endif
2849
2850 cleanup();
2851 }
2852
2853 //*********************************************************************
2855 //*********************************************************************
2856 template <typename TIterator>
2857 typename etl::enable_if< etl::is_pointer< typename etl::remove_reference<TIterator>::type>::value>::type
2858 append_impl(iterator position, TIterator first, TIterator last, bool truncated, bool secure)
2859 {
2860 append_impl(position, first, size_t(etl::distance(first, last)), truncated || is_truncated(), secure);
2861 }
2862
2863 //*************************************************************************
2865 //*************************************************************************
2866 template <typename TIterator>
2867 size_type find_impl(TIterator first, TIterator last, size_type sz, size_type pos = 0) const
2868 {
2869 if ((pos + sz) > size())
2870 {
2871 return npos;
2872 }
2873
2874 const_iterator iposition = etl::search(begin() + pos, end(), first, last);
2875
2876 if (iposition == end())
2877 {
2878 return npos;
2879 }
2880 else
2881 {
2882 return static_cast<size_type>(etl::distance(begin(), iposition));
2883 }
2884 }
2885
2886 //*************************************************************************
2888 //*************************************************************************
2889 template <typename TIterator>
2890 size_type rfind_impl(TIterator rfirst, TIterator rlast, size_type sz, size_type pos = 0) const
2891 {
2892 if (sz > size())
2893 {
2894 return npos;
2895 }
2896
2897 if (pos >= size())
2898 {
2899 pos = size();
2900 }
2901
2902 pos = size() - pos;
2903
2904 const_reverse_iterator iposition = etl::search(rbegin() + static_cast<difference_type>(pos), rend(), rfirst, rlast);
2905
2906 if (iposition == rend())
2907 {
2908 return npos;
2909 }
2910 else
2911 {
2912 return size() - sz - static_cast<size_type>(etl::distance(rbegin(), iposition));
2913 }
2914 }
2915
2916 //*********************************************************************
2918 //*********************************************************************
2919 template <typename U>
2920 static typename etl::enable_if<sizeof(U) == sizeof(char), size_t>::type get_string_length(const U* str)
2921 {
2922 return ::strlen(reinterpret_cast<const char*>(str));
2923 }
2924
2925#if ETL_USING_LIBC_WCHAR_H
2926 //*********************************************************************
2928 //*********************************************************************
2929 template <typename U>
2930 static typename etl::enable_if<sizeof(U) == sizeof(wchar_t), size_t>::type get_string_length(const U* str)
2931 {
2932 return ::wcslen(reinterpret_cast<const wchar_t*>(str));
2933 }
2934#endif
2935
2936 //*********************************************************************
2938 //*********************************************************************
2939 template <typename U>
2940 static
2941#if ETL_USING_LIBC_WCHAR_H
2942 typename etl::enable_if<(sizeof(U) != sizeof(char)) && (sizeof(U) != sizeof(wchar_t)), size_t>::type
2943#else
2944 typename etl::enable_if<(sizeof(U) != sizeof(char)), size_t>::type
2945#endif
2946 get_string_length(const U* str)
2947 {
2948 if (str == ETL_NULLPTR)
2949 {
2950 return 0;
2951 }
2952
2953 const U* end = str;
2954
2955 while (*end++ != 0)
2956 {
2957 // Do nothing.
2958 }
2959
2960 return size_t(end - str) - 1;
2961 }
2962 };
2963
2964 //***************************************************************************
2970 //***************************************************************************
2971 template <typename T>
2973 {
2974 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
2975 }
2976
2977 //***************************************************************************
2983 //***************************************************************************
2984 template <typename T>
2985 bool operator==(const etl::ibasic_string<T>& lhs, const T* rhs)
2986 {
2987 return (lhs.size() == etl::strlen(rhs)) && etl::equal(lhs.begin(), lhs.end(), rhs);
2988 }
2989
2990 //***************************************************************************
2996 //***************************************************************************
2997 template <typename T>
2998 bool operator==(const T* lhs, const etl::ibasic_string<T>& rhs)
2999 {
3000 return (rhs.size() == etl::strlen(lhs)) && etl::equal(rhs.begin(), rhs.end(), lhs);
3001 }
3002
3003 //***************************************************************************
3009 //***************************************************************************
3010 template <typename T>
3012 {
3013 return !(lhs == rhs);
3014 }
3015
3016 //***************************************************************************
3022 //***************************************************************************
3023 template <typename T>
3024 bool operator!=(const etl::ibasic_string<T>& lhs, const T* rhs)
3025 {
3026 return !(lhs == rhs);
3027 }
3028
3029 //***************************************************************************
3035 //***************************************************************************
3036 template <typename T>
3037 bool operator!=(const T* lhs, const etl::ibasic_string<T>& rhs)
3038 {
3039 return !(lhs == rhs);
3040 }
3041
3042 //***************************************************************************
3048 //***************************************************************************
3049 template <typename T>
3051 {
3052 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
3053 }
3054
3055 //***************************************************************************
3061 //***************************************************************************
3062 template <typename T>
3063 bool operator<(const etl::ibasic_string<T>& lhs, const T* rhs)
3064 {
3065 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs, rhs + etl::strlen(rhs));
3066 }
3067
3068 //***************************************************************************
3074 //***************************************************************************
3075 template <typename T>
3076 bool operator<(const T* lhs, const etl::ibasic_string<T>& rhs)
3077 {
3078 return etl::lexicographical_compare(lhs, lhs + etl::strlen(lhs), rhs.begin(), rhs.end());
3079 }
3080
3081 //***************************************************************************
3087 //***************************************************************************
3088 template <typename T>
3090 {
3091 return (rhs < lhs);
3092 }
3093
3094 //***************************************************************************
3100 //***************************************************************************
3101 template <typename T>
3102 bool operator>(const etl::ibasic_string<T>& lhs, const T* rhs)
3103 {
3104 return (rhs < lhs);
3105 }
3106
3107 //***************************************************************************
3113 //***************************************************************************
3114 template <typename T>
3115 bool operator>(const T* lhs, const etl::ibasic_string<T>& rhs)
3116 {
3117 return (rhs < lhs);
3118 }
3119
3120 //***************************************************************************
3127 //***************************************************************************
3128 template <typename T>
3130 {
3131 return !(lhs > rhs);
3132 }
3133
3134 //***************************************************************************
3141 //***************************************************************************
3142 template <typename T>
3143 bool operator<=(const etl::ibasic_string<T>& lhs, const T* rhs)
3144 {
3145 return !(lhs > rhs);
3146 }
3147
3148 //***************************************************************************
3155 //***************************************************************************
3156 template <typename T>
3157 bool operator<=(const T* lhs, const etl::ibasic_string<T>& rhs)
3158 {
3159 return !(lhs > rhs);
3160 }
3161
3162 //***************************************************************************
3169 //***************************************************************************
3170 template <typename T>
3172 {
3173 return !(lhs < rhs);
3174 }
3175
3176 //***************************************************************************
3183 //***************************************************************************
3184 template <typename T>
3185 bool operator>=(const etl::ibasic_string<T>& lhs, const T* rhs)
3186 {
3187 return !(lhs < rhs);
3188 }
3189
3190 //***************************************************************************
3197 //***************************************************************************
3198 template <typename T>
3199 bool operator>=(const T* lhs, const etl::ibasic_string<T>& rhs)
3200 {
3201 return !(lhs < rhs);
3202 }
3203
3204 //***************************************************************************
3210 //***************************************************************************
3211#if ETL_USING_STD_OSTREAM
3212 template <typename T>
3213 std::basic_ostream<T, std::char_traits<T> >& operator<<(std::basic_ostream<T, std::char_traits<T> >& os, const etl::ibasic_string<T>& str)
3214 {
3215 os.write(str.data(), static_cast<std::streamsize>(str.size()));
3216 return os;
3217 }
3218#endif
3219} // namespace etl
3220
3221#undef ETL_USING_WCHAR_T_H
3222
3223#include "private/minmax_pop.h"
3224
3225#endif
String view.
Definition string_view.h:117
ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:239
ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the array.
Definition string_view.h:307
ETL_CONSTEXPR const_reverse_iterator rend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the array.
Definition string_view.h:279
ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
Returns a const pointer to the first element of the internal storage.
Definition string_view.h:223
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:247
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:231
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:263
Definition flags.h:53
Definition basic_string.h:350
int compare(size_type position, size_type length_, const ibasic_string &str) const
Compare position / length with string.
Definition basic_string.h:1928
ibasic_string & append(TIterator first, TIterator last)
Definition basic_string.h:869
size_type find_last_of(const_pointer s, size_type position=npos) const
Definition basic_string.h:2096
size_type rfind(const_pointer s, size_type position=npos) const
Definition basic_string.h:1534
ibasic_string & replace(const_iterator first, const_iterator last, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1752
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:1822
etl::ibasic_string< T > & insert(size_type position, const etl::ibasic_string< T > &str)
Definition basic_string.h:1189
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:1832
size_type find_last_not_of(const_pointer s, size_type position=npos) const
Definition basic_string.h:2275
size_type find(const_pointer s, size_type pos=0) const
Definition basic_string.h:1469
ibasic_string & operator=(const ibasic_string &rhs)
Assignment operator.
Definition basic_string.h:2363
ibasic_string & append(const ibasic_string &str, size_type subposition, size_type sublength=npos)
Definition basic_string.h:849
const_reverse_iterator rbegin() const
Definition basic_string.h:434
bool contains(const etl::ibasic_string< T > &str) const
Checks that the string is within this string.
Definition basic_string.h:1586
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:701
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:1266
pointer data_end()
Definition basic_string.h:666
iterator erase(const_iterator first, const_iterator last)
Definition basic_string.h:1384
iterator insert(const_iterator position, TIterator first, TIterator last)
Definition basic_string.h:1086
bool is_within_buffer(const_pointer ptr) const
Checks if a pointer is within the buffer.
Definition basic_string.h:2711
bool contains(value_type c) const
Checks that character is within this string.
Definition basic_string.h:1611
size_type find_last_of(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:2086
size_type find_first_of(value_type c, size_type position=0) const
Definition basic_string.h:2065
bool starts_with(const etl::ibasic_string< T > &str) const
Checks that the string is the start of this string.
Definition basic_string.h:1619
size_type find(T c, size_type position=0) const
Definition basic_string.h:1494
ibasic_string & replace(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view, size_type subposition, size_type sublength)
Definition basic_string.h:1778
bool ends_with(value_type c) const
Checks that the character is the end of this string.
Definition basic_string.h:1696
void pop_back()
Definition basic_string.h:824
size_type rfind(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:1513
bool contains(const_pointer s) const
Checks that text is within this string.
Definition basic_string.h:1603
etl::ibasic_string< T > & insert(size_type position, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1215
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:2445
ibasic_string & replace(size_type position, size_type length_, const_pointer s, size_type n)
Definition basic_string.h:1841
iterator to_iterator(const_iterator itr) const
Convert from const_iterator to iterator.
Definition basic_string.h:2703
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:1854
const_reference operator[](size_type i) const
Definition basic_string.h:572
ibasic_string & replace(const_iterator first, const_iterator last, const ibasic_string &str)
Definition basic_string.h:1740
size_type find_first_of(const ibasic_string< T > &str, size_type position=0) const
Definition basic_string.h:2009
size_type find_first_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=0) const
Definition basic_string.h:2030
const_reference back() const
Definition basic_string.h:638
void assign(const_pointer str, size_type n)
Definition basic_string.h:748
const_iterator begin() const
Definition basic_string.h:380
size_type find_last_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2118
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:1668
reverse_iterator rbegin()
Definition basic_string.h:425
ibasic_string & replace(const_iterator first, const_iterator last, TIterator first_replace, TIterator last_replace)
Definition basic_string.h:1893
void resize(size_type new_size)
Definition basic_string.h:480
size_type find_last_not_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2297
ibasic_string & replace(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1724
size_type find_first_not_of(const_pointer s, size_type position=0) const
Definition basic_string.h:2191
size_type rfind(T c, size_type position=npos) const
Definition basic_string.h:1562
etl::ibasic_string< T > & erase(size_type position, size_type length_=npos)
Definition basic_string.h:1329
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:1991
iterator insert(const_iterator position, size_type n, T value)
Definition basic_string.h:996
ibasic_string & append(const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:904
const_reference at(size_type i) const
Definition basic_string.h:598
void assign(const etl::basic_string_view< T, TOtherTraits > &view)
Assigns values to the string from a view.
Definition basic_string.h:757
ibasic_string & operator+=(const_pointer rhs)
+= operator.
Definition basic_string.h:2418
void clear()
Clears the string.
Definition basic_string.h:790
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:1950
reverse_iterator rend()
Definition basic_string.h:443
ibasic_string & operator=(const etl::basic_string_view< T, TOtherTraits > &view)
Assignment operator.
Definition basic_string.h:2387
size_type find_last_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=npos) const
Definition basic_string.h:2107
iterator erase(iterator i_element)
Definition basic_string.h:1347
ibasic_string & append(const_pointer str, size_type n)
Definition basic_string.h:892
const_reverse_iterator crend() const
Definition basic_string.h:470
bool contains(const etl::basic_string_view< T, TOtherTraits > &view) const
Checks that the view is within this string.
Definition basic_string.h:1595
reference at(size_type i)
Definition basic_string.h:585
size_type rfind(const etl::basic_string_view< T, TOtherTraits > &view, size_type pos=0) const
Definition basic_string.h:1524
bool starts_with(value_type c) const
Checks that the character is the start of this string.
Definition basic_string.h:1646
int compare(const etl::basic_string_view< T, TOtherTraits > &view) const
Compare with etl::basic_string_view.
Definition basic_string.h:1920
~ibasic_string()
Destructor.
Definition basic_string.h:2688
size_type find(const_pointer s, size_type pos, size_type n) const
Definition basic_string.h:1482
size_type find_first_of(const_pointer s, size_type position=0) const
Definition basic_string.h:2019
ibasic_string & replace(size_type position, size_type length_, const ibasic_string &str, size_type subposition, size_type sublength)
Definition basic_string.h:1761
iterator begin()
Definition basic_string.h:371
iterator end()
Definition basic_string.h:389
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:1873
ibasic_string & replace(const_iterator first, const_iterator last, const_pointer s, size_type n)
Definition basic_string.h:1813
void assign(TIterator first, TIterator last)
Definition basic_string.h:727
etl::ibasic_string< T > & insert(size_type position, const etl::ibasic_string< T > &str, size_type subposition, size_type sublength)
Definition basic_string.h:1232
size_type find(const ibasic_string< T > &str, size_type pos=0) const
Definition basic_string.h:1448
void push_back(T value)
Definition basic_string.h:801
size_type find_first_not_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2213
const_reverse_iterator crbegin() const
Definition basic_string.h:461
iterator insert(const_iterator position, T value)
Definition basic_string.h:942
ibasic_string & operator=(const_pointer rhs)
Assignment operator.
Definition basic_string.h:2376
etl::ibasic_string< T > & insert(size_type position, const_pointer s, size_type n)
Definition basic_string.h:1301
ibasic_string & replace(size_type position, size_type length_, const ibasic_string &str)
Definition basic_string.h:1707
ibasic_string(T *p_buffer_, size_type MAX_SIZE_)
Constructor.
Definition basic_string.h:2473
bool ends_with(const_pointer s) const
Checks that the string is the end of this string.
Definition basic_string.h:1681
etl::ibasic_string< T > & insert(size_type position, size_type n, value_type c)
Definition basic_string.h:1315
const_reverse_iterator rend() const
Definition basic_string.h:452
size_type find_last_not_of(const ibasic_string< T > &str, size_type position=npos) const
Definition basic_string.h:2265
size_type find(const etl::basic_string_view< T, TOtherTraits > &view, size_type pos=0) const
Definition basic_string.h:1459
const_pointer data_end() const
Definition basic_string.h:675
void assign(const etl::ibasic_string< T > &other)
Definition basic_string.h:685
const_iterator cend() const
Definition basic_string.h:416
const_pointer c_str() const
Return a pointer to a C string.
Definition basic_string.h:1409
void resize(size_type new_size, T value)
Definition basic_string.h:491
ETL_CONSTEXPR const_pointer data() const
Definition basic_string.h:657
const_reference front() const
Definition basic_string.h:618
ibasic_string & operator+=(const etl::basic_string_view< T, TOtherTraits > &rhs)
+= operator.
Definition basic_string.h:2408
pointer data()
Definition basic_string.h:648
size_type find_first_not_of(value_type c, size_type position=0) const
Definition basic_string.h:2244
ibasic_string & append(const_pointer str)
Definition basic_string.h:880
ibasic_string & append(size_type n, T c)
Definition basic_string.h:916
size_type find_first_not_of(const ibasic_string< T > &str, size_type position=0) const
Definition basic_string.h:2181
size_type find_last_of(value_type c, size_type position=npos) const
Definition basic_string.h:2151
size_type copy(pointer dest, size_type count, size_type pos=0) const
Definition basic_string.h:1420
ibasic_string & append(const ibasic_string &str)
Definition basic_string.h:836
size_type find_last_not_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=npos) const
Definition basic_string.h:2286
ibasic_string & operator+=(T rhs)
+= operator.
Definition basic_string.h:2428
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:1794
reference front()
Definition basic_string.h:608
reference back()
Definition basic_string.h:628
bool starts_with(const_pointer s) const
Checks that the string is the start of this string.
Definition basic_string.h:1636
const_iterator cbegin() const
Definition basic_string.h:407
size_type find_first_not_of(const etl::basic_string_view< T, TOtherTraits > &view, size_type position=0) const
Definition basic_string.h:2202
int compare(size_type position, size_type length_, const etl::basic_string_view< T, TOtherTraits > &view, size_type subposition, size_type sublength) const
Definition basic_string.h:1967
void assign(size_type n, T c)
Definition basic_string.h:768
void initialise()
Initialise the string.
Definition basic_string.h:2482
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:1628
ibasic_string & operator+=(const ibasic_string &rhs)
+= operator.
Definition basic_string.h:2397
void trim_to_terminator()
Definition basic_string.h:2458
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:1999
size_type rfind(const_pointer s, size_type position, size_type length_) const
Definition basic_string.h:1549
bool ends_with(const etl::ibasic_string< T > &str) const
Checks that the string is the end of this string.
Definition basic_string.h:1654
size_type find_first_of(const_pointer s, size_type position, size_type n) const
Definition basic_string.h:2041
int compare(const ibasic_string &str) const
Compare with string.
Definition basic_string.h:1911
const_iterator end() const
Definition basic_string.h:398
iterator erase(const_iterator i_element)
Definition basic_string.h:1363
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:1942
etl::ibasic_string< T > & insert(size_type position, const_pointer s)
Definition basic_string.h:1286
void assign(const_pointer str)
Definition basic_string.h:737
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:2494
iterator insert(const_iterator position, const etl::basic_string_view< T, TOtherTraits > &view)
Definition basic_string.h:1179
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:335
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:334
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:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
Definition integral_limits.h:518
void memory_clear_range(volatile T *begin, size_t n)
Definition memory.h:2561
Definition basic_string.h:157
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
T * mem_move(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2877
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:3213
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:2974
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1133
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1147
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
T * mem_copy(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2835
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:293
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1106
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1120
iterator
Definition iterator.h:424
remove_pointer
Definition type_traits.h:147