source: mainline/uspace/lib/cpp/include/impl/string.hpp@ 98c99ba

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

cpp: fixed reverse iterator generators of vector and string

  • Property mode set to 100644
File size: 19.0 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 {
[177a576]253 public:
254 using traits_type = Traits;
255 using value_type = typename traits_type::char_type;
256 using allocator_type = Allocator;
257 using size_type = typename allocator_traits<allocator_type>::size_type;
258 using difference_type = typename allocator_traits<allocator_type>::difference_type;
[52d025c]259
[177a576]260 using reference = value_type&;
261 using const_reference = const value_type&;
262 using pointer = allocator_traits<allocator_type>::pointer;
263 using const_pointer = allocator_traits<allocator_type>::const_pointer;
[52d025c]264
[177a576]265 using iterator = pointer;
266 using const_iterator = const_pointer;
267 using reverse_iterator = std::reverse_iterator<iterator>;
268 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
[52d025c]269
[177a576]270 static constexpr size_type npos = -1;
[52d025c]271
[177a576]272 /**
273 * 21.4.2, construct/copy/destroy:
274 */
275 basic_string() noexcept
276 : basic_string(allocator_type{})
277 { /* DUMMY BODY */ }
[52d025c]278
[177a576]279 explicit basic_string(const allocator_type& alloc);
[52d025c]280
[177a576]281 basic_string(const basic_string& other);
[52d025c]282
[177a576]283 basic_string(basic_string&& other);
[52d025c]284
[177a576]285 basic_string(const basic_string& other, size_type pos, size_type n = npos,
286 const allocator_type& alloc = allocator_type{});
[52d025c]287
[177a576]288 basic_string(const value_type*, size_type n, const allocator_type& alloc = allocator{});
[52d025c]289
[177a576]290 basic_string(const value_type*, const allocator_type& alloc = allocator{});
[52d025c]291
[177a576]292 basic_string(size_type n, value_type c, const allocator_type& alloc = allocator{});
[52d025c]293
[177a576]294 template<class InputIterator>
295 basic_string(InputIterator first, InputIterator last,
296 const allocator_type& alloc = allocator{});
[52d025c]297
[177a576]298 basic_string(initializer_list<value_type> init, const allocator_type& alloc = allocator{});
[52d025c]299
[177a576]300 basic_string(const basic_string& other, const allocator_type& alloc);
[52d025c]301
[177a576]302 basic_string(basic_string&& other, const allocator_type& alloc);
[52d025c]303
[177a576]304 ~basic_string();
[52d025c]305
[177a576]306 basic_string& operator=(const basic_string& other);
[52d025c]307
[177a576]308 basic_string& operator=(basic_string&& other)
309 noexcept(allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
310 allocator_traits<allocator_type>::is_always_equal::value);
[52d025c]311
[177a576]312 basic_string& operator=(const value_type* other);
[52d025c]313
[177a576]314 basic_string& operator=(value_type c);
[52d025c]315
[177a576]316 basic_string& operator=(initializer_list<value_type>);
[52d025c]317
[177a576]318 /**
319 * 21.4.3, iterators:
320 */
[52d025c]321
[177a576]322 iterator begin() noexcept;
[52d025c]323
[177a576]324 const_iterator begin() const noexcept;
[52d025c]325
[177a576]326 iterator end() noexcept;
[52d025c]327
[177a576]328 const_iterator end() const noexcept;
[52d025c]329
[177a576]330 reverse_iterator rbegin() noexcept
331 {
[98c99ba]332 return make_reverse_iterator(end());
[177a576]333 }
[52d025c]334
[177a576]335 const_reverse_iterator rbegin() const noexcept
336 {
[98c99ba]337 return make_reverse_iterator(cend());
[177a576]338 }
[52d025c]339
[177a576]340 reverse_iterator rend() noexcept
341 {
[98c99ba]342 return make_reverse_iterator(begin());
[177a576]343 }
[52d025c]344
[177a576]345 const_reverse_iterator rend() const noexcept
346 {
[98c99ba]347 return make_reverse_iterator(cbegin());
[177a576]348 }
[52d025c]349
[177a576]350 const_iterator cbegin() const noexcept;
[52d025c]351
[177a576]352 const_iterator cend() const noexcept;
[52d025c]353
[177a576]354 const_reverse_iterator crbegin() const noexcept
355 {
[98c99ba]356 return rbegin();
[177a576]357 }
[52d025c]358
[177a576]359 const_reverse_iterator crend() const noexcept
360 {
[98c99ba]361 return rend();
[177a576]362 }
[52d025c]363
[177a576]364 /**
365 * 21.4.4, capacity:
366 */
[52d025c]367
[177a576]368 size_type size() const noexcept;
[52d025c]369
[177a576]370 size_type length() const noexcept;
[52d025c]371
[177a576]372 size_type max_size() const noexcept;
[52d025c]373
[177a576]374 void resize(size_type n, value_type c);
[52d025c]375
[177a576]376 void resize(size_type n);
[52d025c]377
[177a576]378 size_type capacity() const noexcept;
[52d025c]379
[177a576]380 void reserve(size_type res_arg = 0);
[52d025c]381
[177a576]382 void shrink_to_fit();
[52d025c]383
[177a576]384 void clear() noexcept;
[52d025c]385
[177a576]386 bool empty() const noexcept;
[52d025c]387
[177a576]388 /**
389 * 21.4.5, element access:
390 */
[52d025c]391
[177a576]392 const_reference operator[](size_type idx) const;
[52d025c]393
[177a576]394 reference operator[](size_type idx);
[52d025c]395
[177a576]396 const_reference at(size_type idx) const;
[52d025c]397
[177a576]398 reference at(size_type idx);
[52d025c]399
[177a576]400 const_reference front() const;
[52d025c]401
[177a576]402 reference front();
[52d025c]403
[177a576]404 const_reference back() const;
[52d025c]405
[177a576]406 reference back();
[52d025c]407
[177a576]408 /**
409 * 21.4.6, modifiers:
410 */
[52d025c]411
[177a576]412 basic_string& operator+=(const basic_string& str);
[52d025c]413
[177a576]414 basic_string& operator+=(const value_type* str);
[52d025c]415
[177a576]416 basic_string& operator+=(value_type c);
[52d025c]417
[177a576]418 basic_string& operator+=(initializer_list<value_type> init);
[52d025c]419
[177a576]420 basic_string& append(const basic_string& str);
[52d025c]421
[177a576]422 basic_string& append(const basic_string& str, size_type pos
423 size_type n = npos);
[52d025c]424
[177a576]425 basic_string& append(const value_type* str, size_type n);
[52d025c]426
[177a576]427 basic_string& append(const value_type* str);
[52d025c]428
[177a576]429 basic_string& append(size_type n, value_type c);
[52d025c]430
[177a576]431 template<class InputIterator>
432 basic_string& append(InputIterator first, InputIterator last);
[52d025c]433
[177a576]434 basic_string& append(initializer_list<value_type> init);
[52d025c]435
[177a576]436 void push_back(value_type c);
[52d025c]437
[177a576]438 basic_string& assign(const basic_string& str);
[52d025c]439
[177a576]440 basic_string& assign(basic_string&& str);
[52d025c]441
[177a576]442 basic_string& assign(const basic_string& str, size_type pos,
443 size_type n = npos);
[52d025c]444
[177a576]445 basic_string& assign(const value_type* str, size_type n);
[52d025c]446
[177a576]447 basic_string& assign(const value_type* str);
[52d025c]448
[177a576]449 basic_string& assign(size_type n, value_type c);
[52d025c]450
[177a576]451 template<class InputIterator>
452 basic_string& assign(InputIterator first, InputIterator last);
[52d025c]453
[177a576]454 basic_string& assign(initializer_list<value_type> init);
[52d025c]455
[177a576]456 basic_string& insert(size_type pos, const basic_string& str);
[52d025c]457
[177a576]458 basic_string& insert(size_type pos1, const basic_string& str,
459 size_type pos2, size_type n = npos);
[52d025c]460
[177a576]461 basic_string& insert(size_type pos, const value_type* str, size_type n);
[52d025c]462
[177a576]463 basic_string& insert(size_type pos, const value_type* str);
[52d025c]464
[177a576]465 basic_string& insert(size_type pos, size_type n, value_type c);
[52d025c]466
[177a576]467 iterator insert(const_iterator pos, value_type c);
[52d025c]468
[177a576]469 iterator insert(const_iterator pos, size_type n, value_type c);
[52d025c]470
[177a576]471 template<class InputIterator>
472 iterator insert(const_iterator pos, InputIterator first,
473 InputIterator last);
[52d025c]474
[177a576]475 iterator insert(const_iterator pos, initializer_list<value_type>);
[52d025c]476
[177a576]477 basic_string& erase(size_type pos = 0; size_type n = npos);
[52d025c]478
[177a576]479 iterator erase(const_iterator pos);
[52d025c]480
[177a576]481 iterator erase(const_iterator pos, const_iterator last);
[52d025c]482
[177a576]483 void pop_back();
[52d025c]484
[177a576]485 basic_string& replace(size_type pos, size_type n, const basic_string& str);
[52d025c]486
[177a576]487 basic_string& replace(size_type pos1, size_type n1, const basic_string& str
488 size_type pos2, size_type n2);
[52d025c]489
[177a576]490 basic_string& replace(size_type pos, size_type n1, const value_type* str,
491 size_type n2);
[52d025c]492
[177a576]493 basic_string& replace(size_type pos, size_type n, const value_type* str);
[52d025c]494
[177a576]495 basic_string& replace(size_type pos, size_type n1, size_type n2,
496 value_type c);
[52d025c]497
[177a576]498 basic_string& replace(const_iterator i1, const_iterator i2,
499 const basic_string& str);
[52d025c]500
[177a576]501 basic_string& replace(const_iterator i1, const_iterator i2,
502 const value_type* str, size_type n);
[52d025c]503
[177a576]504 basic_string& replace(const_iterator i1, const_iterator i2,
505 const value_type* str);
[52d025c]506
[177a576]507 basic_string& replace(const_iterator i1, const_iterator i2,
508 value_type c);
[52d025c]509
[177a576]510 template<class InputIterator>
511 basic_string& replace(const_iterator i1, const_iterator i2,
512 InputIterator j1, InputIterator j2);
[52d025c]513
[177a576]514 basic_string& replace(const_iterator i1, const_iterator i2,
515 initializer_list<value_type> init);
[52d025c]516
[177a576]517 size_type copy(value_type* str, size_type n, size_type pos = 0) const;
[52d025c]518
[177a576]519 void swap(basic_string& other)
520 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
521 allocator_traits<allocator_type>::is_always_equal);
[52d025c]522
[177a576]523 /**
524 * 21.4.7, string operations:
525 */
[52d025c]526
[177a576]527 const value_type* c_str() const noexcept;
[52d025c]528
[177a576]529 const value_type* data() const noexcept;
[52d025c]530
[177a576]531 allocator_type get_allocator() const noexcept;
[52d025c]532
[177a576]533 size_type find(const basic_string& str, size_type pos = 0) const noexcept;
[52d025c]534
[177a576]535 size_type find(const value_type* str, size_type pos, size_type n) const;
[52d025c]536
[177a576]537 size_type find(const value_type* str, size_type pos = 0) const;
[52d025c]538
[177a576]539 size_type find(value_type c, size_type pos = 0) const;
[52d025c]540
[177a576]541 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
[52d025c]542
[177a576]543 size_type rfind(const value_type* str, size_type pos, size_type n) const;
[52d025c]544
[177a576]545 size_type rfind(const value_type* str, size_type pos = npos) const;
[52d025c]546
[177a576]547 size_type rfind(value_type c, size_type pos = npos) const;
[52d025c]548
[177a576]549 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
[52d025c]550
[177a576]551 size_type find_first_of(const value_type* str, size_type pos, size_type n) const;
[52d025c]552
[177a576]553 size_type find_first_of(const value_type* str, size_type pos = 0) const;
[52d025c]554
[177a576]555 size_type find_first_of(value_type c, size_type pos = 0) const;
[52d025c]556
[177a576]557 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
[52d025c]558
[177a576]559 size_type find_last_of(const value_type* str, size_type pos, size_type n) const;
[52d025c]560
[177a576]561 size_type find_last_of(const value_type* str, size_type pos = npos) const;
[52d025c]562
[177a576]563 size_type find_last_of(value_type c, size_type pos = npos) const;
[52d025c]564
[177a576]565 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
[52d025c]566
[177a576]567 size_type find_first_not_of(const value_type* str, size_type pos, size_type n) const;
[52d025c]568
[177a576]569 size_type find_first_not_of(const value_type* str, size_type pos = 0) const;
[52d025c]570
[177a576]571 size_type find_first_not_of(value_type c, size_type pos = 0) const;
[52d025c]572
[177a576]573 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
[52d025c]574
[177a576]575 size_type find_last_not_of(const value_type* str, size_type pos, size_type n) const;
[52d025c]576
[177a576]577 size_type find_last_not_of(const value_type* str, size_type pos = npos) const;
[52d025c]578
[177a576]579 size_type find_last_not_of(value_type c, size_type pos = npos) const;
[52d025c]580
[177a576]581 basic_string substr(size_type pos = 0, size_type n = npos) const;
[52d025c]582
[177a576]583 int compare(const basic_string& other) const noexcept;
[52d025c]584
[177a576]585 int compare(size_type pos, size_type n, const basic_string& other) const;
[52d025c]586
[177a576]587 int compare(size_type pos1, size_type n1, const basic_string& other,
588 size_type pos2, size_type n2 = npos) const;
[52d025c]589
[177a576]590 int compare(const value_type* other) const;
[52d025c]591
[177a576]592 int compare(size_type pos, size_type n, const value_type* other) const;
[52d025c]593
[177a576]594 int compare(size_type pos1, size_type n1,
595 const value_type* other, size_type n2) const;
[52d025c]596 };
597}
598
599#endif
Note: See TracBrowser for help on using the repository browser.