// Components for manipulating non-owning sequences of characters -*- C++ -*-

// Note: This file has been stolen from the gcc repo
// (libstdc++-v3/include/experimental/bits/string_view.tcc) and has local
// modifications.

// Copyright (C) 2013-2021 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/>.

/** @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 GDB_STRING_VIEW_TCC
#define GDB_STRING_VIEW_TCC 1

namespace gdb
{
  template<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);

      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<typename _CharT, typename _Traits>
    /*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<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);

      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<typename _CharT, typename _Traits>
    /*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<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);
      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<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);
      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<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);
      for (; __pos < this->_M_len; ++__pos)
	if (!traits_type::find(__str, __n, this->_M_str[__pos]))
	  return __pos;
      return npos;
    }

  template<typename _CharT, typename _Traits>
    /*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<typename _CharT, typename _Traits>
    /*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
    {
      gdb_assert (__str != nullptr || __n == 0);
      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<typename _CharT, typename _Traits>
    /*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 gdb

#endif // GDB_STRING_VIEW_TCC
