Embedded Template Library 1.0
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 "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
44namespace etl
45{
46#if ETL_USING_CPP11
47 inline namespace literals
48 {
49 inline namespace string_literals
50 {
51 constexpr etl::string_view operator ""_sv(const char* str, size_t length) noexcept
52 {
53 return etl::string_view{ str, length };
54 }
55 }
56 }
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
76 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
77
78 //*************************************************************************
80 //*************************************************************************
82 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
83 {
84 this->initialise();
85 }
86
87 //*************************************************************************
90 //*************************************************************************
92 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
93 {
94 this->assign(other);
95 }
96
97 //*************************************************************************
100 //*************************************************************************
101 string(const etl::istring& other)
102 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
103 {
104 this->assign(other);
105 }
106
107 //*************************************************************************
112 //*************************************************************************
113 string(const etl::istring& other, size_t position, size_t length = npos)
114 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
115 {
116 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
117
118 this->assign(other, position, length);
119 }
120
121 //*************************************************************************
124 //*************************************************************************
125 ETL_EXPLICIT_STRING_FROM_CHAR string(const value_type* text)
126 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
127 {
128 this->assign(text, text + etl::char_traits<value_type>::length(text));
129 }
130
131 //*************************************************************************
135 //*************************************************************************
136 string(const value_type* text, size_t count)
137 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
138 {
139 this->assign(text, text + count);
140 }
141
142 //*************************************************************************
146 //*************************************************************************
147 string(size_type count, value_type c)
148 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
149 {
150 this->initialise();
151 this->resize(count, c);
152 }
153
154 //*************************************************************************
159 //*************************************************************************
160 template <typename TIterator>
161 string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
162 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
163 {
164 this->assign(first, last);
165 }
166
167#if ETL_HAS_INITIALIZER_LIST
168 //*************************************************************************
170 //*************************************************************************
171 string(std::initializer_list<value_type> init)
172 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
173 {
174 this->assign(init.begin(), init.end());
175 }
176#endif
177
178 //*************************************************************************
181 //*************************************************************************
182 explicit string(const etl::string_view& view)
183 : istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
184 {
185 this->assign(view.begin(), view.end());
186 }
187
188 //*************************************************************************
192 //*************************************************************************
193 etl::string<MAX_SIZE_> substr(size_type position = 0, size_type length_ = npos) const
194 {
195 etl::string<MAX_SIZE_> new_string;
196
197 if (position != this->size())
198 {
199 ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds));
200
201 length_ = etl::min(length_, this->size() - position);
202
203 new_string.assign(buffer + position, buffer + position + length_);
204 }
205
206 return new_string;
207 }
208
209 //*************************************************************************
211 //*************************************************************************
212 string& operator = (const string& rhs)
213 {
214 if (&rhs != this)
215 {
216 this->assign(rhs);
217 }
218
219 return *this;
220 }
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 void repair()
250#if ETL_HAS_ISTRING_REPAIR
251 ETL_OVERRIDE
252#endif
253 {
255 }
256
257 private:
258
259 value_type buffer[MAX_SIZE + 1];
260 };
261
262 template <size_t MAX_SIZE_>
263 ETL_CONSTANT size_t string<MAX_SIZE_>::MAX_SIZE;
264
265 //***************************************************************************
268 //***************************************************************************
269 class string_ext : public istring
270 {
271 public:
272
273 typedef istring base_type;
274 typedef istring interface_type;
275
276 typedef istring::value_type value_type;
277 typedef istring::size_type size_type;
278
279 //*************************************************************************
281 //*************************************************************************
282 string_ext(value_type* buffer, size_type buffer_size)
283 : istring(buffer, buffer_size - 1U)
284 {
285 this->initialise();
286 }
287
288 //*************************************************************************
291 //*************************************************************************
292 string_ext(const etl::string_ext& other, value_type* buffer, size_type buffer_size)
293 : istring(buffer, buffer_size - 1U)
294 {
295 this->assign(other);
296 }
297
298 //*************************************************************************
301 //*************************************************************************
302 string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size)
303 : istring(buffer, buffer_size - 1U)
304 {
305 this->assign(other);
306 }
307
308 //*************************************************************************
313 //*************************************************************************
314 string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size, size_type position, size_type length = npos)
315 : istring(buffer, buffer_size - 1U)
316 {
317 ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
318
319 this->assign(other, position, length);
320 }
321
322 //*************************************************************************
325 //*************************************************************************
326 string_ext(const char* text, char* buffer, size_type buffer_size)
327 : istring(buffer, buffer_size - 1U)
328 {
329 // Is the initial text at the same address as the buffer?
330 if (text == buffer)
331 {
332 this->current_size = etl::strlen(buffer);
333 }
334 else
335 {
336 this->assign(text, text + etl::strlen(text));
337 }
338 }
339
340 //*************************************************************************
344 //*************************************************************************
345 string_ext(const value_type* text, size_type count, value_type* buffer, size_type buffer_size)
346 : istring(buffer, buffer_size - 1U)
347 {
348 this->assign(text, text + count);
349 }
350
351 //*************************************************************************
355 //*************************************************************************
356 string_ext(size_type count, value_type c, value_type* buffer, size_type buffer_size)
357 : istring(buffer, buffer_size - 1U)
358 {
359 this->initialise();
360 this->resize(count, c);
361 }
362
363 //*************************************************************************
368 //*************************************************************************
369 template <typename TIterator>
370 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)
371 : istring(buffer, buffer_size - 1U)
372 {
373 this->assign(first, last);
374 }
375
376#if ETL_HAS_INITIALIZER_LIST
377 //*************************************************************************
379 //*************************************************************************
380 string_ext(std::initializer_list<value_type> init, value_type* buffer, size_type buffer_size)
381 : istring(buffer, buffer_size - 1U)
382 {
383 this->assign(init.begin(), init.end());
384 }
385#endif
386
387 //*************************************************************************
390 //*************************************************************************
391 explicit string_ext(const etl::string_view& view, value_type* buffer, size_type buffer_size)
392 : istring(buffer, buffer_size - 1U)
393 {
394 this->assign(view.begin(), view.end());
395 }
396
397 //*************************************************************************
399 //*************************************************************************
401 {
402 if (&rhs != this)
403 {
404 this->assign(rhs);
405 }
406
407 return *this;
408 }
409
410
411 //*************************************************************************
413 //*************************************************************************
415 {
416 if (&rhs != this)
417 {
418 this->assign(rhs);
419 }
420
421 return *this;
422 }
423
424 //*************************************************************************
426 //*************************************************************************
427 string_ext& operator = (const value_type* text)
428 {
429 this->assign(text);
430
431 return *this;
432 }
433
434 //*************************************************************************
436 //*************************************************************************
437 void repair()
438#if ETL_HAS_ISTRING_REPAIR
439 ETL_OVERRIDE
440#endif
441 {
442 }
443
444 private:
445
446 //*************************************************************************
448 //*************************************************************************
449 string_ext(const string_ext& other) ETL_DELETE;
450 };
451
452 //*************************************************************************
454 //*************************************************************************
455#if ETL_USING_8BIT_TYPES
456 template <>
457 struct hash<etl::istring>
458 {
459 size_t operator()(const etl::istring& text) const
460 {
461 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
462 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
463 }
464 };
465
466 template <size_t SIZE>
467 struct hash<etl::string<SIZE> >
468 {
469 size_t operator()(const etl::string<SIZE>& text) const
470 {
471 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
472 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
473 }
474 };
475
476 template <>
477 struct hash<etl::string_ext>
478 {
479 size_t operator()(const etl::string_ext& text) const
480 {
481 return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
482 reinterpret_cast<const uint8_t*>(text.data() + text.size()));
483 }
484 };
485#endif
486
487 //***************************************************************************
489 //***************************************************************************
490 template<size_t Array_Size>
491 etl::string<Array_Size - 1U> make_string(const char(&text)[Array_Size])
492 {
493 return etl::string<Array_Size - 1U>(text, etl::strlen(text, Array_Size - 1));
494 }
495
496 //***************************************************************************
498 //***************************************************************************
499 template<size_t MAX_SIZE, size_t SIZE>
501 {
502 return etl::string<MAX_SIZE>(text, etl::strlen(text, SIZE));
503 }
504}
505
506#include "private/minmax_pop.h"
507
508#endif
String view.
Definition: string_view.h:96
ETL_CONSTEXPR const_iterator begin() const
Returns a const iterator to the beginning of the array.
Definition: string_view.h:193
ETL_CONSTEXPR const_iterator end() const
Returns a const iterator to the end of the array.
Definition: string_view.h:209
Definition: basic_string.h:326
void resize(size_type new_size)
Definition: basic_string.h:456
void assign(const etl::ibasic_string< T > &other)
Definition: basic_string.h:626
pointer data()
Definition: basic_string.h:589
void initialise()
Initialise the string.
Definition: basic_string.h:2289
void repair_buffer(T *p_buffer_)
Fix the internal pointers after a low level memory copy.
Definition: basic_string.h:2302
size_type length() const
Definition: basic_string.h:185
size_type current_size
The current number of elements in the string.
Definition: basic_string.h:311
size_type size() const
Definition: basic_string.h:176
Definition: string.h:270
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size, size_type position, size_type length=npos)
Definition: string.h:314
string_ext(value_type *buffer, size_type buffer_size)
Constructor.
Definition: string.h:282
string_ext(const etl::string_ext &other, value_type *buffer, size_type buffer_size)
Definition: string.h:292
string_ext(const etl::string_view &view, value_type *buffer, size_type buffer_size)
Definition: string.h:391
string_ext(const char *text, char *buffer, size_type buffer_size)
Definition: string.h:326
string_ext(size_type count, value_type c, value_type *buffer, size_type buffer_size)
Definition: string.h:356
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size)
Definition: string.h:302
void repair()
Fix the internal pointers after a low level memory copy.
Definition: string.h:437
string_ext(const value_type *text, size_type count, value_type *buffer, size_type buffer_size)
Definition: string.h:345
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:370
string_ext & operator=(const string_ext &rhs)
Assignment operator.
Definition: string.h:400
Definition: basic_string.h:98
Definition: string.h:68
etl::string< MAX_SIZE_ > substr(size_type position=0, size_type length_=npos) const
Definition: string.h:193
void repair()
Fix the internal pointers after a low level memory copy.
Definition: string.h:249
string()
Constructor.
Definition: string.h:81
string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition: string.h:161
string(const etl::string_view &view)
Definition: string.h:182
string(const etl::string< MAX_SIZE_ > &other)
Definition: string.h:91
string(const etl::istring &other)
Definition: string.h:101
string & operator=(const string &rhs)
Assignment operator.
Definition: string.h:212
string(const etl::istring &other, size_t position, size_t length=npos)
Definition: string.h:113
string(const value_type *text, size_t count)
Definition: string.h:136
string(size_type count, value_type c)
Definition: string.h:147
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
enable_if
Definition: type_traits_generator.h:1191
is_integral
Definition: type_traits_generator.h:1001
bitset_ext
Definition: absolute.h:38
etl::string< Array_Size - 1U > make_string(const char(&text)[Array_Size])
Hash function.
Definition: string.h:491
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:500
ETL_CONSTEXPR size_t strlen(const T *t)
Alternative strlen for all character types.
Definition: char_traits.h:267
Character traits for any character type.
Definition: char_traits.h:102