Embedded Template Library 1.0
Loading...
Searching...
No Matches
u8string.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) 2023 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_U8STRING_INCLUDED
32#define ETL_U8STRING_INCLUDED
33
34#include "platform.h"
35#include "basic_string.h"
36#include "string_view.h"
37#include "hash.h"
38#include "initializer_list.h"
39
40#include <ctype.h>
41
42#include "private/minmax_push.h"
43
44#if ETL_HAS_CHAR8_T
45namespace etl
46{
47#if ETL_USING_CPP11 && ETL_HAS_NATIVE_CHAR8_T
48 inline namespace literals
49 {
50 inline namespace string_literals
51 {
52 inline constexpr etl::u8string_view operator ""_sv(const char8_t* str, size_t length) ETL_NOEXCEPT
53 {
54 return etl::u8string_view{ str, length };
55 }
56 }
57 }
58#endif
59
60 typedef etl::ibasic_string<char8_t> iu8string;
61
62 //***************************************************************************
66 //***************************************************************************
67 template <size_t MAX_SIZE_>
68 class u8string : public iu8string
69 {
70 public:
71
72 typedef iu8string base_type;
73 typedef iu8string interface_type;
74
75 typedef iu8string::value_type value_type;
76
77 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
78
79 //*************************************************************************
81 //*************************************************************************
83 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
84 {
85 this->initialise();
86 }
87
88 //*************************************************************************
91 //*************************************************************************
93 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
94 {
95 this->initialise();
96 this->assign(other);
97 }
98
99 //*************************************************************************
102 //*************************************************************************
103 u8string(const etl::iu8string& other)
104 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
105 {
106 this->initialise();
107 this->assign(other);
108 }
109
110 //*************************************************************************
115 //*************************************************************************
116 u8string(const etl::iu8string& other, size_t position, size_t length = npos)
117 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
118 {
119 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
120
121 this->initialise();
122 this->assign(other, position, length);
123 }
124
125 //*************************************************************************
128 //*************************************************************************
129 ETL_EXPLICIT_STRING_FROM_CHAR u8string(const value_type* text)
130 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
131 {
132 this->initialise();
133 this->assign(text);
134 }
135
136 //*************************************************************************
140 //*************************************************************************
141 u8string(const value_type* text, size_t count)
142 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
143 {
144 this->initialise();
145 this->assign(text, text + count);
146 }
147
148 //*************************************************************************
152 //*************************************************************************
153 u8string(size_type count, value_type c)
154 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
155 {
156 this->initialise();
157 this->resize(count, c);
158 }
159
160 //*************************************************************************
165 //*************************************************************************
166 template <typename TIterator>
167 u8string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
168 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
169 {
170 this->initialise();
171 this->assign(first, last);
172 }
173
174#if ETL_HAS_INITIALIZER_LIST
175 //*************************************************************************
177 //*************************************************************************
178 u8string(std::initializer_list<value_type> init)
179 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
180 {
181 this->initialise();
182 this->assign(init.begin(), init.end());
183 }
184#endif
185
186 //*************************************************************************
189 //*************************************************************************
190 explicit u8string(const etl::u8string_view& view)
191 : iu8string(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
192 {
193 this->initialise();
194 this->assign(view.begin(), view.end());
195 }
196
197 //*************************************************************************
201 //*************************************************************************
202 etl::u8string<MAX_SIZE_> substr(size_type position = 0, size_type length_ = npos) const
203 {
204 etl::u8string<MAX_SIZE_> new_string;
205
206 if (position != this->size())
207 {
208 ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds));
209
210 length_ = etl::min(length_, this->size() - position);
211
212 new_string.assign(buffer + position, buffer + position + length_);
213 }
214
215 return new_string;
216 }
217
218 //*************************************************************************
220 //*************************************************************************
222 {
223 if (&rhs != this)
224 {
225 this->assign(rhs);
226 }
227
228 return *this;
229 }
230
231
232 //*************************************************************************
234 //*************************************************************************
235 u8string& operator = (const iu8string& rhs)
236 {
237 if (&rhs != this)
238 {
239 this->assign(rhs);
240 }
241
242 return *this;
243 }
244
245 //*************************************************************************
247 //*************************************************************************
248 u8string& operator = (const value_type* text)
249 {
250 this->assign(text);
251
252 return *this;
253 }
254
255 //*************************************************************************
257 //*************************************************************************
258 u8string& operator = (const etl::u8string_view& view)
259 {
260 this->assign(view);
261
262 return *this;
263 }
264
265 //*************************************************************************
267 //*************************************************************************
268#if ETL_HAS_ISTRING_REPAIR
269 virtual void repair() ETL_OVERRIDE
270#else
271 void repair()
272#endif
273 {
275 }
276
277 private:
278
279 value_type buffer[MAX_SIZE + 1];
280 };
281
282 template <size_t MAX_SIZE_>
283 ETL_CONSTANT size_t u8string<MAX_SIZE_>::MAX_SIZE;
284
285 //***************************************************************************
288 //***************************************************************************
289 class u8string_ext : public iu8string
290 {
291 public:
292
293 typedef iu8string base_type;
294 typedef iu8string interface_type;
295
296 typedef iu8string::value_type value_type;
297 typedef iu8string::size_type size_type;
298
299 //*************************************************************************
301 //*************************************************************************
302 u8string_ext(value_type* buffer, size_type buffer_size)
303 : iu8string(buffer, buffer_size - 1U)
304 {
305 this->initialise();
306 }
307
308 //*************************************************************************
311 //*************************************************************************
312 u8string_ext(const etl::u8string_ext& other, value_type* buffer, size_type buffer_size)
313 : iu8string(buffer, buffer_size - 1U)
314 {
315 if (this->is_within_buffer(other.data()))
316 {
317 this->current_size = other.size();
318 }
319 else
320 {
321 this->initialise();
322 this->assign(other);
323 }
324 }
325
326 //*************************************************************************
329 //*************************************************************************
330 u8string_ext(const etl::iu8string& other, value_type* buffer, size_type buffer_size)
331 : iu8string(buffer, buffer_size - 1U)
332 {
333 if (this->is_within_buffer(other.data()))
334 {
335 this->current_size = other.size();
336 }
337 else
338 {
339 this->initialise();
340 this->assign(other);
341 }
342 }
343
344 //*************************************************************************
349 //*************************************************************************
350 u8string_ext(const etl::iu8string& other, value_type* buffer, size_type buffer_size, size_type position, size_type length = npos)
351 : iu8string(buffer, buffer_size - 1U)
352 {
353 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
354
355 if (this->is_within_buffer(other.data()))
356 {
357 this->current_size = other.size();
358 }
359 else
360 {
361 this->initialise();
362 this->assign(other, position, length);
363 }
364 }
365
366 //*************************************************************************
369 //*************************************************************************
370 template <typename TPointer>
371 u8string_ext(TPointer text, value_type* buffer, size_type buffer_size,
373 : iu8string(buffer, buffer_size - 1U)
374 {
375 if (this->is_within_buffer(text))
376 {
377 this->current_size = etl::strlen(buffer);
378 }
379 else
380 {
381 this->initialise();
382 this->assign(text, text + etl::strlen(text));
383 }
384 }
385
386 //*************************************************************************
389 //*************************************************************************
390 template <size_t Size>
391 u8string_ext(const value_type (&literal)[Size], value_type* buffer, size_type buffer_size)
392 : iu8string(buffer, buffer_size - 1U)
393 {
394 if (this->is_within_buffer(literal))
395 {
396 this->current_size = etl::strlen(literal);
397 }
398 else
399 {
400 this->initialise();
401 this->assign(literal);
402 }
403 }
404
405 //*************************************************************************
409 //*************************************************************************
410 u8string_ext(const value_type* text, size_type count, value_type* buffer, size_type buffer_size)
411 : iu8string(buffer, buffer_size - 1U)
412 {
413 if (this->is_within_buffer(text))
414 {
415 this->current_size = count;
416 }
417 else
418 {
419 this->initialise();
420 this->assign(text, text + count);
421 }
422 }
423
424 //*************************************************************************
428 //*************************************************************************
429 u8string_ext(size_type count, value_type c, value_type* buffer, size_type buffer_size)
430 : iu8string(buffer, buffer_size - 1U)
431 {
432 this->initialise();
433 this->resize(count, c);
434 }
435
436 //*************************************************************************
439 //*************************************************************************
440 explicit u8string_ext(const etl::u8string_view& view, value_type* buffer, size_type buffer_size)
441 : iu8string(buffer, buffer_size - 1U)
442 {
443 if (this->is_within_buffer(view.data()))
444 {
445 this->current_size = view.size();
446 }
447 else
448 {
449 this->initialise();
450 this->assign(view.begin(), view.end());
451 }
452 }
453
454 //*************************************************************************
459 //*************************************************************************
460 template <typename TIterator>
461 u8string_ext(TIterator first, TIterator last, value_type* buffer, size_type buffer_size, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
462 : iu8string(buffer, buffer_size - 1U)
463 {
464 if (this->is_within_buffer(etl::addressof(*first)))
465 {
466 this->current_size = etl::distance(first, last);
467 }
468 else
469 {
470 this->initialise();
471 this->assign(first, last);
472 }
473 }
474
475#if ETL_HAS_INITIALIZER_LIST
476 //*************************************************************************
478 //*************************************************************************
479 u8string_ext(std::initializer_list<value_type> init, value_type* buffer, size_type buffer_size)
480 : iu8string(buffer, buffer_size - 1U)
481 {
482 this->initialise();
483 this->assign(init.begin(), init.end());
484 }
485#endif
486
487 //*************************************************************************
489 //*************************************************************************
491 {
492 if (&rhs != this)
493 {
494 this->assign(rhs);
495 }
496
497 return *this;
498 }
499
500 //*************************************************************************
502 //*************************************************************************
503 u8string_ext& operator = (const iu8string& rhs)
504 {
505 if (&rhs != this)
506 {
507 this->assign(rhs);
508 }
509
510 return *this;
511 }
512
513 //*************************************************************************
515 //*************************************************************************
516 u8string_ext& operator = (const value_type* text)
517 {
518 this->assign(text);
519
520 return *this;
521 }
522
523 //*************************************************************************
525 //*************************************************************************
526 u8string_ext& operator = (const etl::u8string_view& view)
527 {
528 this->assign(view);
529
530 return *this;
531 }
532
533 //*************************************************************************
535 //*************************************************************************
536#if ETL_HAS_ISTRING_REPAIR
537 virtual void repair() ETL_OVERRIDE
538#else
539 void repair()
540#endif
541 {
542 }
543
544 private:
545
546 //*************************************************************************
548 //*************************************************************************
549 u8string_ext(const u8string_ext& other) ETL_DELETE;
550 };
551
552 //*************************************************************************
554 //*************************************************************************
555#if ETL_USING_8BIT_TYPES
557 template <>
558 struct hash<etl::iu8string>
559 {
560 size_t operator()(const etl::iu8string& text) const
561 {
562 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
563 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
564 }
565 };
566
567 template <size_t SIZE>
568 struct hash<etl::u8string<SIZE> >
569 {
570 size_t operator()(const etl::u8string<SIZE>& text) const
571 {
572 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
573 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
574 }
575 };
576
577 template <>
578 struct hash<etl::u8string_ext>
579 {
580 size_t operator()(const etl::u8string_ext& text) const
581 {
582 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
583 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
584 }
585 };
587#endif
588
589 //***************************************************************************
591 //***************************************************************************
592 template<size_t Array_Size>
593 etl::u8string<Array_Size - 1U> make_string(const char(&text)[Array_Size])
594 {
595 return etl::u8string<Array_Size - 1U>(text, etl::strlen(text, Array_Size - 1));
596 }
597
598 //***************************************************************************
600 //***************************************************************************
601 template<size_t MAX_SIZE, size_t SIZE>
603 {
604 return etl::u8string<MAX_SIZE>(text, etl::strlen(text, SIZE));
605 }
606}
607#endif
608
609#include "private/minmax_pop.h"
610
611#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:196
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:220
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:204
bool is_within_buffer(const_pointer ptr) const
Definition basic_string.h:2718
void resize(size_type new_size)
Definition basic_string.h:481
void assign(const etl::ibasic_string< char8_t > &other)
Definition basic_string.h:683
pointer data()
Definition basic_string.h:646
void initialise()
Definition basic_string.h:2491
void repair_buffer(char8_t *p_buffer_)
Definition basic_string.h:2503
size_type length() const
Definition basic_string.h:202
size_type current_size
The current number of elements in the string.
Definition basic_string.h:336
size_type size() const
Definition basic_string.h:193
Definition basic_string.h:115
Definition u8string.h:290
u8string_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 u8string.h:461
u8string_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 u8string.h:371
u8string_ext & operator=(const u8string_ext &rhs)
Assignment operator.
Definition u8string.h:490
u8string_ext(const etl::u8string_ext &other, value_type *buffer, size_type buffer_size)
Definition u8string.h:312
u8string_ext(const etl::iu8string &other, value_type *buffer, size_type buffer_size, size_type position, size_type length=npos)
Definition u8string.h:350
void repair()
Fix the internal pointers after a low level memory copy.
Definition u8string.h:539
u8string_ext(value_type *buffer, size_type buffer_size)
Constructor.
Definition u8string.h:302
u8string_ext(const value_type *text, size_type count, value_type *buffer, size_type buffer_size)
Definition u8string.h:410
u8string_ext(const etl::iu8string &other, value_type *buffer, size_type buffer_size)
Definition u8string.h:330
u8string_ext(const value_type(&literal)[Size], value_type *buffer, size_type buffer_size)
Definition u8string.h:391
u8string_ext(size_type count, value_type c, value_type *buffer, size_type buffer_size)
Definition u8string.h:429
u8string_ext(const etl::u8string_view &view, value_type *buffer, size_type buffer_size)
Definition u8string.h:440
Definition u8string.h:69
u8string & operator=(const u8string &rhs)
Assignment operator.
Definition u8string.h:221
u8string(const value_type *text, size_t count)
Definition u8string.h:141
u8string(size_type count, value_type c)
Definition u8string.h:153
void repair()
Fix the internal pointers after a low level memory copy.
Definition u8string.h:271
etl::u8string< MAX_SIZE_ > substr(size_type position=0, size_type length_=npos) const
Definition u8string.h:202
u8string(const etl::u8string_view &view)
Definition u8string.h:190
u8string(const etl::iu8string &other, size_t position, size_t length=npos)
Definition u8string.h:116
u8string(const etl::u8string< MAX_SIZE_ > &other)
Definition u8string.h:92
ETL_EXPLICIT_STRING_FROM_CHAR u8string(const value_type *text)
Definition u8string.h:129
u8string()
Constructor.
Definition u8string.h:82
u8string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition u8string.h:167
u8string(const etl::iu8string &other)
Definition u8string.h:103
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
enable_if
Definition type_traits_generator.h:1254
is_same
Definition type_traits_generator.h:1104
bitset_ext
Definition absolute.h:39
etl::string< Array_Size - 1U > make_string(const char(&text)[Array_Size])
Hash function.
Definition string.h:591
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:600
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:287