Embedded Template Library 1.0
Loading...
Searching...
No Matches
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_STRING_INCLUDED
32#define ETL_STRING_INCLUDED
33
34#include "platform.h"
35#include "basic_string.h"
36#include "hash.h"
37#include "initializer_list.h"
38#include "string_view.h"
39
40#include <ctype.h>
41
42#include "private/minmax_push.h"
43
44namespace etl
45{
46#if ETL_USING_CPP11
47 inline namespace literals
48 {
49 inline namespace string_literals
50 {
51 inline constexpr etl::string_view operator""_sv(const char* str, size_t length) ETL_NOEXCEPT
52 {
53 return etl::string_view{str, length};
54 }
55 } // namespace string_literals
56 } // namespace literals
57#endif
58
59 typedef etl::ibasic_string<char> istring;
60
61 //***************************************************************************
65 //***************************************************************************
66 template <size_t MAX_SIZE_>
67 class string : public istring
68 {
69 public:
70
71 typedef istring base_type;
72 typedef istring interface_type;
73
74 typedef istring::value_type value_type;
75 typedef istring::size_type size_type;
76
77 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
78
79 //*************************************************************************
81 //*************************************************************************
83 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
84 {
85 this->initialise();
86 }
87
88 //*************************************************************************
91 //*************************************************************************
93 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
94 {
95 this->assign(other);
96 }
97
98 //*************************************************************************
101 //*************************************************************************
102 string(const etl::istring& other)
103 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
104 {
105 this->assign(other);
106 }
107
108 //*************************************************************************
113 //*************************************************************************
114 string(const etl::istring& other, size_t position, size_t length = npos)
115 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
116 {
117 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
118
119 this->assign(other, position, length);
120 }
121
122 //*************************************************************************
125 //*************************************************************************
126 ETL_EXPLICIT_STRING_FROM_CHAR string(const value_type* text)
127 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
128 {
129 this->assign(text);
130 }
131
132 //*************************************************************************
136 //*************************************************************************
137 string(const value_type* text, size_t count)
138 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
139 {
140 this->assign(text, text + count);
141 }
142
143 //*************************************************************************
147 //*************************************************************************
148 string(size_type count, value_type c)
149 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
150 {
151 this->initialise();
152 this->resize(count, c);
153 }
154
155 //*************************************************************************
160 //*************************************************************************
161 template <typename TIterator>
162 string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
163 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
164 {
165 this->assign(first, last);
166 }
167
168#if ETL_HAS_INITIALIZER_LIST
169 //*************************************************************************
171 //*************************************************************************
172 string(std::initializer_list<value_type> init)
173 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
174 {
175 this->assign(init.begin(), init.end());
176 }
177#endif
178
179 //*************************************************************************
182 //*************************************************************************
183 explicit string(const etl::string_view& view)
184 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
185 {
186 this->assign(view.begin(), view.end());
187 }
188
189 //*************************************************************************
193 //*************************************************************************
194 etl::string<MAX_SIZE_> substr(size_type position = 0, size_type length_ = npos) const
195 {
196 etl::string<MAX_SIZE_> new_string;
197
198 if (position != this->size())
199 {
200 ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds));
201
202 length_ = etl::min(length_, this->size() - position);
203
204 new_string.assign(buffer + position, buffer + position + length_);
205 }
206
207 return new_string;
208 }
209
210 //*************************************************************************
212 //*************************************************************************
213 string& operator=(const string& rhs)
214 {
215 if (&rhs != this)
216 {
217 this->assign(rhs);
218 }
219
220 return *this;
221 }
222
223 //*************************************************************************
225 //*************************************************************************
226 string& operator=(const istring& rhs)
227 {
228 if (&rhs != this)
229 {
230 this->assign(rhs);
231 }
232
233 return *this;
234 }
235
236 //*************************************************************************
238 //*************************************************************************
239 string& operator=(const value_type* text)
240 {
241 this->assign(text);
242
243 return *this;
244 }
245
246 //*************************************************************************
248 //*************************************************************************
249 string& operator=(const etl::string_view& view)
250 {
251 this->assign(view);
252
253 return *this;
254 }
255
256 //*************************************************************************
258 //*************************************************************************
259#if ETL_HAS_ISTRING_REPAIR
260 virtual void repair() ETL_OVERRIDE
261#else
262 void repair()
263#endif
264 {
266 }
267
268 private:
269
270 value_type buffer[MAX_SIZE + 1];
271 };
272
273 template <size_t MAX_SIZE_>
274 ETL_CONSTANT typename string<MAX_SIZE_>::size_type string<MAX_SIZE_>::MAX_SIZE;
275
276 //***************************************************************************
279 //***************************************************************************
280 class string_ext : public istring
281 {
282 public:
283
284 typedef istring base_type;
285 typedef istring interface_type;
286
287 typedef istring::value_type value_type;
288 typedef istring::size_type size_type;
289
290 //*************************************************************************
292 //*************************************************************************
293 string_ext(value_type* buffer, size_type buffer_size)
294 : istring(buffer, buffer_size - 1U)
295 {
296 this->initialise();
297 }
298
299 //*************************************************************************
302 //*************************************************************************
303 template <size_t Size>
304 string_ext(value_type (&buffer)[Size])
305 : istring(buffer, Size - 1U)
306 {
307 this->initialise();
308 }
309
310 //*************************************************************************
313 //*************************************************************************
314 string_ext(const etl::string_ext& other, value_type* buffer, size_type buffer_size)
315 : istring(buffer, buffer_size - 1U)
316 {
317 if (this->is_within_buffer(other.data()))
318 {
319 this->current_size = other.size();
320 }
321 else
322 {
323 this->assign(other);
324 }
325 }
326
327 //*************************************************************************
330 //*************************************************************************
331 string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size)
332 : istring(buffer, buffer_size - 1U)
333 {
334 if (this->is_within_buffer(other.data()))
335 {
336 this->current_size = other.size();
337 }
338 else
339 {
340 this->assign(other);
341 }
342 }
343
344 //*************************************************************************
348 //*************************************************************************
349 template <size_t BufferSize>
350 string_ext(const etl::istring& other, value_type (&buffer)[BufferSize])
351 : istring(buffer, BufferSize - 1U)
352 {
353 if (this->is_within_buffer(other.data()))
354 {
355 this->current_size = other.size();
356 }
357 else
358 {
359 this->assign(other);
360 }
361 }
362
363 //*************************************************************************
368 //*************************************************************************
369 string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size, size_type position, size_type length = npos)
370 : istring(buffer, buffer_size - 1U)
371 {
372 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
373
374 if (this->is_within_buffer(other.data()))
375 {
376 this->current_size = other.size();
377 }
378 else
379 {
380 this->assign(other, position, length);
381 }
382 }
383
384 //*************************************************************************
390 //*************************************************************************
391 template <size_t BufferSize>
392 string_ext(const etl::istring& other, value_type (&buffer)[BufferSize], size_type position, size_type length = npos)
393 : istring(buffer, BufferSize - 1U)
394 {
395 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
396
397 if (this->is_within_buffer(other.data()))
398 {
399 this->current_size = other.size();
400 }
401 else
402 {
403 this->assign(other, position, length);
404 }
405 }
406
407 //*************************************************************************
410 //*************************************************************************
411 template <typename TPointer>
412 string_ext(TPointer text, value_type* buffer, size_type buffer_size,
413 typename etl::enable_if<etl::is_same<const value_type*, TPointer>::value, int>::type* = ETL_NULLPTR)
414 : istring(buffer, buffer_size - 1U)
415 {
416 if (this->is_within_buffer(text))
417 {
418 this->current_size = etl::strlen(buffer);
419 }
420 else
421 {
422 this->assign(text);
423 }
424 }
425
426 //*************************************************************************
430 //*************************************************************************
431 template <typename TPointer, size_t BufferSize>
432 string_ext(TPointer text, value_type (&buffer)[BufferSize],
433 typename etl::enable_if<etl::is_same<const value_type*, TPointer>::value, int>::type* = ETL_NULLPTR)
434 : istring(buffer, BufferSize - 1U)
435 {
436 if (this->is_within_buffer(text))
437 {
438 this->current_size = etl::strlen(buffer);
439 }
440 else
441 {
442 this->assign(text);
443 }
444 }
445
446 //*************************************************************************
449 //*************************************************************************
450 template <size_t Size>
451 string_ext(const value_type (&literal)[Size], value_type* buffer, size_type buffer_size)
452 : istring(buffer, buffer_size - 1U)
453 {
454 if (this->is_within_buffer(literal))
455 {
456 this->current_size = etl::strlen(literal);
457 }
458 else
459 {
460 this->assign(literal);
461 }
462 }
463
464 //*************************************************************************
468 //*************************************************************************
469 template <size_t LiteralSize, size_t BufferSize>
470 string_ext(const value_type (&literal)[LiteralSize], value_type (&buffer)[BufferSize])
471 : istring(buffer, BufferSize - 1U)
472 {
473 if (this->is_within_buffer(literal))
474 {
475 this->current_size = etl::strlen(literal);
476 }
477 else
478 {
479 this->assign(literal);
480 }
481 }
482
483 //*************************************************************************
487 //*************************************************************************
488 string_ext(const value_type* text, size_type count, value_type* buffer, size_type buffer_size)
489 : istring(buffer, buffer_size - 1U)
490 {
491 if (this->is_within_buffer(text))
492 {
493 this->current_size = count;
494 }
495 else
496 {
497 this->assign(text, text + count);
498 }
499 }
500
501 //*************************************************************************
506 //*************************************************************************
507 template <size_t BufferSize>
508 string_ext(const value_type* text, size_type count, value_type (&buffer)[BufferSize])
509 : istring(buffer, BufferSize - 1U)
510 {
511 if (this->is_within_buffer(text))
512 {
513 this->current_size = count;
514 }
515 else
516 {
517 this->assign(text, text + count);
518 }
519 }
520
521 //*************************************************************************
525 //*************************************************************************
526 string_ext(size_type count, value_type c, value_type* buffer, size_type buffer_size)
527 : istring(buffer, buffer_size - 1U)
528 {
529 this->initialise();
530 this->resize(count, c);
531 }
532
533 //*************************************************************************
538 //*************************************************************************
539 template <size_t BufferSize>
540 string_ext(size_type count, value_type c, value_type (&buffer)[BufferSize])
541 : istring(buffer, BufferSize - 1U)
542 {
543 this->initialise();
544 this->resize(count, c);
545 }
546
547 //*************************************************************************
550 //*************************************************************************
551 explicit string_ext(const etl::string_view& view, value_type* buffer, size_type buffer_size)
552 : istring(buffer, buffer_size - 1U)
553 {
554 if (this->is_within_buffer(view.data()))
555 {
556 this->current_size = view.size();
557 }
558 else
559 {
560 this->assign(view.begin(), view.end());
561 }
562 }
563
564 //*************************************************************************
568 //*************************************************************************
569 template <size_t BufferSize>
570 explicit string_ext(const etl::string_view& view, value_type (&buffer)[BufferSize])
571 : istring(buffer, BufferSize - 1U)
572 {
573 if (this->is_within_buffer(view.data()))
574 {
575 this->current_size = view.size();
576 }
577 else
578 {
579 this->assign(view.begin(), view.end());
580 }
581 }
582
583 //*************************************************************************
588 //*************************************************************************
589 template <typename TIterator>
590 string_ext(TIterator first, TIterator last, value_type* buffer, size_type buffer_size,
591 typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
592 : istring(buffer, buffer_size - 1U)
593 {
594 if (this->is_within_buffer(etl::addressof(*first)))
595 {
596 this->current_size = static_cast<size_type>(etl::distance(first, last));
597 }
598 else
599 {
600 this->assign(first, last);
601 }
602 }
603
604 //*************************************************************************
610 //*************************************************************************
611 template <typename TIterator, size_t BufferSize>
612 string_ext(TIterator first, TIterator last, value_type (&buffer)[BufferSize],
613 typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
614 : istring(buffer, BufferSize - 1U)
615 {
616 if (this->is_within_buffer(etl::addressof(*first)))
617 {
618 this->current_size = static_cast<size_type>(etl::distance(first, last));
619 }
620 else
621 {
622 this->assign(first, last);
623 }
624 }
625
626#if ETL_HAS_INITIALIZER_LIST
627 //*************************************************************************
629 //*************************************************************************
630 string_ext(std::initializer_list<value_type> init, value_type* buffer, size_type buffer_size)
631 : istring(buffer, buffer_size - 1U)
632 {
633 this->assign(init.begin(), init.end());
634 }
635
636 //*************************************************************************
640 //*************************************************************************
641 template <size_t BufferSize>
642 string_ext(std::initializer_list<value_type> init, value_type (&buffer)[BufferSize])
643 : istring(buffer, BufferSize - 1U)
644 {
645 this->assign(init.begin(), init.end());
646 }
647#endif
648
649 //*************************************************************************
651 //*************************************************************************
653 {
654 if (&rhs != this)
655 {
656 this->assign(rhs);
657 }
658
659 return *this;
660 }
661
662 //*************************************************************************
664 //*************************************************************************
665 string_ext& operator=(const istring& rhs)
666 {
667 if (&rhs != this)
668 {
669 this->assign(rhs);
670 }
671
672 return *this;
673 }
674
675 //*************************************************************************
677 //*************************************************************************
678 string_ext& operator=(const value_type* text)
679 {
680 this->assign(text);
681
682 return *this;
683 }
684
685 //*************************************************************************
687 //*************************************************************************
688 string_ext& operator=(const etl::string_view& view)
689 {
690 this->assign(view);
691
692 return *this;
693 }
694
695 //*************************************************************************
697 //*************************************************************************
698#if ETL_HAS_ISTRING_REPAIR
699 virtual void repair() ETL_OVERRIDE
700#else
701 void repair()
702#endif
703 {
704 }
705
706 private:
707
708 //*************************************************************************
710 //*************************************************************************
711 string_ext(const string_ext& other) ETL_DELETE;
712 };
713
714 //*************************************************************************
716 //*************************************************************************
717#if ETL_USING_8BIT_TYPES
718 template <>
719 struct hash<etl::istring>
720 {
721 size_t operator()(const etl::istring& text) const
722 {
723 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
724 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
725 }
726 };
727
728 template <size_t SIZE>
729 struct hash<etl::string<SIZE> >
730 {
731 size_t operator()(const etl::string<SIZE>& text) const
732 {
733 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
734 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
735 }
736 };
737
738 template <>
739 struct hash<etl::string_ext>
740 {
741 size_t operator()(const etl::string_ext& text) const
742 {
743 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
744 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
745 }
746 };
747#endif
748
749 //***************************************************************************
751 //***************************************************************************
752 template <size_t Array_Size>
753 etl::string<Array_Size - 1U> make_string(const char (&text)[Array_Size])
754 {
755 return etl::string<Array_Size - 1U>(text, etl::strlen(text, Array_Size - 1));
756 }
757
758 //***************************************************************************
760 //***************************************************************************
761 template <size_t MAX_SIZE, size_t SIZE>
763 {
764 return etl::string<MAX_SIZE>(text, etl::strlen(text, SIZE));
765 }
766} // namespace etl
767
768#include "private/minmax_pop.h"
769
770#endif
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
bool is_within_buffer(const_pointer ptr) const
Definition basic_string.h:2711
void resize(size_type new_size)
Definition basic_string.h:480
void assign(const etl::ibasic_string< char > &other)
Definition basic_string.h:685
pointer data()
Definition basic_string.h:648
void initialise()
Definition basic_string.h:2482
void repair_buffer(char *p_buffer_)
Definition basic_string.h:2494
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 size() const
Definition basic_string.h:193
Definition string.h:281
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size, size_type position, size_type length=npos)
Definition string.h:369
string_ext(const etl::istring &other, value_type(&buffer)[BufferSize])
Definition string.h:350
string_ext(const value_type(&literal)[LiteralSize], value_type(&buffer)[BufferSize])
Definition string.h:470
string_ext(value_type *buffer, size_type buffer_size)
Constructor.
Definition string.h:293
string_ext(const etl::string_ext &other, value_type *buffer, size_type buffer_size)
Definition string.h:314
string_ext(TPointer text, value_type(&buffer)[BufferSize], typename etl::enable_if< etl::is_same< const value_type *, TPointer >::value, int >::type *=ETL_NULLPTR)
Definition string.h:432
string_ext(const etl::string_view &view, value_type *buffer, size_type buffer_size)
Definition string.h:551
string_ext(const etl::string_view &view, value_type(&buffer)[BufferSize])
Definition string.h:570
string_ext(size_type count, value_type c, value_type *buffer, size_type buffer_size)
Definition string.h:526
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size)
Definition string.h:331
string_ext & operator=(const etl::string_view &view)
Assignment operator.
Definition string.h:688
string_ext(TIterator first, TIterator last, value_type(&buffer)[BufferSize], typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:612
string_ext(const value_type(&literal)[Size], value_type *buffer, size_type buffer_size)
Definition string.h:451
string_ext(TPointer text, value_type *buffer, size_type buffer_size, typename etl::enable_if< etl::is_same< const value_type *, TPointer >::value, int >::type *=ETL_NULLPTR)
Definition string.h:412
void repair()
Fix the internal pointers after a low level memory copy.
Definition string.h:701
string_ext & operator=(const value_type *text)
Assignment operator.
Definition string.h:678
string_ext & operator=(const istring &rhs)
Assignment operator.
Definition string.h:665
string_ext(size_type count, value_type c, value_type(&buffer)[BufferSize])
Definition string.h:540
string_ext(const value_type *text, size_type count, value_type *buffer, size_type buffer_size)
Definition string.h:488
string_ext(value_type(&buffer)[Size])
Definition string.h:304
string_ext(const value_type *text, size_type count, value_type(&buffer)[BufferSize])
Definition string.h:508
string_ext(TIterator first, TIterator last, value_type *buffer, size_type buffer_size, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:590
string_ext & operator=(const string_ext &rhs)
Assignment operator.
Definition string.h:652
string_ext(const etl::istring &other, value_type(&buffer)[BufferSize], size_type position, size_type length=npos)
Definition string.h:392
Definition basic_string.h:115
Definition string.h:68
etl::string< MAX_SIZE_ > substr(size_type position=0, size_type length_=npos) const
Definition string.h:194
string & operator=(const istring &rhs)
Assignment operator.
Definition string.h:226
void repair()
Fix the internal pointers after a low level memory copy.
Definition string.h:262
string & operator=(const value_type *text)
Assignment operator.
Definition string.h:239
string()
Constructor.
Definition string.h:82
string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:162
string(const etl::string_view &view)
Definition string.h:183
string(const etl::string< MAX_SIZE_ > &other)
Definition string.h:92
string(const etl::istring &other)
Definition string.h:102
string & operator=(const string &rhs)
Assignment operator.
Definition string.h:213
string(const etl::istring &other, size_t position, size_t length=npos)
Definition string.h:114
string(const value_type *text, size_t count)
Definition string.h:137
string & operator=(const etl::string_view &view)
Assignment operator.
Definition string.h:249
ETL_EXPLICIT_STRING_FROM_CHAR string(const value_type *text)
Definition string.h:126
string(size_type count, value_type c)
Definition string.h:148
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
bitset_ext
Definition absolute.h:40
etl::string< Array_Size - 1U > make_string(const char(&text)[Array_Size])
Hash function.
Definition string.h:753
etl::string< MAX_SIZE > make_string_with_capacity(const char(&text)[SIZE])
Make string with max capacity from string literal or array.
Definition string.h:762
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:293