// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A string-like object that points to a sized piece of memory.
//
// You can use StringPiece as a function or method parameter.  A StringPiece
// parameter can receive a double-quoted string literal argument, a "const
// char*" argument, a string argument, or a StringPiece argument with no data
// copying.  Systematic use of StringPiece for arguments reduces data
// copies and strlen() calls.
//
// Prefer passing StringPieces by value:
//   void MyFunction(StringPiece arg);
// If circumstances require, you may also pass by const reference:
//   void MyFunction(const StringPiece& arg);  // not preferred
// Both of these have the same lifetime semantics.  Passing by value
// generates slightly smaller code.  For more discussion, Googlers can see
// the thread go/stringpiecebyvalue on c-users.

#ifndef BASE_STRINGS_STRING_PIECE_H_
#define BASE_STRINGS_STRING_PIECE_H_

#include <stddef.h>

#include <algorithm>
#include <iosfwd>
#include <limits>
#include <string>
#include <type_traits>

#include "polyfills/base/base_export.h"
#include "polyfills/base/check.h"
#include "polyfills/base/check_op.h"
#include "base/compiler_specific.h"
#include "base/strings/string_piece_forward.h"
#include "build/build_config.h"

namespace gurl_base {

// internal --------------------------------------------------------------------

// Many of the StringPiece functions use different implementations for the
// 8-bit and 16-bit versions, and we don't want lots of template expansions in
// this (very common) header that will slow down compilation.
//
// So here we define overloaded functions called by the StringPiece template.
// For those that share an implementation, the two versions will expand to a
// template internal to the .cc file.
namespace internal {

BASE_EXPORT size_t find(StringPiece self, StringPiece s, size_t pos);
BASE_EXPORT size_t find(StringPiece16 self, StringPiece16 s, size_t pos);

BASE_EXPORT size_t rfind(StringPiece self, StringPiece s, size_t pos);
BASE_EXPORT size_t rfind(StringPiece16 self, StringPiece16 s, size_t pos);

BASE_EXPORT size_t find_first_of(StringPiece self, StringPiece s, size_t pos);
BASE_EXPORT size_t find_first_of(StringPiece16 self,
                                 StringPiece16 s,
                                 size_t pos);

BASE_EXPORT size_t find_first_not_of(StringPiece self,
                                     StringPiece s,
                                     size_t pos);
BASE_EXPORT size_t find_first_not_of(StringPiece16 self,
                                     StringPiece16 s,
                                     size_t pos);

BASE_EXPORT size_t find_last_of(StringPiece self, StringPiece s, size_t pos);
BASE_EXPORT size_t find_last_of(StringPiece16 self,
                                StringPiece16 s,
                                size_t pos);

BASE_EXPORT size_t find_last_not_of(StringPiece self,
                                    StringPiece s,
                                    size_t pos);
BASE_EXPORT size_t find_last_not_of(StringPiece16 self,
                                    StringPiece16 s,
                                    size_t pos);

BASE_EXPORT size_t find(WStringPiece self, WStringPiece s, size_t pos);
BASE_EXPORT size_t rfind(WStringPiece self, WStringPiece s, size_t pos);
BASE_EXPORT size_t find_first_of(WStringPiece self, WStringPiece s, size_t pos);
BASE_EXPORT size_t find_first_not_of(WStringPiece self,
                                     WStringPiece s,
                                     size_t pos);
BASE_EXPORT size_t find_last_of(WStringPiece self, WStringPiece s, size_t pos);
BASE_EXPORT size_t find_last_not_of(WStringPiece self,
                                    WStringPiece s,
                                    size_t pos);

}  // namespace internal

// BasicStringPiece ------------------------------------------------------------

// Mirrors the C++17 version of std::basic_string_view<> as closely as possible,
// except where noted below.
template <typename CharT, typename Traits>
class GSL_POINTER BasicStringPiece {
 public:
  using traits_type = Traits;
  using value_type = CharT;
  using pointer = CharT*;
  using const_pointer = const CharT*;
  using reference = 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;

  constexpr BasicStringPiece() noexcept : ptr_(nullptr), length_(0) {}
  constexpr BasicStringPiece(const BasicStringPiece& other) noexcept = default;
  constexpr BasicStringPiece& operator=(const BasicStringPiece& view) noexcept =
      default;
  constexpr BasicStringPiece(const CharT* s, size_type count)
      : ptr_(s), length_(count) {}
  constexpr BasicStringPiece(const CharT* s)
      : ptr_(s), length_(s ? traits_type::length(s) : 0) {
    // Intentional STL deviation: Null-check instead of UB.
    GURL_CHECK(s);
  }
  // Explicitly disallow construction from nullptr. Note that this does not
  // catch construction from runtime strings that might be null.
  // Note: The following is just a more elaborate way of spelling
  // `BasicStringPiece(nullptr_t) = delete`, but unfortunately the terse form is
  // not supported by the PNaCl toolchain.
  template <class T, class = std::enable_if_t<std::is_null_pointer<T>::value>>
  BasicStringPiece(T) {
    static_assert(sizeof(T) == 0,  // Always false.
                  "StringPiece does not support construction from nullptr, use "
                  "the default constructor instead.");
  }

  // These are necessary because std::basic_string provides construction from
  // (an object convertible to) a std::basic_string_view, as well as an explicit
  // cast operator to a std::basic_string_view, but (obviously) not from/to a
  // BasicStringPiece.
  BasicStringPiece(const std::basic_string<CharT>& str)
      : ptr_(str.data()), length_(str.size()) {}
  explicit operator std::basic_string<CharT>() const {
    return std::basic_string<CharT>(data(), size());
  }

  constexpr const_iterator begin() const noexcept { return ptr_; }
  constexpr const_iterator cbegin() const noexcept { return ptr_; }
  constexpr const_iterator end() const noexcept { return ptr_ + length_; }
  constexpr const_iterator cend() const noexcept { return ptr_ + length_; }
  constexpr const_reverse_iterator rbegin() const noexcept {
    return const_reverse_iterator(ptr_ + length_);
  }
  constexpr const_reverse_iterator crbegin() const noexcept {
    return const_reverse_iterator(ptr_ + length_);
  }
  constexpr const_reverse_iterator rend() const noexcept {
    return const_reverse_iterator(ptr_);
  }
  constexpr const_reverse_iterator crend() const noexcept {
    return const_reverse_iterator(ptr_);
  }

  constexpr const_reference operator[](size_type pos) const {
    // Intentional STL deviation: Bounds-check instead of UB.
    return at(pos);
  }
  constexpr const_reference at(size_type pos) const {
    GURL_CHECK_LT(pos, size());
    return data()[pos];
  }

  constexpr const_reference front() const { return operator[](0); }

  constexpr const_reference back() const { return operator[](size() - 1); }

  constexpr const_pointer data() const noexcept { return ptr_; }

  constexpr size_type size() const noexcept { return length_; }
  constexpr size_type length() const noexcept { return length_; }

  constexpr size_type max_size() const {
    return std::numeric_limits<size_type>::max() / sizeof(CharT);
  }

  [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }

  constexpr void remove_prefix(size_type n) {
    // Intentional STL deviation: Bounds-check instead of UB.
    GURL_CHECK_LE(n, size());
    ptr_ += n;
    length_ -= n;
  }

  constexpr void remove_suffix(size_type n) {
    // Intentional STL deviation: Bounds-check instead of UB.
    GURL_CHECK_LE(n, size());
    length_ -= n;
  }

  constexpr void swap(BasicStringPiece& v) noexcept {
    // Note: Cannot use std::swap() since it is not constexpr until C++20.
    const const_pointer ptr = ptr_;
    ptr_ = v.ptr_;
    v.ptr_ = ptr;
    const size_type length = length_;
    length_ = v.length_;
    v.length_ = length;
  }

  constexpr size_type copy(CharT* dest,
                           size_type count,
                           size_type pos = 0) const {
    GURL_CHECK_LE(pos, size());
    const size_type rcount = std::min(count, size() - pos);
    traits_type::copy(dest, data() + pos, rcount);
    return rcount;
  }

  constexpr BasicStringPiece substr(size_type pos = 0,
                                    size_type count = npos) const {
    GURL_CHECK_LE(pos, size());
    const size_type rcount = std::min(count, size() - pos);
    return {data() + pos, rcount};
  }

  constexpr int compare(BasicStringPiece v) const noexcept {
    const size_type rlen = std::min(size(), v.size());
    const int result = traits_type::compare(data(), v.data(), rlen);
    if (result != 0)
      return result;
    if (size() == v.size())
      return 0;
    return size() < v.size() ? -1 : 1;
  }
  constexpr int compare(size_type pos1,
                        size_type count1,
                        BasicStringPiece v) const {
    return substr(pos1, count1).compare(v);
  }
  constexpr int compare(size_type pos1,
                        size_type count1,
                        BasicStringPiece v,
                        size_type pos2,
                        size_type count2) const {
    return substr(pos1, count1).compare(v.substr(pos2, count2));
  }
  constexpr int compare(const CharT* s) const {
    return compare(BasicStringPiece(s));
  }
  constexpr int compare(size_type pos1,
                        size_type count1,
                        const CharT* s) const {
    return substr(pos1, count1).compare(BasicStringPiece(s));
  }
  constexpr int compare(size_type pos1,
                        size_type count1,
                        const CharT* s,
                        size_type count2) const {
    return substr(pos1, count1).compare(BasicStringPiece(s, count2));
  }

  constexpr size_type find(BasicStringPiece v,
                           size_type pos = 0) const noexcept {
    if (is_constant_evaluated()) {
      if (v.size() > size())
        return npos;
      for (size_type p = pos; p <= size() - v.size(); ++p) {
        if (!compare(p, v.size(), v))
          return p;
      }
      return npos;
    }

    return internal::find(*this, v, pos);
  }
  constexpr size_type find(CharT ch, size_type pos = 0) const noexcept {
    if (pos >= size())
      return npos;

    const const_pointer result =
        traits_type::find(data() + pos, size() - pos, ch);
    return result ? static_cast<size_type>(result - data()) : npos;
  }
  constexpr size_type find(const CharT* s,
                           size_type pos,
                           size_type count) const {
    return find(BasicStringPiece(s, count), pos);
  }
  constexpr size_type find(const CharT* s, size_type pos = 0) const {
    return find(BasicStringPiece(s), pos);
  }

  constexpr size_type rfind(BasicStringPiece v,
                            size_type pos = npos) const noexcept {
    if (is_constant_evaluated()) {
      if (v.size() > size())
        return npos;
      for (size_type p = std::min(size() - v.size(), pos);; --p) {
        if (!compare(p, v.size(), v))
          return p;
        if (!p)
          break;
      }
      return npos;
    }

    return internal::rfind(*this, v, pos);
  }
  constexpr size_type rfind(CharT c, size_type pos = npos) const noexcept {
    if (empty())
      return npos;

    for (size_t i = std::min(pos, size() - 1);; --i) {
      if (data()[i] == c)
        return i;

      if (i == 0)
        break;
    }
    return npos;
  }
  constexpr size_type rfind(const CharT* s,
                            size_type pos,
                            size_type count) const {
    return rfind(BasicStringPiece(s, count), pos);
  }
  constexpr size_type rfind(const CharT* s, size_type pos = npos) const {
    return rfind(BasicStringPiece(s), pos);
  }

  constexpr size_type find_first_of(BasicStringPiece v,
                                    size_type pos = 0) const noexcept {
    if (is_constant_evaluated()) {
      if (empty() || v.empty())
        return npos;
      for (size_type p = pos; p < size(); ++p) {
        if (v.find(data()[p]) != npos)
          return p;
      }
      return npos;
    }

    return internal::find_first_of(*this, v, pos);
  }
  constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept {
    return find(c, pos);
  }
  constexpr size_type find_first_of(const CharT* s,
                                    size_type pos,
                                    size_type count) const {
    return find_first_of(BasicStringPiece(s, count), pos);
  }
  constexpr size_type find_first_of(const CharT* s, size_type pos = 0) const {
    return find_first_of(BasicStringPiece(s), pos);
  }

  constexpr size_type find_last_of(BasicStringPiece v,
                                   size_type pos = npos) const noexcept {
    if (is_constant_evaluated()) {
      if (empty() || v.empty())
        return npos;
      for (size_type p = std::min(pos, size() - 1);; --p) {
        if (v.find(data()[p]) != npos)
          return p;
        if (!p)
          break;
      }
      return npos;
    }

    return internal::find_last_of(*this, v, pos);
  }
  constexpr size_type find_last_of(CharT c,
                                   size_type pos = npos) const noexcept {
    return rfind(c, pos);
  }
  constexpr size_type find_last_of(const CharT* s,
                                   size_type pos,
                                   size_type count) const {
    return find_last_of(BasicStringPiece(s, count), pos);
  }
  constexpr size_type find_last_of(const CharT* s, size_type pos = npos) const {
    return find_last_of(BasicStringPiece(s), pos);
  }

  constexpr size_type find_first_not_of(BasicStringPiece v,
                                        size_type pos = 0) const noexcept {
    if (is_constant_evaluated()) {
      if (empty())
        return npos;
      for (size_type p = pos; p < size(); ++p) {
        if (v.find(data()[p]) == npos)
          return p;
      }
      return npos;
    }

    return internal::find_first_not_of(*this, v, pos);
  }
  constexpr size_type find_first_not_of(CharT c,
                                        size_type pos = 0) const noexcept {
    if (empty())
      return npos;

    for (; pos < size(); ++pos) {
      if (data()[pos] != c)
        return pos;
    }
    return npos;
  }
  constexpr size_type find_first_not_of(const CharT* s,
                                        size_type pos,
                                        size_type count) const {
    return find_first_not_of(BasicStringPiece(s, count), pos);
  }
  constexpr size_type find_first_not_of(const CharT* s,
                                        size_type pos = 0) const {
    return find_first_not_of(BasicStringPiece(s), pos);
  }

  constexpr size_type find_last_not_of(BasicStringPiece v,
                                       size_type pos = npos) const noexcept {
    if (is_constant_evaluated()) {
      if (empty())
        return npos;
      for (size_type p = std::min(pos, size() - 1);; --p) {
        if (v.find(data()[p]) == npos)
          return p;
        if (!p)
          break;
      }
      return npos;
    }

    return internal::find_last_not_of(*this, v, pos);
  }
  constexpr size_type find_last_not_of(CharT c,
                                       size_type pos = npos) const noexcept {
    if (empty())
      return npos;

    for (size_t i = std::min(pos, size() - 1);; --i) {
      if (data()[i] != c)
        return i;
      if (i == 0)
        break;
    }
    return npos;
  }
  constexpr size_type find_last_not_of(const CharT* s,
                                       size_type pos,
                                       size_type count) const {
    return find_last_not_of(BasicStringPiece(s, count), pos);
  }
  constexpr size_type find_last_not_of(const CharT* s,
                                       size_type pos = npos) const {
    return find_last_not_of(BasicStringPiece(s), pos);
  }

  static constexpr size_type npos = size_type(-1);

 protected:
  const_pointer ptr_;
  size_type length_;
};

// static
template <typename CharT, typename Traits>
const typename BasicStringPiece<CharT, Traits>::size_type
    BasicStringPiece<CharT, Traits>::npos;

// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
extern template class BASE_EXPORT BasicStringPiece<char>;
extern template class BASE_EXPORT BasicStringPiece<char16_t>;
#endif

template <typename CharT, typename Traits>
constexpr bool operator==(BasicStringPiece<CharT, Traits> lhs,
                          BasicStringPiece<CharT, Traits> rhs) noexcept {
  return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}
// Here and below we make use of std::common_type_t to emulate
// std::type_identity (part of C++20). This creates a non-deduced context, so
// that we can compare StringPieces with types that implicitly convert to
// StringPieces. See https://wg21.link/n3766 for details.
// Furthermore, we require dummy template parameters for these overloads to work
// around a name mangling issue on Windows.
template <typename CharT, typename Traits, int = 1>
constexpr bool operator==(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}
template <typename CharT, typename Traits, int = 2>
constexpr bool operator==(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}

template <typename CharT, typename Traits>
constexpr bool operator!=(BasicStringPiece<CharT, Traits> lhs,
                          BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(lhs == rhs);
}
template <typename CharT, typename Traits, int = 1>
constexpr bool operator!=(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return !(lhs == rhs);
}
template <typename CharT, typename Traits, int = 2>
constexpr bool operator!=(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(lhs == rhs);
}

template <typename CharT, typename Traits>
constexpr bool operator<(BasicStringPiece<CharT, Traits> lhs,
                         BasicStringPiece<CharT, Traits> rhs) noexcept {
  return lhs.compare(rhs) < 0;
}
template <typename CharT, typename Traits, int = 1>
constexpr bool operator<(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return lhs.compare(rhs) < 0;
}

template <typename CharT, typename Traits, int = 2>
constexpr bool operator<(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return lhs.compare(rhs) < 0;
}

template <typename CharT, typename Traits>
constexpr bool operator>(BasicStringPiece<CharT, Traits> lhs,
                         BasicStringPiece<CharT, Traits> rhs) noexcept {
  return rhs < lhs;
}
template <typename CharT, typename Traits, int = 1>
constexpr bool operator>(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return rhs < lhs;
}
template <typename CharT, typename Traits, int = 2>
constexpr bool operator>(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return rhs < lhs;
}

template <typename CharT, typename Traits>
constexpr bool operator<=(BasicStringPiece<CharT, Traits> lhs,
                          BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(rhs < lhs);
}
template <typename CharT, typename Traits, int = 1>
constexpr bool operator<=(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return !(rhs < lhs);
}
template <typename CharT, typename Traits, int = 2>
constexpr bool operator<=(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(rhs < lhs);
}

template <typename CharT, typename Traits>
constexpr bool operator>=(BasicStringPiece<CharT, Traits> lhs,
                          BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(lhs < rhs);
}
template <typename CharT, typename Traits, int = 1>
constexpr bool operator>=(
    BasicStringPiece<CharT, Traits> lhs,
    std::common_type_t<BasicStringPiece<CharT, Traits>> rhs) noexcept {
  return !(lhs < rhs);
}
template <typename CharT, typename Traits, int = 2>
constexpr bool operator>=(
    std::common_type_t<BasicStringPiece<CharT, Traits>> lhs,
    BasicStringPiece<CharT, Traits> rhs) noexcept {
  return !(lhs < rhs);
}

BASE_EXPORT std::ostream& operator<<(std::ostream& o, StringPiece piece);
// Not in the STL: convenience functions to output non-UTF-8 strings to an
// 8-bit-width stream.
BASE_EXPORT std::ostream& operator<<(std::ostream& o, StringPiece16 piece);
BASE_EXPORT std::ostream& operator<<(std::ostream& o, WStringPiece piece);

// Intentionally omitted (since Chromium does not use character literals):
// operator""sv.

// Stand-ins for the STL's std::hash<> specializations.
template <typename StringPieceType>
struct StringPieceHashImpl {
  // This is a custom hash function. We don't use the ones already defined for
  // string and std::u16string directly because it would require the string
  // constructors to be called, which we don't want.
  size_t operator()(StringPieceType sp) const {
    size_t result = 0;
    for (auto c : sp)
      result = (result * 131) + static_cast<size_t>(c);
    return result;
  }
};
using StringPieceHash = StringPieceHashImpl<StringPiece>;
using StringPiece16Hash = StringPieceHashImpl<StringPiece16>;
using WStringPieceHash = StringPieceHashImpl<WStringPiece>;

}  // namespace base

#endif  // BASE_STRINGS_STRING_PIECE_H_
