* testsuite/26_numerics/headers/cmath/hypot.cc: XFAIL on AIX.
[official-gcc.git] / libstdc++-v3 / include / std / string_view
blobcf728dd83e97fc4b08678474e65222aaf11bb2f9
1 // Components for manipulating non-owning sequences of characters -*- C++ -*-
3 // Copyright (C) 2013-2016 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 string_view
26  *  This is a Standard C++ Library header.
27  */
30 // N3762 basic_string_view library
33 #ifndef _GLIBCXX_STRING_VIEW
34 #define _GLIBCXX_STRING_VIEW 1
36 #pragma GCC system_header
38 #if __cplusplus <= 201402L
39 # include <bits/c++17_warning.h>
40 #else
42 #include <limits>
43 #include <iosfwd>
44 #include <bits/char_traits.h>
45 #include <bits/functional_hash.h>
46 #include <bits/range_access.h>
48 namespace std _GLIBCXX_VISIBILITY(default)
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52   /**
53    *  @class basic_string_view <string_view>
54    *  @brief  A non-owning reference to a string.
55    *
56    *  @ingroup strings
57    *  @ingroup sequences
58    *
59    *  @tparam _CharT  Type of character
60    *  @tparam _Traits  Traits for character type, defaults to
61    *                   char_traits<_CharT>.
62    *
63    *  A basic_string_view looks like this:
64    *
65    *  @code
66    *    _CharT*    _M_str
67    *    size_t     _M_len
68    *  @endcode
69    */
70   template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
71     class basic_string_view
72     {
73     public:
75       // types
76       using traits_type = _Traits;
77       using value_type = _CharT;
78       using pointer = const _CharT*;
79       using const_pointer = const _CharT*;
80       using reference = const _CharT&;
81       using const_reference = const _CharT&;
82       using const_iterator = const _CharT*;
83       using iterator = const_iterator;
84       using const_reverse_iterator = std::reverse_iterator<const_iterator>;
85       using reverse_iterator = const_reverse_iterator;
86       using size_type = size_t;
87       using difference_type = ptrdiff_t;
88       static constexpr size_type npos = size_type(-1);
90       // [string.view.cons], construct/copy
92       constexpr
93       basic_string_view() noexcept
94       : _M_len{0}, _M_str{nullptr}
95       { }
97       constexpr basic_string_view(const basic_string_view&) noexcept = default;
99       constexpr basic_string_view(const _CharT* __str)
100       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
101         _M_str{__str}
102       { }
104       constexpr basic_string_view(const _CharT* __str, size_type __len)
105       : _M_len{__len},
106         _M_str{__str}
107       { }
109       basic_string_view&
110       operator=(const basic_string_view&) noexcept = default;
112       // [string.view.iterators], iterators
114       constexpr const_iterator
115       begin() const noexcept
116       { return this->_M_str; }
118       constexpr const_iterator
119       end() const noexcept
120       { return this->_M_str + this->_M_len; }
122       constexpr const_iterator
123       cbegin() const noexcept
124       { return this->_M_str; }
126       constexpr const_iterator
127       cend() const noexcept
128       { return this->_M_str + this->_M_len; }
130       const_reverse_iterator
131       rbegin() const noexcept
132       { return const_reverse_iterator(this->end()); }
134       const_reverse_iterator
135       rend() const noexcept
136       { return const_reverse_iterator(this->begin()); }
138       const_reverse_iterator
139       crbegin() const noexcept
140       { return const_reverse_iterator(this->end()); }
142       const_reverse_iterator
143       crend() const noexcept
144       { return const_reverse_iterator(this->begin()); }
146       // [string.view.capacity], capacity
148       constexpr size_type
149       size() const noexcept
150       { return this->_M_len; }
152       constexpr size_type
153       length() const noexcept
154       { return _M_len; }
156       constexpr size_type
157       max_size() const noexcept
158       {
159         return (npos - sizeof(size_type) - sizeof(void*))
160                 / sizeof(value_type) / 4;
161       }
163       constexpr bool
164       empty() const noexcept
165       { return this->_M_len == 0; }
167       // [string.view.access], element access
169       constexpr const _CharT&
170       operator[](size_type __pos) const noexcept
171       {
172         // TODO: Assert to restore in a way compatible with the constexpr.
173         // __glibcxx_assert(__pos < this->_M_len);
174         return *(this->_M_str + __pos);
175       }
177       constexpr const _CharT&
178       at(size_type __pos) const
179       {
180         return __pos < this->_M_len
181              ? *(this->_M_str + __pos)
182              : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
183                                              "(which is %zu) >= this->size() "
184                                              "(which is %zu)"),
185                                          __pos, this->size()),
186                 *this->_M_str);
187       }
189       constexpr const _CharT&
190       front() const
191       {
192         // TODO: Assert to restore in a way compatible with the constexpr.
193         // __glibcxx_assert(this->_M_len > 0);
194         return *this->_M_str;
195       }
197       constexpr const _CharT&
198       back() const
199       {
200         // TODO: Assert to restore in a way compatible with the constexpr.
201         // __glibcxx_assert(this->_M_len > 0);
202         return *(this->_M_str + this->_M_len - 1);
203       }
205       constexpr const _CharT*
206       data() const noexcept
207       { return this->_M_str; }
209       // [string.view.modifiers], modifiers:
211       void
212       remove_prefix(size_type __n)
213       {
214         __glibcxx_assert(this->_M_len >= __n);
215         this->_M_str += __n;
216         this->_M_len -= __n;
217       }
219       void
220       remove_suffix(size_type __n)
221       { this->_M_len -= __n; }
223       void
224       swap(basic_string_view& __sv) noexcept
225       {
226         std::swap(this->_M_len, __sv._M_len);
227         std::swap(this->_M_str, __sv._M_str);
228       }
231       // [string.view.ops], string operations:
233       size_type
234       copy(_CharT* __str, size_type __n, size_type __pos = 0) const
235       {
236         __glibcxx_requires_string_len(__str, __n);
237         if (__pos > this->_M_len)
238           __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos "
239                                        "(which is %zu) > this->size() "
240                                        "(which is %zu)"),
241                                    __pos, this->size());
242         size_type __rlen{std::min(__n, size_type{this->_M_len  - __pos})};
243         for (auto __begin = this->_M_str + __pos,
244              __end = __begin + __rlen; __begin != __end;)
245           *__str++ = *__begin++;
246         return __rlen;
247       }
250       // [string.view.ops], string operations:
252       constexpr basic_string_view
253       substr(size_type __pos, size_type __n=npos) const
254       {
255         return __pos <= this->_M_len
256              ? basic_string_view{this->_M_str + __pos,
257                                 std::min(__n, size_type{this->_M_len  - __pos})}
258              : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos "
259                                              "(which is %zu) > this->size() "
260                                              "(which is %zu)"),
261                                      __pos, this->size()), basic_string_view{});
262       }
264       int
265       compare(basic_string_view __str) const noexcept
266       {
267         int __ret = traits_type::compare(this->_M_str, __str._M_str,
268                                          std::min(this->_M_len, __str._M_len));
269         if (__ret == 0)
270           __ret = _S_compare(this->_M_len, __str._M_len);
271         return __ret;
272       }
274       int
275       compare(size_type __pos1, size_type __n1, basic_string_view __str) const
276       { return this->substr(__pos1, __n1).compare(__str); }
278       int
279       compare(size_type __pos1, size_type __n1,
280               basic_string_view __str, size_type __pos2, size_type __n2) const
281       { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
283       int
284       compare(const _CharT* __str) const noexcept
285       { return this->compare(basic_string_view{__str}); }
287       int
288       compare(size_type __pos1, size_type __n1, const _CharT* __str) const
289       { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
291       int
292       compare(size_type __pos1, size_type __n1,
293               const _CharT* __str, size_type __n2) const
294       {
295         return this->substr(__pos1, __n1)
296                    .compare(basic_string_view(__str, __n2));
297       }
299       size_type
300       find(basic_string_view __str, size_type __pos = 0) const noexcept
301       { return this->find(__str._M_str, __pos, __str._M_len); }
303       size_type
304       find(_CharT __c, size_type __pos=0) const noexcept;
306       size_type
307       find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
309       size_type
310       find(const _CharT* __str, size_type __pos=0) const noexcept
311       { return this->find(__str, __pos, traits_type::length(__str)); }
313       size_type
314       rfind(basic_string_view __str, size_type __pos = npos) const noexcept
315       { return this->rfind(__str._M_str, __pos, __str._M_len); }
317       size_type
318       rfind(_CharT __c, size_type __pos = npos) const noexcept;
320       size_type
321       rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
323       size_type
324       rfind(const _CharT* __str, size_type __pos = npos) const noexcept
325       { return this->rfind(__str, __pos, traits_type::length(__str)); }
327       size_type
328       find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
329       { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
331       size_type
332       find_first_of(_CharT __c, size_type __pos = 0) const noexcept
333       { return this->find(__c, __pos); }
335       size_type
336       find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
338       size_type
339       find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
340       { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
342       size_type
343       find_last_of(basic_string_view __str,
344                    size_type __pos = npos) const noexcept
345       { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
347       size_type
348       find_last_of(_CharT __c, size_type __pos=npos) const noexcept
349       { return this->rfind(__c, __pos); }
351       size_type
352       find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
354       size_type
355       find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
356       { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
358       size_type
359       find_first_not_of(basic_string_view __str,
360                         size_type __pos = 0) const noexcept
361       { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
363       size_type
364       find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
366       size_type
367       find_first_not_of(const _CharT* __str,
368                         size_type __pos, size_type __n) const;
370       size_type
371       find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
372       {
373         return this->find_first_not_of(__str, __pos,
374                                        traits_type::length(__str));
375       }
377       size_type
378       find_last_not_of(basic_string_view __str,
379                        size_type __pos = npos) const noexcept
380       { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
382       size_type
383       find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
385       size_type
386       find_last_not_of(const _CharT* __str,
387                        size_type __pos, size_type __n) const;
389       size_type
390       find_last_not_of(const _CharT* __str,
391                        size_type __pos = npos) const noexcept
392       {
393         return this->find_last_not_of(__str, __pos,
394                                       traits_type::length(__str));
395       }
397       size_type
398       _M_check(size_type __pos, const char* __s) const
399       {
400         if (__pos > this->size())
401           __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
402                                        "this->size() (which is %zu)"),
403                                    __s, __pos, this->size());
404         return __pos;
405       }
407       // NB: _M_limit doesn't check for a bad __pos value.
408       size_type
409       _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
410       {
411         const bool __testoff =  __off < this->size() - __pos;
412         return __testoff ? __off : this->size() - __pos;
413       }
414       
415     private:
417       static constexpr int
418       _S_compare(size_type __n1, size_type __n2) noexcept
419       {
420         return difference_type{__n1 - __n2} > std::numeric_limits<int>::max()
421              ? std::numeric_limits<int>::max()
422              : difference_type{__n1 - __n2} < std::numeric_limits<int>::min()
423              ? std::numeric_limits<int>::min()
424              : static_cast<int>(difference_type{__n1 - __n2});
425       }
427       size_t        _M_len;
428       const _CharT* _M_str;
429     };
430 _GLIBCXX_END_NAMESPACE_VERSION
432   // [string.view.comparison], non-member basic_string_view comparison function
433   namespace __detail
434   {
435 _GLIBCXX_BEGIN_NAMESPACE_VERSION
436     //  Identity transform to make ADL work with just one argument.
437     //  See n3766.html.
438     template<typename _Tp = void>
439       struct __identity
440       { typedef _Tp type; };
442     template<>
443       struct __identity<void>;
445     template<typename _Tp>
446       using __idt = typename __identity<_Tp>::type;
447 _GLIBCXX_END_NAMESPACE_VERSION
448   }
450 _GLIBCXX_BEGIN_NAMESPACE_VERSION
452   template<typename _CharT, typename _Traits>
453     inline bool
454     operator==(basic_string_view<_CharT, _Traits> __x,
455                basic_string_view<_CharT, _Traits> __y) noexcept
456     { return __x.compare(__y) == 0; }
458   template<typename _CharT, typename _Traits>
459     inline bool
460     operator==(basic_string_view<_CharT, _Traits> __x,
461                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
462     { return __x.compare(__y) == 0; }
464   template<typename _CharT, typename _Traits>
465     inline bool
466     operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
467                basic_string_view<_CharT, _Traits> __y) noexcept
468     { return __x.compare(__y) == 0; }
470   template<typename _CharT, typename _Traits>
471     inline bool
472     operator!=(basic_string_view<_CharT, _Traits> __x,
473                basic_string_view<_CharT, _Traits> __y) noexcept
474     { return !(__x == __y); }
476   template<typename _CharT, typename _Traits>
477     inline bool
478     operator!=(basic_string_view<_CharT, _Traits> __x,
479                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
480     { return !(__x == __y); }
482   template<typename _CharT, typename _Traits>
483     inline bool
484     operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
485                basic_string_view<_CharT, _Traits> __y) noexcept
486     { return !(__x == __y); }
488   template<typename _CharT, typename _Traits>
489     inline bool
490     operator< (basic_string_view<_CharT, _Traits> __x,
491                basic_string_view<_CharT, _Traits> __y) noexcept
492     { return __x.compare(__y) < 0; }
494   template<typename _CharT, typename _Traits>
495     inline bool
496     operator< (basic_string_view<_CharT, _Traits> __x,
497                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
498     { return __x.compare(__y) < 0; }
500   template<typename _CharT, typename _Traits>
501     inline bool
502     operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
503                basic_string_view<_CharT, _Traits> __y) noexcept
504     { return __x.compare(__y) < 0; }
506   template<typename _CharT, typename _Traits>
507     inline bool
508     operator> (basic_string_view<_CharT, _Traits> __x,
509                basic_string_view<_CharT, _Traits> __y) noexcept
510     { return __x.compare(__y) > 0; }
512   template<typename _CharT, typename _Traits>
513     inline bool
514     operator> (basic_string_view<_CharT, _Traits> __x,
515                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
516     { return __x.compare(__y) > 0; }
518   template<typename _CharT, typename _Traits>
519     inline bool
520     operator> (__detail::__idt<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     inline bool
526     operator<=(basic_string_view<_CharT, _Traits> __x,
527                basic_string_view<_CharT, _Traits> __y) noexcept
528     { return __x.compare(__y) <= 0; }
530   template<typename _CharT, typename _Traits>
531     inline bool
532     operator<=(basic_string_view<_CharT, _Traits> __x,
533                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
534     { return __x.compare(__y) <= 0; }
536   template<typename _CharT, typename _Traits>
537     inline bool
538     operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
539                basic_string_view<_CharT, _Traits> __y) noexcept
540     { return __x.compare(__y) <= 0; }
542   template<typename _CharT, typename _Traits>
543     inline bool
544     operator>=(basic_string_view<_CharT, _Traits> __x,
545                basic_string_view<_CharT, _Traits> __y) noexcept
546     { return __x.compare(__y) >= 0; }
548   template<typename _CharT, typename _Traits>
549     inline bool
550     operator>=(basic_string_view<_CharT, _Traits> __x,
551                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
552     { return __x.compare(__y) >= 0; }
554   template<typename _CharT, typename _Traits>
555     inline bool
556     operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
557                basic_string_view<_CharT, _Traits> __y) noexcept
558     { return __x.compare(__y) >= 0; }
560   // [string.view.io], Inserters and extractors
561   template<typename _CharT, typename _Traits>
562     inline basic_ostream<_CharT, _Traits>&
563     operator<<(basic_ostream<_CharT, _Traits>& __os,
564                basic_string_view<_CharT,_Traits> __str)
565     { return __ostream_insert(__os, __str.data(), __str.size()); }
568   // basic_string_view typedef names
570   using string_view = basic_string_view<char>;
571 #ifdef _GLIBCXX_USE_WCHAR_T
572   using wstring_view = basic_string_view<wchar_t>;
573 #endif
574 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
575   using u16string_view = basic_string_view<char16_t>;
576   using u32string_view = basic_string_view<char32_t>;
577 #endif
579   // [string.view.hash], hash support:
581   template<typename _Tp>
582     struct hash;
584   template<>
585     struct hash<string_view>
586     : public __hash_base<size_t, string_view>
587     {
588       size_t
589       operator()(const string_view& __str) const noexcept
590       { return std::_Hash_impl::hash(__str.data(), __str.length()); }
591     };
593   template<>
594     struct __is_fast_hash<hash<string_view>> : std::false_type
595     { };
597 #ifdef _GLIBCXX_USE_WCHAR_T
598   template<>
599     struct hash<wstring_view>
600     : public __hash_base<size_t, wstring>
601     {
602       size_t
603       operator()(const wstring_view& __s) const noexcept
604       { return std::_Hash_impl::hash(__s.data(),
605                                      __s.length() * sizeof(wchar_t)); }
606     };
608   template<>
609     struct __is_fast_hash<hash<wstring_view>> : std::false_type
610     { };
611 #endif
613 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
614   template<>
615     struct hash<u16string_view>
616     : public __hash_base<size_t, u16string_view>
617     {
618       size_t
619       operator()(const u16string_view& __s) const noexcept
620       { return std::_Hash_impl::hash(__s.data(),
621                                      __s.length() * sizeof(char16_t)); }
622     };
624   template<>
625     struct __is_fast_hash<hash<u16string_view>> : std::false_type
626     { };
628   template<>
629     struct hash<u32string_view>
630     : public __hash_base<size_t, u32string_view>
631     {
632       size_t
633       operator()(const u32string_view& __s) const noexcept
634       { return std::_Hash_impl::hash(__s.data(),
635                                      __s.length() * sizeof(char32_t)); }
636     };
638   template<>
639     struct __is_fast_hash<hash<u32string_view>> : std::false_type
640     { };
641 #endif
643   inline namespace literals
644   {
645   inline namespace string_view_literals
646   {
647   _GLIBCXX_BEGIN_NAMESPACE_VERSION
649     inline constexpr basic_string_view<char>
650     operator""sv(const char* __str, size_t __len)
651     { return basic_string_view<char>{__str, __len}; }
653 #ifdef _GLIBCXX_USE_WCHAR_T
654     inline constexpr basic_string_view<wchar_t>
655     operator""sv(const wchar_t* __str, size_t __len)
656     { return basic_string_view<wchar_t>{__str, __len}; }
657 #endif
659 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
660     inline constexpr basic_string_view<char16_t>
661     operator""sv(const char16_t* __str, size_t __len)
662     { return basic_string_view<char16_t>{__str, __len}; }
664     inline constexpr basic_string_view<char32_t>
665     operator""sv(const char32_t* __str, size_t __len)
666     { return basic_string_view<char32_t>{__str, __len}; }
667 #endif
669   _GLIBCXX_END_NAMESPACE_VERSION
670   } // namespace string_literals
671   } // namespace literals
673 _GLIBCXX_END_NAMESPACE_VERSION
674 } // namespace std
676 #include <bits/string_view.tcc>
678 #endif // __cplusplus <= 201402L
680 #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW