| // Components for manipulating non-owning sequences of characters -*- C++ -*- | 
 |  | 
 |  | 
 | #ifndef COMMON_GDB_STRING_VIEW_H | 
 | #define COMMON_GDB_STRING_VIEW_H | 
 |  | 
 | // Note: This file has been stolen from the gcc repo | 
 | // (libstdc++-v3/include/experimental/string_view) and has local modifications. | 
 |  | 
 | // Copyright (C) 2013-2020 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 | 
 | // <http://www.gnu.org/licenses/>. | 
 |  | 
 | // | 
 | // N3762 basic_string_view library | 
 | // | 
 |  | 
 |  | 
 | #if __cplusplus >= 201703L | 
 |  | 
 | #include <string_view> | 
 |  | 
 | namespace gdb { | 
 |   using string_view = std::string_view; | 
 | } /* namespace gdb */ | 
 |  | 
 | #else /* __cplusplus < 201703L */ | 
 |  | 
 | #include <string> | 
 | #include <limits> | 
 | #include "gdb_assert.h" | 
 |  | 
 | namespace gdb { | 
 |  | 
 |   /** | 
 |    *  @class basic_string_view <experimental/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<typename _CharT, typename _Traits = std::char_traits<_CharT>> | 
 |     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<const_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<typename _Allocator> | 
 |         basic_string_view(const std::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) | 
 | 	     : (error (_("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) | 
 |       { | 
 | 	gdb_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<typename _Allocator> | 
 |         explicit operator std::basic_string<_CharT, _Traits, _Allocator>() const | 
 |         { | 
 | 	  return { this->_M_str, this->_M_len }; | 
 | 	} | 
 |  | 
 |       template<typename _Allocator = std::allocator<_CharT>> | 
 | 	std::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 | 
 |       { | 
 | 	gdb_assert (__str != nullptr || __n == 0); | 
 | 	if (__pos > this->_M_len) | 
 | 	  error (_("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})} | 
 | 	     : (error (_("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); } | 
 |  | 
 |       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<int>::max() | 
 | 	     ? std::numeric_limits<int>::max() | 
 | 	     : difference_type(__n1 - __n2) < std::numeric_limits<int>::min() | 
 | 	     ? std::numeric_limits<int>::min() | 
 | 	     : static_cast<int>(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<typename _Tp> | 
 |       using __idt = typename std::common_type<_Tp>::type; | 
 |   } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*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<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator==(basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return __x.size() == __y.size() && __x.compare(__y) == 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.size() == __y.size() && __x.compare(__y) == 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator!=(basic_string_view<_CharT, _Traits> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return !(__x == __y); } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator!=(basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return !(__x == __y); } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return !(__x == __y); } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator< (basic_string_view<_CharT, _Traits> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) < 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator< (basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return __x.compare(__y) < 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) < 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator> (basic_string_view<_CharT, _Traits> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) > 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator> (basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return __x.compare(__y) > 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) > 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator<=(basic_string_view<_CharT, _Traits> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) <= 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator<=(basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return __x.compare(__y) <= 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) <= 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator>=(basic_string_view<_CharT, _Traits> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) >= 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator>=(basic_string_view<_CharT, _Traits> __x, | 
 |                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | 
 |     { return __x.compare(__y) >= 0; } | 
 |  | 
 |   template<typename _CharT, typename _Traits> | 
 |     /*constexpr*/ bool | 
 |     operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, | 
 |                basic_string_view<_CharT, _Traits> __y) noexcept | 
 |     { return __x.compare(__y) >= 0; } | 
 |  | 
 |   // basic_string_view typedef names | 
 |  | 
 |   using string_view = basic_string_view<char>; | 
 | } /* namespace gdb */ | 
 |  | 
 | #include "gdb_string_view.tcc" | 
 |  | 
 | #endif // __cplusplus < 201703L | 
 |  | 
 | #endif /* COMMON_GDB_STRING_VIEW_H */ |