gdb/riscv: Use legacy register numbers in default target description
[external/binutils.git] / gdb / common / gdb_string_view.h
1 // Components for manipulating non-owning sequences of characters -*- C++ -*-
2
3
4 #ifndef COMMON_GDB_STRING_VIEW_H
5 #define COMMON_GDB_STRING_VIEW_H
6
7 // Note: This file has been stolen from the gcc repo
8 // (libstdc++-v3/include/experimental/string_view) and has local modifications.
9
10 // Copyright (C) 2013-2019 Free Software Foundation, Inc.
11 //
12 // This file is part of the GNU ISO C++ Library.  This library is free
13 // software; you can redistribute it and/or modify it under the
14 // terms of the GNU General Public License as published by the
15 // Free Software Foundation; either version 3, or (at your option)
16 // any later version.
17
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 // GNU General Public License for more details.
22
23 // Under Section 7 of GPL version 3, you are granted additional
24 // permissions described in the GCC Runtime Library Exception, version
25 // 3.1, as published by the Free Software Foundation.
26
27 // You should have received a copy of the GNU General Public License and
28 // a copy of the GCC Runtime Library Exception along with this program;
29 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
30 // <http://www.gnu.org/licenses/>.
31
32 //
33 // N3762 basic_string_view library
34 //
35
36
37 #if __cplusplus >= 201703L
38
39 #include <string_view>
40
41 namespace gdb {
42   using string_view = std::string_view;
43 } /* namespace gdb */
44
45 #else /* __cplusplus < 201703L */
46
47 #include <string>
48 #include <limits>
49
50 namespace gdb {
51
52   /**
53    *  @class basic_string_view <experimental/string_view>
54    *  @brief  A non-owning reference to a string.
55    *
56    *  @ingroup strings
57    *  @ingroup sequences
58    *  @ingroup experimental
59    *
60    *  @tparam _CharT  Type of character
61    *  @tparam _Traits  Traits for character type, defaults to
62    *                   char_traits<_CharT>.
63    *
64    *  A basic_string_view looks like this:
65    *
66    *  @code
67    *    _CharT*    _M_str
68    *    size_t     _M_len
69    *  @endcode
70    */
71   template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
72     class basic_string_view
73     {
74     public:
75
76       // types
77       using traits_type = _Traits;
78       using value_type = _CharT;
79       using pointer = const _CharT*;
80       using const_pointer = const _CharT*;
81       using reference = const _CharT&;
82       using const_reference = const _CharT&;
83       using const_iterator = const _CharT*;
84       using iterator = const_iterator;
85       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
86       using reverse_iterator = const_reverse_iterator;
87       using size_type = size_t;
88       using difference_type = ptrdiff_t;
89       static constexpr size_type npos = size_type(-1);
90
91       // [string.view.cons], construct/copy
92
93       constexpr
94       basic_string_view() noexcept
95       : _M_len{0}, _M_str{nullptr}
96       { }
97
98       constexpr basic_string_view(const basic_string_view&) noexcept = default;
99
100       template<typename _Allocator>
101         basic_string_view(const std::basic_string<_CharT, _Traits,
102                           _Allocator>& __str) noexcept
103         : _M_len{__str.length()}, _M_str{__str.data()}
104         { }
105
106       /*constexpr*/ basic_string_view(const _CharT* __str)
107       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
108         _M_str{__str}
109       { }
110
111       constexpr basic_string_view(const _CharT* __str, size_type __len)
112       : _M_len{__len},
113         _M_str{__str}
114       { }
115
116       basic_string_view&
117       operator=(const basic_string_view&) noexcept = default;
118
119       // [string.view.iterators], iterators
120
121       constexpr const_iterator
122       begin() const noexcept
123       { return this->_M_str; }
124
125       constexpr const_iterator
126       end() const noexcept
127       { return this->_M_str + this->_M_len; }
128
129       constexpr const_iterator
130       cbegin() const noexcept
131       { return this->_M_str; }
132
133       constexpr const_iterator
134       cend() const noexcept
135       { return this->_M_str + this->_M_len; }
136
137       const_reverse_iterator
138       rbegin() const noexcept
139       { return const_reverse_iterator(this->end()); }
140
141       const_reverse_iterator
142       rend() const noexcept
143       { return const_reverse_iterator(this->begin()); }
144
145       const_reverse_iterator
146       crbegin() const noexcept
147       { return const_reverse_iterator(this->end()); }
148
149       const_reverse_iterator
150       crend() const noexcept
151       { return const_reverse_iterator(this->begin()); }
152
153       // [string.view.capacity], capacity
154
155       constexpr size_type
156       size() const noexcept
157       { return this->_M_len; }
158
159       constexpr size_type
160       length() const noexcept
161       { return _M_len; }
162
163       constexpr size_type
164       max_size() const noexcept
165       {
166         return (npos - sizeof(size_type) - sizeof(void*))
167                 / sizeof(value_type) / 4;
168       }
169
170       constexpr bool
171       empty() const noexcept
172       { return this->_M_len == 0; }
173
174       // [string.view.access], element access
175
176       constexpr const _CharT&
177       operator[](size_type __pos) const
178       {
179         // TODO: Assert to restore in a way compatible with the constexpr.
180         // __glibcxx_assert(__pos < this->_M_len);
181         return *(this->_M_str + __pos);
182       }
183
184       constexpr const _CharT&
185       at(size_type __pos) const
186       {
187         return __pos < this->_M_len
188              ? *(this->_M_str + __pos)
189              : (error (_("basic_string_view::at: __pos "
190                          "(which is %zu) >= this->size() "
191                          "(which is %zu)"),
192                        __pos, this->size()),
193                 *this->_M_str);
194       }
195
196       constexpr const _CharT&
197       front() const
198       {
199         // TODO: Assert to restore in a way compatible with the constexpr.
200         // __glibcxx_assert(this->_M_len > 0);
201         return *this->_M_str;
202       }
203
204       constexpr const _CharT&
205       back() const
206       {
207         // TODO: Assert to restore in a way compatible with the constexpr.
208         // __glibcxx_assert(this->_M_len > 0);
209         return *(this->_M_str + this->_M_len - 1);
210       }
211
212       constexpr const _CharT*
213       data() const noexcept
214       { return this->_M_str; }
215
216       // [string.view.modifiers], modifiers:
217
218       /*constexpr*/ void
219       remove_prefix(size_type __n)
220       {
221         gdb_assert (this->_M_len >= __n);
222         this->_M_str += __n;
223         this->_M_len -= __n;
224       }
225
226       /*constexpr*/ void
227       remove_suffix(size_type __n)
228       { this->_M_len -= __n; }
229
230       /*constexpr*/ void
231       swap(basic_string_view& __sv) noexcept
232       {
233         auto __tmp = *this;
234         *this = __sv;
235         __sv = __tmp;
236       }
237
238
239       // [string.view.ops], string operations:
240
241       template<typename _Allocator>
242         explicit operator std::basic_string<_CharT, _Traits, _Allocator>() const
243         {
244           return { this->_M_str, this->_M_len };
245         }
246
247       template<typename _Allocator = std::allocator<_CharT>>
248         std::basic_string<_CharT, _Traits, _Allocator>
249         to_string(const _Allocator& __alloc = _Allocator()) const
250         {
251           return { this->_M_str, this->_M_len, __alloc };
252         }
253
254       size_type
255       copy(_CharT* __str, size_type __n, size_type __pos = 0) const
256       {
257         gdb_assert (__str != nullptr || __n == 0);
258         if (__pos > this->_M_len)
259           error (_("basic_string_view::copy: __pos "
260                    "(which is %zu) > this->size() "
261                    "(which is %zu)"),
262                  __pos, this->size());
263         size_type __rlen{std::min(__n, size_type{this->_M_len  - __pos})};
264         for (auto __begin = this->_M_str + __pos,
265              __end = __begin + __rlen; __begin != __end;)
266           *__str++ = *__begin++;
267         return __rlen;
268       }
269
270
271       // [string.view.ops], string operations:
272
273       /*constexpr*/ basic_string_view
274       substr(size_type __pos, size_type __n=npos) const
275       {
276         return __pos <= this->_M_len
277              ? basic_string_view{this->_M_str + __pos,
278                                 std::min(__n, size_type{this->_M_len  - __pos})}
279              : (error (_("basic_string_view::substr: __pos "
280                          "(which is %zu) > this->size() "
281                          "(which is %zu)"),
282                        __pos, this->size()), basic_string_view{});
283       }
284
285       /*constexpr*/ int
286       compare(basic_string_view __str) const noexcept
287       {
288         int __ret = traits_type::compare(this->_M_str, __str._M_str,
289                                          std::min(this->_M_len, __str._M_len));
290         if (__ret == 0)
291           __ret = _S_compare(this->_M_len, __str._M_len);
292         return __ret;
293       }
294
295       /*constexpr*/ int
296       compare(size_type __pos1, size_type __n1, basic_string_view __str) const
297       { return this->substr(__pos1, __n1).compare(__str); }
298
299       /*constexpr*/ int
300       compare(size_type __pos1, size_type __n1,
301               basic_string_view __str, size_type __pos2, size_type __n2) const
302       { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
303
304       /*constexpr*/ int
305       compare(const _CharT* __str) const noexcept
306       { return this->compare(basic_string_view{__str}); }
307
308       /*constexpr*/ int
309       compare(size_type __pos1, size_type __n1, const _CharT* __str) const
310       { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
311
312       /*constexpr*/ int
313       compare(size_type __pos1, size_type __n1,
314               const _CharT* __str, size_type __n2) const
315       {
316         return this->substr(__pos1, __n1)
317                    .compare(basic_string_view(__str, __n2));
318       }
319
320       /*constexpr*/ size_type
321       find(basic_string_view __str, size_type __pos = 0) const noexcept
322       { return this->find(__str._M_str, __pos, __str._M_len); }
323
324       /*constexpr*/ size_type
325       find(_CharT __c, size_type __pos=0) const noexcept;
326
327       /*constexpr*/ size_type
328       find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
329
330       /*constexpr*/ size_type
331       find(const _CharT* __str, size_type __pos=0) const noexcept
332       { return this->find(__str, __pos, traits_type::length(__str)); }
333
334       /*constexpr*/ size_type
335       rfind(basic_string_view __str, size_type __pos = npos) const noexcept
336       { return this->rfind(__str._M_str, __pos, __str._M_len); }
337
338       /*constexpr*/ size_type
339       rfind(_CharT __c, size_type __pos = npos) const noexcept;
340
341       /*constexpr*/ size_type
342       rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
343
344       /*constexpr*/ size_type
345       rfind(const _CharT* __str, size_type __pos = npos) const noexcept
346       { return this->rfind(__str, __pos, traits_type::length(__str)); }
347
348       /*constexpr*/ size_type
349       find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
350       { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
351
352       /*constexpr*/ size_type
353       find_first_of(_CharT __c, size_type __pos = 0) const noexcept
354       { return this->find(__c, __pos); }
355
356       /*constexpr*/ size_type
357       find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
358
359       /*constexpr*/ size_type
360       find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
361       { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
362
363       /*constexpr*/ size_type
364       find_last_of(basic_string_view __str,
365                    size_type __pos = npos) const noexcept
366       { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
367
368       size_type
369       find_last_of(_CharT __c, size_type __pos=npos) const noexcept
370       { return this->rfind(__c, __pos); }
371
372       /*constexpr*/ size_type
373       find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
374
375       /*constexpr*/ size_type
376       find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
377       { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
378
379       /*constexpr*/ size_type
380       find_first_not_of(basic_string_view __str,
381                         size_type __pos = 0) const noexcept
382       { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
383
384       /*constexpr*/ size_type
385       find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
386
387       /*constexpr*/ size_type
388       find_first_not_of(const _CharT* __str,
389                         size_type __pos, size_type __n) const;
390
391       /*constexpr*/ size_type
392       find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
393       {
394         return this->find_first_not_of(__str, __pos,
395                                        traits_type::length(__str));
396       }
397
398       /*constexpr*/ size_type
399       find_last_not_of(basic_string_view __str,
400                        size_type __pos = npos) const noexcept
401       { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
402
403       /*constexpr*/ size_type
404       find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
405
406       /*constexpr*/ size_type
407       find_last_not_of(const _CharT* __str,
408                        size_type __pos, size_type __n) const;
409
410       /*constexpr*/ size_type
411       find_last_not_of(const _CharT* __str,
412                        size_type __pos = npos) const noexcept
413       {
414         return this->find_last_not_of(__str, __pos,
415                                       traits_type::length(__str));
416       }
417
418     private:
419
420       static constexpr int
421       _S_compare(size_type __n1, size_type __n2) noexcept
422       {
423         return difference_type(__n1 - __n2) > std::numeric_limits<int>::max()
424              ? std::numeric_limits<int>::max()
425              : difference_type(__n1 - __n2) < std::numeric_limits<int>::min()
426              ? std::numeric_limits<int>::min()
427              : static_cast<int>(difference_type(__n1 - __n2));
428       }
429
430       size_t        _M_len;
431       const _CharT* _M_str;
432     };
433
434   // [string.view.comparison], non-member basic_string_view comparison functions
435
436   namespace __detail
437   {
438     // Identity transform to create a non-deduced context, so that only one
439     // argument participates in template argument deduction and the other
440     // argument gets implicitly converted to the deduced type. See n3766.html.
441     template<typename _Tp>
442       using __idt = typename std::common_type<_Tp>::type;
443   }
444
445   template<typename _CharT, typename _Traits>
446     /*constexpr*/ bool
447     operator==(basic_string_view<_CharT, _Traits> __x,
448                basic_string_view<_CharT, _Traits> __y) noexcept
449     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
450
451   template<typename _CharT, typename _Traits>
452     /*constexpr*/ bool
453     operator==(basic_string_view<_CharT, _Traits> __x,
454                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
455     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
456
457   template<typename _CharT, typename _Traits>
458     /*constexpr*/ bool
459     operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
460                basic_string_view<_CharT, _Traits> __y) noexcept
461     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
462
463   template<typename _CharT, typename _Traits>
464     /*constexpr*/ bool
465     operator!=(basic_string_view<_CharT, _Traits> __x,
466                basic_string_view<_CharT, _Traits> __y) noexcept
467     { return !(__x == __y); }
468
469   template<typename _CharT, typename _Traits>
470     /*constexpr*/ bool
471     operator!=(basic_string_view<_CharT, _Traits> __x,
472                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
473     { return !(__x == __y); }
474
475   template<typename _CharT, typename _Traits>
476     /*constexpr*/ bool
477     operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
478                basic_string_view<_CharT, _Traits> __y) noexcept
479     { return !(__x == __y); }
480
481   template<typename _CharT, typename _Traits>
482     /*constexpr*/ bool
483     operator< (basic_string_view<_CharT, _Traits> __x,
484                basic_string_view<_CharT, _Traits> __y) noexcept
485     { return __x.compare(__y) < 0; }
486
487   template<typename _CharT, typename _Traits>
488     /*constexpr*/ bool
489     operator< (basic_string_view<_CharT, _Traits> __x,
490                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
491     { return __x.compare(__y) < 0; }
492
493   template<typename _CharT, typename _Traits>
494     /*constexpr*/ bool
495     operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
496                basic_string_view<_CharT, _Traits> __y) noexcept
497     { return __x.compare(__y) < 0; }
498
499   template<typename _CharT, typename _Traits>
500     /*constexpr*/ bool
501     operator> (basic_string_view<_CharT, _Traits> __x,
502                basic_string_view<_CharT, _Traits> __y) noexcept
503     { return __x.compare(__y) > 0; }
504
505   template<typename _CharT, typename _Traits>
506     /*constexpr*/ bool
507     operator> (basic_string_view<_CharT, _Traits> __x,
508                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
509     { return __x.compare(__y) > 0; }
510
511   template<typename _CharT, typename _Traits>
512     /*constexpr*/ bool
513     operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
514                basic_string_view<_CharT, _Traits> __y) noexcept
515     { return __x.compare(__y) > 0; }
516
517   template<typename _CharT, typename _Traits>
518     /*constexpr*/ bool
519     operator<=(basic_string_view<_CharT, _Traits> __x,
520                basic_string_view<_CharT, _Traits> __y) noexcept
521     { return __x.compare(__y) <= 0; }
522
523   template<typename _CharT, typename _Traits>
524     /*constexpr*/ bool
525     operator<=(basic_string_view<_CharT, _Traits> __x,
526                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
527     { return __x.compare(__y) <= 0; }
528
529   template<typename _CharT, typename _Traits>
530     /*constexpr*/ bool
531     operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
532                basic_string_view<_CharT, _Traits> __y) noexcept
533     { return __x.compare(__y) <= 0; }
534
535   template<typename _CharT, typename _Traits>
536     /*constexpr*/ bool
537     operator>=(basic_string_view<_CharT, _Traits> __x,
538                basic_string_view<_CharT, _Traits> __y) noexcept
539     { return __x.compare(__y) >= 0; }
540
541   template<typename _CharT, typename _Traits>
542     /*constexpr*/ bool
543     operator>=(basic_string_view<_CharT, _Traits> __x,
544                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
545     { return __x.compare(__y) >= 0; }
546
547   template<typename _CharT, typename _Traits>
548     /*constexpr*/ bool
549     operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
550                basic_string_view<_CharT, _Traits> __y) noexcept
551     { return __x.compare(__y) >= 0; }
552
553   // basic_string_view typedef names
554
555   using string_view = basic_string_view<char>;
556 } /* namespace gdb */
557
558 #include "gdb_string_view.tcc"
559
560 #endif // __cplusplus < 201703L
561
562 #endif /* COMMON_GDB_STRING_VIEW_H */