source: mainline/uspace/lib/cpp/include/impl/string.hpp@ 52d025c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 52d025c was 52d025c, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added a string stub

  • Property mode set to 100644
File size: 18.2 KB
RevLine 
[52d025c]1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_STRING
30#define LIBCPP_STRING
31
32#include <initializer_list>
33#include <iosfwd>
34#include <cstdio>
35#include <cstdlib>
36#include <cstring>
37
38namespace std
39{
40
41 /**
42 * 21.2, char_traits:
43 */
44
45 template<class Char>
46 struct char_traits;
47
48 /**
49 * 21.2.3, char_traits specializations:
50 */
51
52 template<>
53 struct char_traits<char>
54 {
55 using char_type = char;
56 using int_type = int;
57 using off_type = streamoff;
58 using pos_type = streampos;
59 /* using state_type = mbstate_t; */
60
61 static void assign(char_type& c1, char_type& c2) noexcept
62 {
63 c1 = c2;
64 }
65
66 static constexpr bool eq(char_type c1, char_type c2) noexcept
67 {
68 return c1 == c2;
69 }
70
71 static constexpr bool lt(char_type c1, char_type c2) noexcept
72 {
73 return c1 < c2;
74 }
75
76 static int compare(const char_type* s1, const char_type* s2, size_t n)
77 {
78 return std::str_lcmp(s1, s2, n);
79 }
80
81 static size_t length(const char_type* s)
82 {
83 return std::str_size(s);
84 }
85
86 static const char_type* find(const char_type* s, size_t n, const char_type& c)
87 {
88 size_t i{};
89 while (i++ < n)
90 {
91 if (s[i] == c)
92 return s + i;
93 }
94
95 return nullptr;
96 }
97
98 static char_type* move(char_type* s1, const char_type* s2, size_t n)
99 {
100 return static_cast<char_type*>(memmove(s1, s2, n));
101 }
102
103 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
104 {
105 return static_cast<char_type*>(memcpy(s1, s2, n));
106 }
107
108 static char_type* assign(char_type* s, size_t n, char_type c)
109 {
110 /**
111 * Note: Even though memset accepts int as its second argument,
112 * the actual implementation assigns that int to a dereferenced
113 * char pointer.
114 */
115 return static_cast<char_type*>(memset(s, static_cast<int>(c), n));
116 }
117
118 static constexpr int_type not_eof(int_type c) noexcept
119 {
120 if (!eq_int_type(c, eof()))
121 return c;
122 else
123 return to_int_type('a'); // We just need something that is not eof.
124 }
125
126 static constexpr char_type to_char_type(int_type c) noexcept
127 {
128 return static_cast<char_type>(c);
129 }
130
131 static constexpr int_type to_int_type(char_type c) noexcept
132 {
133 return static_cast<int_type>(c);
134 }
135
136 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
137 {
138 return c1 == c2;
139 }
140
141 static constexpr int_type eof() noexcept
142 {
143 return static_cast<int_type>(EOF);
144 }
145 };
146
147 template<>
148 struct char_traits<char16_t>
149 { /* TODO: implement */ };
150
151 template<>
152 struct char_traits<char32_t>
153 { /* TODO: implement */ };
154
155 template<>
156 struct char_traits<wchar_t>
157 {
158 using char_type = wchar_t;
159 using int_type = wint_t;
160 using off_type = streamoff;
161 using pos_type = wstreampos;
162 /* using state_type = mbstate_t; */
163
164 static void assign(char_type& c1, char_type& c2) noexcept
165 {
166 c1 = c2;
167 }
168
169 static constexpr bool eq(char_type c1, char_type c2) noexcept
170 {
171 return c1 == c2;
172 }
173
174 static constexpr bool lt(char_type c1, char_type c2) noexcept
175 {
176 return c1 < c2;
177 }
178
179 static int compare(const char_type* s1, const char_type* s2, size_t n)
180 {
181 return std::wstr_lcmp(s1, s2, n);
182 }
183
184 static size_t length(const char_type* s)
185 {
186 return std::wstr_size(s);
187 }
188
189 static const char_type* find(const char_type* s, size_t n, const char_type& c)
190 {
191 size_t i{};
192 while (i++ < n)
193 {
194 if (s[i] == c)
195 return s + i;
196 }
197
198 return nullptr;
199 }
200
201 static char_type* move(char_type* s1, const char_type* s2, size_t n)
202 {
203 return static_cast<char_type*>(memmove(s1, s2, n * sizeof(wchar_t)));
204 }
205
206 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
207 {
208 return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(wchar_t)));
209 }
210
211 static char_type* assign(char_type* s, size_t n, char_type c)
212 {
213 return static_cast<char_type*>(memset(s, static_cast<int>(c), n * sizeof(wchar_t)));
214 }
215
216 static constexpr int_type not_eof(int_type c) noexcept
217 {
218 if (!eq_int_type(c, eof()))
219 return c;
220 else
221 return to_int_type(L'a'); // We just need something that is not eof.
222 }
223
224 static constexpr char_type to_char_type(int_type c) noexcept
225 {
226 return static_cast<char_type>(c);
227 }
228
229 static constexpr int_type to_int_type(char_type c) noexcept
230 {
231 return static_cast<int_type>(c);
232 }
233
234 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
235 {
236 return c1 == c2;
237 }
238
239 static constexpr int_type eof() noexcept
240 {
241 return static_cast<int_type>(EOF);
242 }
243 };
244
245 /**
246 * 21.4, class template basic_string:
247 */
248
249 template<class Char, class Traits = char_traits<Char>,
250 class Allocator = allocator<Char>>
251 class basic_string
252 {
253 using traits_type = Traits;
254 using value_type = typename traits_type::char_type;
255 using allocator_type = Allocator;
256 using size_type = typename allocator_traits<allocator_type>::size_type;
257 using difference_type = typename allocator_traits<allocator_type>::difference_type;
258
259 using reference = value_type&;
260 using const_reference = const value_type&;
261 using pointer = allocator_traits<allocator_type>::pointer;
262 using const_pointer = allocator_traits<allocator_type>::const_pointer;
263
264 using iterator = pointer;
265 using const_iterator = const_pointer;
266 using reverse_iterator = std::reverse_iterator<iterator>;
267 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
268
269 static constexpr size_type npos = -1;
270
271 /**
272 * 21.4.2, construct/copy/destroy:
273 */
274 basic_string() noexcept
275 : basic_string(allocator_type{})
276 { /* DUMMY BODY */ }
277
278 explicit basic_string(const allocator_type& alloc);
279
280 basic_string(const basic_string& other);
281
282 basic_string(basic_string&& other);
283
284 basic_string(const basic_string& other, size_type pos, size_type n = npos,
285 const allocator_type& alloc = allocator_type{});
286
287 basic_string(const value_type*, size_type n, const allocator_type& alloc = allocator{});
288
289 basic_string(const value_type*, const allocator_type& alloc = allocator{});
290
291 basic_string(size_type n, value_type c, const allocator_type& alloc = allocator{});
292
293 template<class InputIterator>
294 basic_string(InputIterator first, InputIterator last,
295 const allocator_type& alloc = allocator{});
296
297 basic_string(initializer_list<value_type> init, const allocator_type& alloc = allocator{});
298
299 basic_string(const basic_string& other, const allocator_type& alloc);
300
301 basic_string(basic_string&& other, const allocator_type& alloc);
302
303 ~basic_string();
304
305 basic_string& operator=(const basic_string& other);
306
307 basic_string& operator=(basic_string&& other)
308 noexcept(allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
309 allocator_traits<allocator_type>::is_always_equal::value);
310
311 basic_string& operator=(const value_type* other);
312
313 basic_string& operator=(value_type c);
314
315 basic_string& operator=(initializer_list<value_type>);
316
317 /**
318 * 21.4.3, iterators:
319 */
320
321 iterator begin() noexcept;
322
323 const_iterator begin() const noexcept;
324
325 iterator end() noexcept;
326
327 const_iterator end() const noexcept;
328
329 reverse_iterator rbegin() noexcept
330 {
331 return make_reverse_iterator(begin());
332 }
333
334 const_reverse_iterator rbegin() const noexcept
335 {
336 return make_reverse_iterator(cbegin());
337 }
338
339 reverse_iterator rend() noexcept
340 {
341 return make_reverse_iterator(end());
342 }
343
344 const_reverse_iterator rend() const noexcept
345 {
346 return make_reverse_iterator(cend());
347 }
348
349 const_iterator cbegin() const noexcept;
350
351 const_iterator cend() const noexcept;
352
353 const_reverse_iterator crbegin() const noexcept
354 {
355 return make_reverse_iterator(cbegin());
356 }
357
358 const_reverse_iterator crend() const noexcept
359 {
360 return make_reverse_iterator(cend());
361 }
362
363 /**
364 * 21.4.4, capacity:
365 */
366
367 size_type size() const noexcept;
368
369 size_type length() const noexcept;
370
371 size_type max_size() const noexcept;
372
373 void resize(size_type n, value_type c);
374
375 void resize(size_type n);
376
377 size_type capacity() const noexcept;
378
379 void reserve(size_type res_arg = 0);
380
381 void shrink_to_fit();
382
383 void clear() noexcept;
384
385 bool empty() const noexcept;
386
387 /**
388 * 21.4.5, element access:
389 */
390
391 const_reference operator[](size_type idx) const;
392
393 reference operator[](size_type idx);
394
395 const_reference at(size_type idx) const;
396
397 reference at(size_type idx);
398
399 const_reference front() const;
400
401 reference front();
402
403 const_reference back() const;
404
405 reference back();
406
407 /**
408 * 21.4.6, modifiers:
409 */
410
411 basic_string& operator+=(const basic_string& str);
412
413 basic_string& operator+=(const value_type* str);
414
415 basic_string& operator+=(value_type c);
416
417 basic_string& operator+=(initializer_list<value_type> init);
418
419 basic_string& append(const basic_string& str);
420
421 basic_string& append(const basic_string& str, size_type pos
422 size_type n = npos);
423
424 basic_string& append(const value_type* str, size_type n);
425
426 basic_string& append(const value_type* str);
427
428 basic_string& append(size_type n, value_type c);
429
430 template<class InputIterator>
431 basic_string& append(InputIterator first, InputIterator last);
432
433 basic_string& append(initializer_list<value_type> init);
434
435 void push_back(value_type c);
436
437 basic_string& assign(const basic_string& str);
438
439 basic_string& assign(basic_string&& str);
440
441 basic_string& assign(const basic_string& str, size_type pos,
442 size_type n = npos);
443
444 basic_string& assign(const value_type* str, size_type n);
445
446 basic_string& assign(const value_type* str);
447
448 basic_string& assign(size_type n, value_type c);
449
450 template<class InputIterator>
451 basic_string& assign(InputIterator first, InputIterator last);
452
453 basic_string& assign(initializer_list<value_type> init);
454
455 basic_string& insert(size_type pos, const basic_string& str);
456
457 basic_string& insert(size_type pos1, const basic_string& str,
458 size_type pos2, size_type n = npos);
459
460 basic_string& insert(size_type pos, const value_type* str, size_type n);
461
462 basic_string& insert(size_type pos, const value_type* str);
463
464 basic_string& insert(size_type pos, size_type n, value_type c);
465
466 iterator insert(const_iterator pos, value_type c);
467
468 iterator insert(const_iterator pos, size_type n, value_type c);
469
470 template<class InputIterator>
471 iterator insert(const_iterator pos, InputIterator first,
472 InputIterator last);
473
474 iterator insert(const_iterator pos, initializer_list<value_type>);
475
476 basic_string& erase(size_type pos = 0; size_type n = npos);
477
478 iterator erase(const_iterator pos);
479
480 iterator erase(const_iterator pos, const_iterator last);
481
482 void pop_back();
483
484 basic_string& replace(size_type pos, size_type n, const basic_string& str);
485
486 basic_string& replace(size_type pos1, size_type n1, const basic_string& str
487 size_type pos2, size_type n2);
488
489 basic_string& replace(size_type pos, size_type n1, const value_type* str,
490 size_type n2);
491
492 basic_string& replace(size_type pos, size_type n, const value_type* str);
493
494 basic_string& replace(size_type pos, size_type n1, size_type n2,
495 value_type c);
496
497 basic_string& replace(const_iterator i1, const_iterator i2,
498 const basic_string& str);
499
500 basic_string& replace(const_iterator i1, const_iterator i2,
501 const value_type* str, size_type n);
502
503 basic_string& replace(const_iterator i1, const_iterator i2,
504 const value_type* str);
505
506 basic_string& replace(const_iterator i1, const_iterator i2,
507 value_type c);
508
509 template<class InputIterator>
510 basic_string& replace(const_iterator i1, const_iterator i2,
511 InputIterator j1, InputIterator j2);
512
513 basic_string& replace(const_iterator i1, const_iterator i2,
514 initializer_list<value_type> init);
515
516 size_type copy(value_type* str, size_type n, size_type pos = 0) const;
517
518 void swap(basic_string& other)
519 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
520 allocator_traits<allocator_type>::is_always_equal);
521
522 /**
523 * 21.4.7, string operations:
524 */
525
526 const value_type* c_str() const noexcept;
527
528 const value_type* data() const noexcept;
529
530 allocator_type get_allocator() const noexcept;
531
532 size_type find(const basic_string& str, size_type pos = 0) const noexcept;
533
534 size_type find(const value_type* str, size_type pos, size_type n) const;
535
536 size_type find(const value_type* str, size_type pos = 0) const;
537
538 size_type find(value_type c, size_type pos = 0) const;
539
540 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
541
542 size_type rfind(const value_type* str, size_type pos, size_type n) const;
543
544 size_type rfind(const value_type* str, size_type pos = npos) const;
545
546 size_type rfind(value_type c, size_type pos = npos) const;
547
548 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
549
550 size_type find_first_of(const value_type* str, size_type pos, size_type n) const;
551
552 size_type find_first_of(const value_type* str, size_type pos = 0) const;
553
554 size_type find_first_of(value_type c, size_type pos = 0) const;
555
556 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
557
558 size_type find_last_of(const value_type* str, size_type pos, size_type n) const;
559
560 size_type find_last_of(const value_type* str, size_type pos = npos) const;
561
562 size_type find_last_of(value_type c, size_type pos = npos) const;
563
564 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
565
566 size_type find_first_not_of(const value_type* str, size_type pos, size_type n) const;
567
568 size_type find_first_not_of(const value_type* str, size_type pos = 0) const;
569
570 size_type find_first_not_of(value_type c, size_type pos = 0) const;
571
572 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
573
574 size_type find_last_not_of(const value_type* str, size_type pos, size_type n) const;
575
576 size_type find_last_not_of(const value_type* str, size_type pos = npos) const;
577
578 size_type find_last_not_of(value_type c, size_type pos = npos) const;
579
580 basic_string substr(size_type pos = 0, size_type n = npos) const;
581
582 int compare(const basic_string& other) const noexcept;
583
584 int compare(size_type pos, size_type n, const basic_string& other) const;
585
586 int compare(size_type pos1, size_type n1, const basic_string& other,
587 size_type pos2, size_type n2 = npos) const;
588
589 int compare(const value_type* other) const;
590
591 int compare(size_type pos, size_type n, const value_type* other) const;
592
593 int compare(size_type pos1, size_type n1,
594 const value_type* other, size_type n2) const;
595 };
596}
597
598#endif
Note: See TracBrowser for help on using the repository browser.