From 7adcdf08e792dc30e09af4eecbf1e479a2f56612 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 9 Apr 2018 13:31:04 -0400 Subject: [PATCH] Copy string_view files from libstdc++ This patch copies the following files from libstdc++ (commit 02a4441f002c): ${gcc}/libstdc++-v3/include/experimental/string_view -> ${binutils-gdb}/gdb/common/gdb_string_view.h ${gcc}/libstdc++-v3/include/experimental/bits/string_view.tcc -> ${binutils-gdb}/gdb/common/gdb_string_view.tcc The local modifications are done in the following patch in order to make it easier to review them. gdb/ChangeLog: * common/gdb_string_view.h: New file. * common/gdb_string_view.tcc: New file. --- gdb/ChangeLog | 5 + gdb/common/gdb_string_view.h | 680 +++++++++++++++++++++++++++++++++ gdb/common/gdb_string_view.tcc | 231 +++++++++++ 3 files changed, 916 insertions(+) create mode 100644 gdb/common/gdb_string_view.h create mode 100644 gdb/common/gdb_string_view.tcc diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f398139ecc3..631f15aad30 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2018-04-09 Simon Marchi + + * common/gdb_string_view.h: New file. + * common/gdb_string_view.tcc: New file. + 2018-04-09 Simon Marchi * ax_cxx_compile_stdcxx.m4: Sync with upstream. diff --git a/gdb/common/gdb_string_view.h b/gdb/common/gdb_string_view.h new file mode 100644 index 00000000000..e42d5acde78 --- /dev/null +++ b/gdb/common/gdb_string_view.h @@ -0,0 +1,680 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + +// Copyright (C) 2013-2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file experimental/string_view + * This is a TS C++ Library header. + */ + +// +// N3762 basic_string_view library +// + +#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW +#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1 + +#pragma GCC system_header + +#if __cplusplus >= 201402L + +#include +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace experimental +{ +inline namespace fundamentals_v1 +{ +#define __cpp_lib_experimental_string_view 201411 + + /** + * @class basic_string_view + * @brief A non-owning reference to a string. + * + * @ingroup strings + * @ingroup sequences + * @ingroup experimental + * + * @tparam _CharT Type of character + * @tparam _Traits Traits for character type, defaults to + * char_traits<_CharT>. + * + * A basic_string_view looks like this: + * + * @code + * _CharT* _M_str + * size_t _M_len + * @endcode + */ + template> + class basic_string_view + { + public: + + // types + using traits_type = _Traits; + using value_type = _CharT; + using pointer = const _CharT*; + using const_pointer = const _CharT*; + using reference = const _CharT&; + using const_reference = const _CharT&; + using const_iterator = const _CharT*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static constexpr size_type npos = size_type(-1); + + // [string.view.cons], construct/copy + + constexpr + basic_string_view() noexcept + : _M_len{0}, _M_str{nullptr} + { } + + constexpr basic_string_view(const basic_string_view&) noexcept = default; + + template + basic_string_view(const basic_string<_CharT, _Traits, + _Allocator>& __str) noexcept + : _M_len{__str.length()}, _M_str{__str.data()} + { } + + constexpr basic_string_view(const _CharT* __str) + : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, + _M_str{__str} + { } + + constexpr basic_string_view(const _CharT* __str, size_type __len) + : _M_len{__len}, + _M_str{__str} + { } + + basic_string_view& + operator=(const basic_string_view&) noexcept = default; + + // [string.view.iterators], iterators + + constexpr const_iterator + begin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + end() const noexcept + { return this->_M_str + this->_M_len; } + + constexpr const_iterator + cbegin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + cend() const noexcept + { return this->_M_str + this->_M_len; } + + const_reverse_iterator + rbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + const_reverse_iterator + rend() const noexcept + { return const_reverse_iterator(this->begin()); } + + const_reverse_iterator + crbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + const_reverse_iterator + crend() const noexcept + { return const_reverse_iterator(this->begin()); } + + // [string.view.capacity], capacity + + constexpr size_type + size() const noexcept + { return this->_M_len; } + + constexpr size_type + length() const noexcept + { return _M_len; } + + constexpr size_type + max_size() const noexcept + { + return (npos - sizeof(size_type) - sizeof(void*)) + / sizeof(value_type) / 4; + } + + constexpr bool + empty() const noexcept + { return this->_M_len == 0; } + + // [string.view.access], element access + + constexpr const _CharT& + operator[](size_type __pos) const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(__pos < this->_M_len); + return *(this->_M_str + __pos); + } + + constexpr const _CharT& + at(size_type __pos) const + { + return __pos < this->_M_len + ? *(this->_M_str + __pos) + : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __pos, this->size()), + *this->_M_str); + } + + constexpr const _CharT& + front() const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(this->_M_len > 0); + return *this->_M_str; + } + + constexpr const _CharT& + back() const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(this->_M_len > 0); + return *(this->_M_str + this->_M_len - 1); + } + + constexpr const _CharT* + data() const noexcept + { return this->_M_str; } + + // [string.view.modifiers], modifiers: + + constexpr void + remove_prefix(size_type __n) + { + __glibcxx_assert(this->_M_len >= __n); + this->_M_str += __n; + this->_M_len -= __n; + } + + constexpr void + remove_suffix(size_type __n) + { this->_M_len -= __n; } + + constexpr void + swap(basic_string_view& __sv) noexcept + { + auto __tmp = *this; + *this = __sv; + __sv = __tmp; + } + + + // [string.view.ops], string operations: + + template + explicit operator basic_string<_CharT, _Traits, _Allocator>() const + { + return { this->_M_str, this->_M_len }; + } + + template> + basic_string<_CharT, _Traits, _Allocator> + to_string(const _Allocator& __alloc = _Allocator()) const + { + return { this->_M_str, this->_M_len, __alloc }; + } + + size_type + copy(_CharT* __str, size_type __n, size_type __pos = 0) const + { + __glibcxx_requires_string_len(__str, __n); + if (__pos > this->_M_len) + __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()); + size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})}; + for (auto __begin = this->_M_str + __pos, + __end = __begin + __rlen; __begin != __end;) + *__str++ = *__begin++; + return __rlen; + } + + + // [string.view.ops], string operations: + + constexpr basic_string_view + substr(size_type __pos, size_type __n=npos) const + { + return __pos <= this->_M_len + ? basic_string_view{this->_M_str + __pos, + std::min(__n, size_type{this->_M_len - __pos})} + : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()), basic_string_view{}); + } + + constexpr int + compare(basic_string_view __str) const noexcept + { + int __ret = traits_type::compare(this->_M_str, __str._M_str, + std::min(this->_M_len, __str._M_len)); + if (__ret == 0) + __ret = _S_compare(this->_M_len, __str._M_len); + return __ret; + } + + constexpr int + compare(size_type __pos1, size_type __n1, basic_string_view __str) const + { return this->substr(__pos1, __n1).compare(__str); } + + constexpr int + compare(size_type __pos1, size_type __n1, + basic_string_view __str, size_type __pos2, size_type __n2) const + { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } + + constexpr int + compare(const _CharT* __str) const noexcept + { return this->compare(basic_string_view{__str}); } + + constexpr int + compare(size_type __pos1, size_type __n1, const _CharT* __str) const + { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } + + constexpr int + compare(size_type __pos1, size_type __n1, + const _CharT* __str, size_type __n2) const + { + return this->substr(__pos1, __n1) + .compare(basic_string_view(__str, __n2)); + } + + constexpr size_type + find(basic_string_view __str, size_type __pos = 0) const noexcept + { return this->find(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + find(_CharT __c, size_type __pos=0) const noexcept; + + constexpr size_type + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; + + constexpr size_type + find(const _CharT* __str, size_type __pos=0) const noexcept + { return this->find(__str, __pos, traits_type::length(__str)); } + + constexpr size_type + rfind(basic_string_view __str, size_type __pos = npos) const noexcept + { return this->rfind(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + rfind(_CharT __c, size_type __pos = npos) const noexcept; + + constexpr size_type + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; + + constexpr size_type + rfind(const _CharT* __str, size_type __pos = npos) const noexcept + { return this->rfind(__str, __pos, traits_type::length(__str)); } + + constexpr size_type + find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept + { return this->find_first_of(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + find_first_of(_CharT __c, size_type __pos = 0) const noexcept + { return this->find(__c, __pos); } + + constexpr size_type + find_first_of(const _CharT* __str, size_type __pos, size_type __n) const; + + constexpr size_type + find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept + { return this->find_first_of(__str, __pos, traits_type::length(__str)); } + + constexpr size_type + find_last_of(basic_string_view __str, + size_type __pos = npos) const noexcept + { return this->find_last_of(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + find_last_of(_CharT __c, size_type __pos=npos) const noexcept + { return this->rfind(__c, __pos); } + + constexpr size_type + find_last_of(const _CharT* __str, size_type __pos, size_type __n) const; + + constexpr size_type + find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept + { return this->find_last_of(__str, __pos, traits_type::length(__str)); } + + constexpr size_type + find_first_not_of(basic_string_view __str, + size_type __pos = 0) const noexcept + { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; + + constexpr size_type + find_first_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + constexpr size_type + find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept + { + return this->find_first_not_of(__str, __pos, + traits_type::length(__str)); + } + + constexpr size_type + find_last_not_of(basic_string_view __str, + size_type __pos = npos) const noexcept + { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } + + constexpr size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; + + constexpr size_type + find_last_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + constexpr size_type + find_last_not_of(const _CharT* __str, + size_type __pos = npos) const noexcept + { + return this->find_last_not_of(__str, __pos, + traits_type::length(__str)); + } + + private: + + static constexpr int + _S_compare(size_type __n1, size_type __n2) noexcept + { + return difference_type(__n1 - __n2) > std::numeric_limits::max() + ? std::numeric_limits::max() + : difference_type(__n1 - __n2) < std::numeric_limits::min() + ? std::numeric_limits::min() + : static_cast(difference_type(__n1 - __n2)); + } + + size_t _M_len; + const _CharT* _M_str; + }; + + // [string.view.comparison], non-member basic_string_view comparison functions + + namespace __detail + { + // Identity transform to create a non-deduced context, so that only one + // argument participates in template argument deduction and the other + // argument gets implicitly converted to the deduced type. See n3766.html. + template + using __idt = common_type_t<_Tp>; + } + + template + constexpr bool + operator==(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template + constexpr bool + operator==(basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template + constexpr bool + operator==(__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template + constexpr bool + operator!=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return !(__x == __y); } + + template + constexpr bool + operator!=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return !(__x == __y); } + + template + constexpr bool + operator!=(__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return !(__x == __y); } + + template + constexpr bool + operator< (basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) < 0; } + + template + constexpr bool + operator< (basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return __x.compare(__y) < 0; } + + template + constexpr bool + operator< (__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) < 0; } + + template + constexpr bool + operator> (basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) > 0; } + + template + constexpr bool + operator> (basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return __x.compare(__y) > 0; } + + template + constexpr bool + operator> (__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) > 0; } + + template + constexpr bool + operator<=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) <= 0; } + + template + constexpr bool + operator<=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return __x.compare(__y) <= 0; } + + template + constexpr bool + operator<=(__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) <= 0; } + + template + constexpr bool + operator>=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) >= 0; } + + template + constexpr bool + operator>=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt> __y) noexcept + { return __x.compare(__y) >= 0; } + + template + constexpr bool + operator>=(__detail::__idt> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) >= 0; } + + // [string.view.io], Inserters and extractors + template + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + basic_string_view<_CharT,_Traits> __str) + { return __ostream_insert(__os, __str.data(), __str.size()); } + + + // basic_string_view typedef names + + using string_view = basic_string_view; +#ifdef _GLIBCXX_USE_WCHAR_T + using wstring_view = basic_string_view; +#endif +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + using u16string_view = basic_string_view; + using u32string_view = basic_string_view; +#endif +} // namespace fundamentals_v1 +} // namespace experimental + + + // [string.view.hash], hash support: + template + struct hash; + + template<> + struct hash + : public __hash_base + { + size_t + operator()(const experimental::string_view& __str) const noexcept + { return std::_Hash_impl::hash(__str.data(), __str.length()); } + }; + + template<> + struct __is_fast_hash> : std::false_type + { }; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + struct hash + : public __hash_base + { + size_t + operator()(const experimental::wstring_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(wchar_t)); } + }; + + template<> + struct __is_fast_hash> : std::false_type + { }; +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template<> + struct hash + : public __hash_base + { + size_t + operator()(const experimental::u16string_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(char16_t)); } + }; + + template<> + struct __is_fast_hash> : std::false_type + { }; + + template<> + struct hash + : public __hash_base + { + size_t + operator()(const experimental::u32string_view& __s) const noexcept + { return std::_Hash_impl::hash(__s.data(), + __s.length() * sizeof(char32_t)); } + }; + + template<> + struct __is_fast_hash> : std::false_type + { }; +#endif + +namespace experimental +{ + // I added these EMSR. + inline namespace literals + { + inline namespace string_view_literals + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wliteral-suffix" + inline constexpr basic_string_view + operator""sv(const char* __str, size_t __len) noexcept + { return basic_string_view{__str, __len}; } + +#ifdef _GLIBCXX_USE_WCHAR_T + inline constexpr basic_string_view + operator""sv(const wchar_t* __str, size_t __len) noexcept + { return basic_string_view{__str, __len}; } +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + inline constexpr basic_string_view + operator""sv(const char16_t* __str, size_t __len) noexcept + { return basic_string_view{__str, __len}; } + + inline constexpr basic_string_view + operator""sv(const char32_t* __str, size_t __len) noexcept + { return basic_string_view{__str, __len}; } +#endif +#pragma GCC diagnostic pop + } // namespace string_literals + } // namespace literals +} // namespace experimental + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#include + +#endif // __cplusplus <= 201103L + +#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW diff --git a/gdb/common/gdb_string_view.tcc b/gdb/common/gdb_string_view.tcc new file mode 100644 index 00000000000..579ececd8d8 --- /dev/null +++ b/gdb/common/gdb_string_view.tcc @@ -0,0 +1,231 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + +// Copyright (C) 2013-2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file experimental/bits/string_view.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{experimental/string_view} + */ + +// +// N3762 basic_string_view library +// + +#ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC +#define _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC 1 + +#pragma GCC system_header + +#if __cplusplus >= 201402L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace experimental +{ +inline namespace fundamentals_v1 +{ + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept + { + __glibcxx_requires_string_len(__str, __n); + + if (__n == 0) + return __pos <= this->_M_len ? __pos : npos; + + if (__n <= this->_M_len) + { + for (; __pos <= this->_M_len - __n; ++__pos) + if (traits_type::eq(this->_M_str[__pos], __str[0]) + && traits_type::compare(this->_M_str + __pos + 1, + __str + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find(_CharT __c, size_type __pos) const noexcept + { + size_type __ret = npos; + if (__pos < this->_M_len) + { + const size_type __n = this->_M_len - __pos; + const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c); + if (__p) + __ret = __p - this->_M_str; + } + return __ret; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept + { + __glibcxx_requires_string_len(__str, __n); + + if (__n <= this->_M_len) + { + __pos = std::min(size_type(this->_M_len - __n), __pos); + do + { + if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + rfind(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size > 0) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_of(const _CharT* __str, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__str, __n); + for (; __n && __pos < this->_M_len; ++__pos) + { + const _CharT* __p = traits_type::find(__str, __n, + this->_M_str[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_of(const _CharT* __str, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__str, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__str, __n); + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::find(__str, __n, this->_M_str[__pos])) + return __pos; + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_not_of(_CharT __c, size_type __pos) const noexcept + { + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::eq(this->_M_str[__pos], __c)) + return __pos; + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__str, __n); + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template + constexpr typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_not_of(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } +} // namespace fundamentals_v1 +} // namespace experimental + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // __cplusplus <= 201103L + +#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW_TCC -- 2.30.2