15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copied from strings/stringpiece.cc with modifications
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// For each character in characters_wanted, sets the index corresponding
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// to the ASCII code of that character to 1 in table.  This is used by
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the find_.*_of methods below to tell whether or not a character is in
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the lookup table in constant time.
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The argument `table' must be an array that is large enough to hold all
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the possible values of an unsigned char.  Thus it should be be declared
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// as follows:
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//   bool table[UCHAR_MAX + 1]
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)inline void BuildLookupTable(const StringPiece& characters_wanted,
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             bool* table) {
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t length = characters_wanted.length();
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const char* const data = characters_wanted.data();
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < length; ++i) {
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    table[static_cast<unsigned char>(data[i])] = true;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC doesn't like complex extern templates and DLLs.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(COMPILER_MSVC)
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template class BasicStringPiece<std::string>;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template class BasicStringPiece<string16>;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool operator==(const StringPiece& x, const StringPiece& y) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (x.size() != y.size())
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return o;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) {
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (self.empty())
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    target->clear();
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    target->assign(self.data(), self.size());
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyToString(const StringPiece& self, std::string* target) {
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CopyToStringT(self, target);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CopyToString(const StringPiece16& self, string16* target) {
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CopyToStringT(self, target);
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AppendToStringT(const BasicStringPiece<STR>& self, STR* target) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!self.empty())
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target->append(self.data(), self.size());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AppendToString(const StringPiece& self, std::string* target) {
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AppendToStringT(self, target);
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AppendToString(const StringPiece16& self, string16* target) {
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AppendToStringT(self, target);
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t copyT(const BasicStringPiece<STR>& self,
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             typename STR::value_type* buf,
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             size_t n,
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             size_t pos) {
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t ret = std::min(self.size() - pos, n);
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) {
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return copyT(self, buf, n, pos);
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return copyT(self, buf, n, pos);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t findT(const BasicStringPiece<STR>& self,
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             const BasicStringPiece<STR>& s,
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             size_t pos) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos > self.size())
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typename BasicStringPiece<STR>::const_iterator result =
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::search(self.begin() + pos, self.end(), s.begin(), s.end());
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const size_t xpos =
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static_cast<size_t>(result - self.begin());
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos;
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find(const StringPiece& self, const StringPiece& s, size_t pos) {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return findT(self, s, pos);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos) {
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return findT(self, s, pos);
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t findT(const BasicStringPiece<STR>& self,
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             typename STR::value_type c,
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             size_t pos) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos >= self.size())
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typename BasicStringPiece<STR>::const_iterator result =
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find(self.begin() + pos, self.end(), c);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result != self.end() ?
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find(const StringPiece& self, char c, size_t pos) {
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return findT(self, c, pos);
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find(const StringPiece16& self, char16 c, size_t pos) {
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return findT(self, c, pos);
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfindT(const BasicStringPiece<STR>& self,
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              const BasicStringPiece<STR>& s,
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              size_t pos) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() < s.size())
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.empty())
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::min(self.size(), pos);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typename BasicStringPiece<STR>::const_iterator last =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.begin() + std::min(self.size() - s.size(), pos) + s.size();
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typename BasicStringPiece<STR>::const_iterator result =
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find_end(self.begin(), last, s.begin(), s.end());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result != last ?
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) {
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return rfindT(self, s, pos);
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos) {
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return rfindT(self, s, pos);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfindT(const BasicStringPiece<STR>& self,
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              typename STR::value_type c,
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              size_t pos) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = std::min(pos, self.size() - 1); ;
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       --i) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (self.data()[i] == c)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i == 0)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return BasicStringPiece<STR>::npos;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfind(const StringPiece& self, char c, size_t pos) {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return rfindT(self, c, pos);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t rfind(const StringPiece16& self, char16 c, size_t pos) {
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return rfindT(self, c, pos);
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 8-bit version using lookup table.
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_of(const StringPiece& self,
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const StringPiece& s,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     size_t pos) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0 || s.size() == 0)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringPiece::npos;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid the cost of BuildLookupTable() for a single-character search.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 1)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return find(self, s.data()[0], pos);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool lookup[UCHAR_MAX + 1] = { false };
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildLookupTable(s, lookup);
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = pos; i < self.size(); ++i) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lookup[static_cast<unsigned char>(self.data()[i])]) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StringPiece::npos;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 16-bit brute force version.
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_of(const StringPiece16& self,
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const StringPiece16& s,
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     size_t pos) {
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StringPiece16::const_iterator found =
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end());
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (found == self.end())
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return StringPiece16::npos;
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return found - self.begin();
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 8-bit version using lookup table.
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_not_of(const StringPiece& self,
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         const StringPiece& s,
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         size_t pos) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringPiece::npos;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 0)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid the cost of BuildLookupTable() for a single-character search.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 1)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return find_first_not_of(self, s.data()[0], pos);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool lookup[UCHAR_MAX + 1] = { false };
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildLookupTable(s, lookup);
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = pos; i < self.size(); ++i) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!lookup[static_cast<unsigned char>(self.data()[i])]) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StringPiece::npos;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 16-bit brute-force version.
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     const StringPiece16& s,
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     size_t pos) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0)
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return StringPiece16::npos;
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t self_i = pos; self_i < self.size(); ++self_i) {
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool found = false;
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (size_t s_i = 0; s_i < s.size(); ++s_i) {
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (self[self_i] == s[s_i]) {
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        found = true;
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        break;
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!found)
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return self_i;
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return StringPiece16::npos;
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_not_ofT(const BasicStringPiece<STR>& self,
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                          typename STR::value_type c,
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                          size_t pos) {
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (self.size() == 0)
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; pos < self.size(); ++pos) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (self.data()[pos] != c) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return pos;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return BasicStringPiece<STR>::npos;
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_not_of(const StringPiece& self,
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         char c,
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         size_t pos) {
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return find_first_not_ofT(self, c, pos);
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_first_not_of(const StringPiece16& self,
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         char16 c,
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         size_t pos) {
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return find_first_not_ofT(self, c, pos);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 8-bit version using lookup table.
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0 || s.size() == 0)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringPiece::npos;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid the cost of BuildLookupTable() for a single-character search.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 1)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rfind(self, s.data()[0], pos);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool lookup[UCHAR_MAX + 1] = { false };
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildLookupTable(s, lookup);
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lookup[static_cast<unsigned char>(self.data()[i])])
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i == 0)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StringPiece::npos;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 16-bit brute-force version.
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_of(const StringPiece16& self,
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    const StringPiece16& s,
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    size_t pos) {
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (self.size() == 0)
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return StringPiece16::npos;
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t self_i = std::min(pos, self.size() - 1); ;
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       --self_i) {
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (size_t s_i = 0; s_i < s.size(); s_i++) {
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (self.data()[self_i] == s[s_i])
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        return self_i;
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (self_i == 0)
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return StringPiece16::npos;
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 8-bit version using lookup table.
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_not_of(const StringPiece& self,
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        const StringPiece& s,
341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        size_t pos) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringPiece::npos;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t i = std::min(pos, self.size() - 1);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 0)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid the cost of BuildLookupTable() for a single-character search.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.size() == 1)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return find_last_not_of(self, s.data()[0], pos);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool lookup[UCHAR_MAX + 1] = { false };
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildLookupTable(s, lookup);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; ; --i) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!lookup[static_cast<unsigned char>(self.data()[i])])
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i == 0)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return StringPiece::npos;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 16-bit brute-force version.
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_not_of(const StringPiece16& self,
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        const StringPiece16& s,
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        size_t pos) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (self.size() == 0)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringPiece::npos;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) {
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool found = false;
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (size_t s_i = 0; s_i < s.size(); s_i++) {
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (self.data()[self_i] == s[s_i]) {
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        found = true;
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        break;
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!found)
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return self_i;
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (self_i == 0)
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return StringPiece16::npos;
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_not_ofT(const BasicStringPiece<STR>& self,
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         typename STR::value_type c,
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         size_t pos) {
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (self.size() == 0)
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return BasicStringPiece<STR>::npos;
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (self.data()[i] != c)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i == 0)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return BasicStringPiece<STR>::npos;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_not_of(const StringPiece& self,
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        char c,
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        size_t pos) {
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return find_last_not_ofT(self, c, pos);
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t find_last_not_of(const StringPiece16& self,
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        char16 c,
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        size_t pos) {
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return find_last_not_ofT(self, c, pos);
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template<typename STR>
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self,
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              size_t pos,
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              size_t n) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos > self.size()) pos = self.size();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (n > self.size() - pos) n = self.size() - pos;
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return BasicStringPiece<STR>(self.data() + pos, n);
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)StringPiece substr(const StringPiece& self,
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   size_t pos,
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   size_t n) {
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return substrT(self, pos, n);
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)StringPiece16 substr(const StringPiece16& self,
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     size_t pos,
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     size_t n) {
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return substrT(self, pos, n);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
438