Add support for 32-bit hppa targets in muldi3 expander
[official-gcc.git] / libstdc++-v3 / include / experimental / string_view
blobb8e4db8ef30731122b9e3bc45e2bcd65c77ddd2d
1 // Components for manipulating non-owning sequences of characters -*- C++ -*-
3 // Copyright (C) 2013-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file experimental/string_view
26  *  This is a TS C++ Library header.
27  *  @ingroup libfund-ts
28  */
31 // N3762 basic_string_view library
34 #ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW
35 #define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1
37 #pragma GCC system_header
39 #if __cplusplus >= 201402L
41 #include <string>
42 #include <limits>
43 #include <bits/ranges_base.h> // enable_borrowed_range, enable_view
44 #include <experimental/bits/lfts_config.h>
46 namespace std _GLIBCXX_VISIBILITY(default)
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 namespace experimental
52 inline namespace fundamentals_v1
54 #define __cpp_lib_experimental_string_view 201411
56   /**
57    *  @class basic_string_view <experimental/string_view>
58    *  @brief  A non-owning reference to a string.
59    *
60    *  @ingroup strings
61    *  @ingroup sequences
62    *  @ingroup libfund-ts
63    *
64    *  @tparam _CharT  Type of character
65    *  @tparam _Traits  Traits for character type, defaults to
66    *                   char_traits<_CharT>.
67    *
68    *  A basic_string_view looks like this:
69    *
70    *  @code
71    *    _CharT*    _M_str
72    *    size_t     _M_len
73    *  @endcode
74    */
75   template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
76     class basic_string_view
77     {
78     public:
80       // types
81       using traits_type = _Traits;
82       using value_type = _CharT;
83       using pointer = _CharT*;
84       using const_pointer = const _CharT*;
85       using reference = _CharT&;
86       using const_reference = const _CharT&;
87       using const_iterator = const _CharT*;
88       using iterator = const_iterator;
89       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
90       using reverse_iterator = const_reverse_iterator;
91       using size_type = size_t;
92       using difference_type = ptrdiff_t;
93       static constexpr size_type npos = size_type(-1);
95       // [string.view.cons], construct/copy
97       constexpr
98       basic_string_view() noexcept
99       : _M_len{0}, _M_str{nullptr}
100       { }
102       constexpr basic_string_view(const basic_string_view&) noexcept = default;
104       template<typename _Allocator>
105         basic_string_view(const basic_string<_CharT, _Traits,
106                           _Allocator>& __str) noexcept
107         : _M_len{__str.length()}, _M_str{__str.data()}
108         { }
110       constexpr basic_string_view(const _CharT* __str)
111       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
112         _M_str{__str}
113       { }
115       constexpr basic_string_view(const _CharT* __str, size_type __len)
116       : _M_len{__len},
117         _M_str{__str}
118       { }
120       basic_string_view&
121       operator=(const basic_string_view&) noexcept = default;
123       // [string.view.iterators], iterators
125       constexpr const_iterator
126       begin() const noexcept
127       { return this->_M_str; }
129       constexpr const_iterator
130       end() const noexcept
131       { return this->_M_str + this->_M_len; }
133       constexpr const_iterator
134       cbegin() const noexcept
135       { return this->_M_str; }
137       constexpr const_iterator
138       cend() const noexcept
139       { return this->_M_str + this->_M_len; }
141       const_reverse_iterator
142       rbegin() const noexcept
143       { return const_reverse_iterator(this->end()); }
145       const_reverse_iterator
146       rend() const noexcept
147       { return const_reverse_iterator(this->begin()); }
149       const_reverse_iterator
150       crbegin() const noexcept
151       { return const_reverse_iterator(this->end()); }
153       const_reverse_iterator
154       crend() const noexcept
155       { return const_reverse_iterator(this->begin()); }
157       // [string.view.capacity], capacity
159       constexpr size_type
160       size() const noexcept
161       { return this->_M_len; }
163       constexpr size_type
164       length() const noexcept
165       { return _M_len; }
167       constexpr size_type
168       max_size() const noexcept
169       {
170         return (npos - sizeof(size_type) - sizeof(void*))
171                 / sizeof(value_type) / 4;
172       }
174       _GLIBCXX_NODISCARD constexpr bool
175       empty() const noexcept
176       { return this->_M_len == 0; }
178       // [string.view.access], element access
180       constexpr const _CharT&
181       operator[](size_type __pos) const
182       {
183         __glibcxx_assert(__pos < this->_M_len);
184         return *(this->_M_str + __pos);
185       }
187       constexpr const _CharT&
188       at(size_type __pos) const
189       {
190         return __pos < this->_M_len
191              ? *(this->_M_str + __pos)
192              : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
193                                              "(which is %zu) >= this->size() "
194                                              "(which is %zu)"),
195                                          __pos, this->size()),
196                 *this->_M_str);
197       }
199       constexpr const _CharT&
200       front() const
201       {
202         __glibcxx_assert(this->_M_len > 0);
203         return *this->_M_str;
204       }
206       constexpr const _CharT&
207       back() const
208       {
209         __glibcxx_assert(this->_M_len > 0);
210         return *(this->_M_str + this->_M_len - 1);
211       }
213       constexpr const _CharT*
214       data() const noexcept
215       { return this->_M_str; }
217       // [string.view.modifiers], modifiers:
219       constexpr void
220       remove_prefix(size_type __n)
221       {
222         __glibcxx_assert(this->_M_len >= __n);
223         this->_M_str += __n;
224         this->_M_len -= __n;
225       }
227       constexpr void
228       remove_suffix(size_type __n)
229       { this->_M_len -= __n; }
231       constexpr void
232       swap(basic_string_view& __sv) noexcept
233       {
234         auto __tmp = *this;
235         *this = __sv;
236         __sv = __tmp;
237       }
240       // [string.view.ops], string operations:
242       template<typename _Allocator>
243         explicit operator basic_string<_CharT, _Traits, _Allocator>() const
244         {
245           return { this->_M_str, this->_M_len };
246         }
248       template<typename _Allocator = std::allocator<_CharT>>
249         basic_string<_CharT, _Traits, _Allocator>
250         to_string(const _Allocator& __alloc = _Allocator()) const
251         {
252           return { this->_M_str, this->_M_len, __alloc };
253         }
255       size_type
256       copy(_CharT* __str, size_type __n, size_type __pos = 0) const
257       {
258         __glibcxx_requires_string_len(__str, __n);
259         if (__pos > this->_M_len)
260           __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos "
261                                        "(which is %zu) > this->size() "
262                                        "(which is %zu)"),
263                                    __pos, this->size());
264         size_type __rlen{std::min(__n, size_type{this->_M_len  - __pos})};
265         for (auto __begin = this->_M_str + __pos,
266              __end = __begin + __rlen; __begin != __end;)
267           *__str++ = *__begin++;
268         return __rlen;
269       }
272       // [string.view.ops], string operations:
274       constexpr basic_string_view
275       substr(size_type __pos = 0, size_type __n = npos) const
276       {
277         return __pos <= this->_M_len
278              ? basic_string_view{this->_M_str + __pos,
279                                 std::min(__n, size_type{this->_M_len  - __pos})}
280              : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos "
281                                              "(which is %zu) > this->size() "
282                                              "(which is %zu)"),
283                                      __pos, this->size()), basic_string_view{});
284       }
286       constexpr int
287       compare(basic_string_view __str) const noexcept
288       {
289         int __ret = traits_type::compare(this->_M_str, __str._M_str,
290                                          std::min(this->_M_len, __str._M_len));
291         if (__ret == 0)
292           __ret = _S_compare(this->_M_len, __str._M_len);
293         return __ret;
294       }
296       constexpr int
297       compare(size_type __pos1, size_type __n1, basic_string_view __str) const
298       { return this->substr(__pos1, __n1).compare(__str); }
300       constexpr int
301       compare(size_type __pos1, size_type __n1,
302               basic_string_view __str, size_type __pos2, size_type __n2) const
303       { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
305       constexpr int
306       compare(const _CharT* __str) const noexcept
307       { return this->compare(basic_string_view{__str}); }
309       constexpr int
310       compare(size_type __pos1, size_type __n1, const _CharT* __str) const
311       { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
313       constexpr int
314       compare(size_type __pos1, size_type __n1,
315               const _CharT* __str, size_type __n2) const
316       {
317         return this->substr(__pos1, __n1)
318                    .compare(basic_string_view(__str, __n2));
319       }
321       constexpr size_type
322       find(basic_string_view __str, size_type __pos = 0) const noexcept
323       { return this->find(__str._M_str, __pos, __str._M_len); }
325       constexpr size_type
326       find(_CharT __c, size_type __pos=0) const noexcept;
328       constexpr size_type
329       find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
331       constexpr size_type
332       find(const _CharT* __str, size_type __pos=0) const noexcept
333       { return this->find(__str, __pos, traits_type::length(__str)); }
335       constexpr size_type
336       rfind(basic_string_view __str, size_type __pos = npos) const noexcept
337       { return this->rfind(__str._M_str, __pos, __str._M_len); }
339       constexpr size_type
340       rfind(_CharT __c, size_type __pos = npos) const noexcept;
342       constexpr size_type
343       rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
345       constexpr size_type
346       rfind(const _CharT* __str, size_type __pos = npos) const noexcept
347       { return this->rfind(__str, __pos, traits_type::length(__str)); }
349       constexpr size_type
350       find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
351       { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
353       constexpr size_type
354       find_first_of(_CharT __c, size_type __pos = 0) const noexcept
355       { return this->find(__c, __pos); }
357       constexpr size_type
358       find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
360       constexpr size_type
361       find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
362       { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
364       constexpr size_type
365       find_last_of(basic_string_view __str,
366                    size_type __pos = npos) const noexcept
367       { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
369       constexpr size_type
370       find_last_of(_CharT __c, size_type __pos=npos) const noexcept
371       { return this->rfind(__c, __pos); }
373       constexpr size_type
374       find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
376       constexpr size_type
377       find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
378       { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
380       constexpr size_type
381       find_first_not_of(basic_string_view __str,
382                         size_type __pos = 0) const noexcept
383       { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
385       constexpr size_type
386       find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
388       constexpr size_type
389       find_first_not_of(const _CharT* __str,
390                         size_type __pos, size_type __n) const;
392       constexpr size_type
393       find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
394       {
395         return this->find_first_not_of(__str, __pos,
396                                        traits_type::length(__str));
397       }
399       constexpr size_type
400       find_last_not_of(basic_string_view __str,
401                        size_type __pos = npos) const noexcept
402       { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
404       constexpr size_type
405       find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
407       constexpr size_type
408       find_last_not_of(const _CharT* __str,
409                        size_type __pos, size_type __n) const;
411       constexpr size_type
412       find_last_not_of(const _CharT* __str,
413                        size_type __pos = npos) const noexcept
414       {
415         return this->find_last_not_of(__str, __pos,
416                                       traits_type::length(__str));
417       }
419     private:
421       static constexpr int
422       _S_compare(size_type __n1, size_type __n2) noexcept
423       {
424         return difference_type(__n1 - __n2) > std::numeric_limits<int>::max()
425              ? std::numeric_limits<int>::max()
426              : difference_type(__n1 - __n2) < std::numeric_limits<int>::min()
427              ? std::numeric_limits<int>::min()
428              : static_cast<int>(difference_type(__n1 - __n2));
429       }
431       size_t        _M_len;
432       const _CharT* _M_str;
433     };
435   // [string.view.comparison], non-member basic_string_view comparison functions
437   // Several of these functions use type_identity_t to create a non-deduced
438   // context, so that only one argument participates in template argument
439   // deduction and the other argument gets implicitly converted to the deduced
440   // type (see N3766).
442   template<typename _CharT, typename _Traits>
443     constexpr bool
444     operator==(basic_string_view<_CharT, _Traits> __x,
445                basic_string_view<_CharT, _Traits> __y) noexcept
446     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
448   template<typename _CharT, typename _Traits>
449     constexpr bool
450     operator==(basic_string_view<_CharT, _Traits> __x,
451                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
452     noexcept
453     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
455   template<typename _CharT, typename _Traits>
456     constexpr bool
457     operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
458                basic_string_view<_CharT, _Traits> __y) noexcept
459     { return __x.size() == __y.size() && __x.compare(__y) == 0; }
461   template<typename _CharT, typename _Traits>
462     constexpr bool
463     operator!=(basic_string_view<_CharT, _Traits> __x,
464                basic_string_view<_CharT, _Traits> __y) noexcept
465     { return !(__x == __y); }
467   template<typename _CharT, typename _Traits>
468     constexpr bool
469     operator!=(basic_string_view<_CharT, _Traits> __x,
470                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
471     noexcept
472     { return !(__x == __y); }
474   template<typename _CharT, typename _Traits>
475     constexpr bool
476     operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
477                basic_string_view<_CharT, _Traits> __y) noexcept
478     { return !(__x == __y); }
480   template<typename _CharT, typename _Traits>
481     constexpr bool
482     operator< (basic_string_view<_CharT, _Traits> __x,
483                basic_string_view<_CharT, _Traits> __y) noexcept
484     { return __x.compare(__y) < 0; }
486   template<typename _CharT, typename _Traits>
487     constexpr bool
488     operator< (basic_string_view<_CharT, _Traits> __x,
489                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
490     noexcept
491     { return __x.compare(__y) < 0; }
493   template<typename _CharT, typename _Traits>
494     constexpr bool
495     operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
496                basic_string_view<_CharT, _Traits> __y) noexcept
497     { return __x.compare(__y) < 0; }
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; }
505   template<typename _CharT, typename _Traits>
506     constexpr bool
507     operator> (basic_string_view<_CharT, _Traits> __x,
508                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
509     noexcept
510     { return __x.compare(__y) > 0; }
512   template<typename _CharT, typename _Traits>
513     constexpr bool
514     operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
515                basic_string_view<_CharT, _Traits> __y) noexcept
516     { return __x.compare(__y) > 0; }
518   template<typename _CharT, typename _Traits>
519     constexpr bool
520     operator<=(basic_string_view<_CharT, _Traits> __x,
521                basic_string_view<_CharT, _Traits> __y) noexcept
522     { return __x.compare(__y) <= 0; }
524   template<typename _CharT, typename _Traits>
525     constexpr bool
526     operator<=(basic_string_view<_CharT, _Traits> __x,
527                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
528     noexcept
529     { return __x.compare(__y) <= 0; }
531   template<typename _CharT, typename _Traits>
532     constexpr bool
533     operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
534                basic_string_view<_CharT, _Traits> __y) noexcept
535     { return __x.compare(__y) <= 0; }
537   template<typename _CharT, typename _Traits>
538     constexpr bool
539     operator>=(basic_string_view<_CharT, _Traits> __x,
540                basic_string_view<_CharT, _Traits> __y) noexcept
541     { return __x.compare(__y) >= 0; }
543   template<typename _CharT, typename _Traits>
544     constexpr bool
545     operator>=(basic_string_view<_CharT, _Traits> __x,
546                __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
547     noexcept
548     { return __x.compare(__y) >= 0; }
550   template<typename _CharT, typename _Traits>
551     constexpr bool
552     operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
553                basic_string_view<_CharT, _Traits> __y) noexcept
554     { return __x.compare(__y) >= 0; }
556   // [string.view.io], Inserters and extractors
557   template<typename _CharT, typename _Traits>
558     inline basic_ostream<_CharT, _Traits>&
559     operator<<(basic_ostream<_CharT, _Traits>& __os,
560                basic_string_view<_CharT,_Traits> __str)
561     { return __ostream_insert(__os, __str.data(), __str.size()); }
564   // basic_string_view typedef names
566   using string_view = basic_string_view<char>;
567   using wstring_view = basic_string_view<wchar_t>;
568 #ifdef _GLIBCXX_USE_CHAR8_T
569   using u8string_view = basic_string_view<char8_t>;
570 #endif
571   using u16string_view = basic_string_view<char16_t>;
572   using u32string_view = basic_string_view<char32_t>;
573 } // namespace fundamentals_v1
574 } // namespace experimental
577   // [string.view.hash], hash support:
578   template<typename _Tp>
579     struct hash;
581   template<>
582     struct hash<experimental::string_view>
583     : public __hash_base<size_t, experimental::string_view>
584     {
585       size_t
586       operator()(const experimental::string_view& __str) const noexcept
587       { return std::_Hash_impl::hash(__str.data(), __str.length()); }
588     };
590   template<>
591     struct __is_fast_hash<hash<experimental::string_view>> : std::false_type
592     { };
594   template<>
595     struct hash<experimental::wstring_view>
596     : public __hash_base<size_t, wstring>
597     {
598       size_t
599       operator()(const experimental::wstring_view& __s) const noexcept
600       { return std::_Hash_impl::hash(__s.data(),
601                                      __s.length() * sizeof(wchar_t)); }
602     };
604   template<>
605     struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type
606     { };
608 #ifdef _GLIBCXX_USE_CHAR8_T
609   template<>
610     struct hash<experimental::u8string_view>
611     : public __hash_base<size_t, experimental::u8string_view>
612     {
613       size_t
614       operator()(const experimental::u8string_view& __s) const noexcept
615       { return std::_Hash_impl::hash(__s.data(), __s.length()); }
616     };
618   template<>
619     struct __is_fast_hash<hash<experimental::u8string_view>> : std::false_type
620     { };
621 #endif
623   template<>
624     struct hash<experimental::u16string_view>
625     : public __hash_base<size_t, experimental::u16string_view>
626     {
627       size_t
628       operator()(const experimental::u16string_view& __s) const noexcept
629       { return std::_Hash_impl::hash(__s.data(),
630                                      __s.length() * sizeof(char16_t)); }
631     };
633   template<>
634     struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type
635     { };
637   template<>
638     struct hash<experimental::u32string_view>
639     : public __hash_base<size_t, experimental::u32string_view>
640     {
641       size_t
642       operator()(const experimental::u32string_view& __s) const noexcept
643       { return std::_Hash_impl::hash(__s.data(),
644                                      __s.length() * sizeof(char32_t)); }
645     };
647   template<>
648     struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type
649     { };
651 namespace experimental
653   // I added these EMSR.
654   inline namespace literals
655   {
656   inline namespace string_view_literals
657   {
658 #pragma GCC diagnostic push
659 #pragma GCC diagnostic ignored "-Wliteral-suffix"
660     inline constexpr basic_string_view<char>
661     operator""sv(const char* __str, size_t __len) noexcept
662     { return basic_string_view<char>{__str, __len}; }
664     inline constexpr basic_string_view<wchar_t>
665     operator""sv(const wchar_t* __str, size_t __len) noexcept
666     { return basic_string_view<wchar_t>{__str, __len}; }
668 #ifdef _GLIBCXX_USE_CHAR8_T
669     inline constexpr basic_string_view<char8_t>
670     operator""sv(const char8_t* __str, size_t __len) noexcept
671     { return basic_string_view<char8_t>{__str, __len}; }
672 #endif
674     inline constexpr basic_string_view<char16_t>
675     operator""sv(const char16_t* __str, size_t __len) noexcept
676     { return basic_string_view<char16_t>{__str, __len}; }
678     inline constexpr basic_string_view<char32_t>
679     operator""sv(const char32_t* __str, size_t __len) noexcept
680     { return basic_string_view<char32_t>{__str, __len}; }
681 #pragma GCC diagnostic pop
682   } // namespace string_literals
683   } // namespace literals
684 } // namespace experimental
686 #if __cpp_lib_concepts
687   namespace ranges
688   {
689     // Opt-in to borrowed_range concept
690     template<typename _CharT, typename _Traits>
691       inline constexpr bool
692         enable_borrowed_range<experimental::basic_string_view<_CharT, _Traits>>
693           = true;
695     // Opt-in to view concept
696     template<typename _CharT, typename _Traits>
697       inline constexpr bool
698         enable_view<experimental::basic_string_view<_CharT, _Traits>> = true;
699   }
700 #endif
702 _GLIBCXX_END_NAMESPACE_VERSION
703 } // namespace std
705 #include <experimental/bits/string_view.tcc>
707 #endif // __cplusplus <= 201103L
709 #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW