xref: /aosp_15_r20/external/libchrome/base/strings/string_piece.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker // Copied from strings/stringpiece.h with modifications
5*635a8641SAndroid Build Coastguard Worker //
6*635a8641SAndroid Build Coastguard Worker // A string-like object that points to a sized piece of memory.
7*635a8641SAndroid Build Coastguard Worker //
8*635a8641SAndroid Build Coastguard Worker // You can use StringPiece as a function or method parameter.  A StringPiece
9*635a8641SAndroid Build Coastguard Worker // parameter can receive a double-quoted string literal argument, a "const
10*635a8641SAndroid Build Coastguard Worker // char*" argument, a string argument, or a StringPiece argument with no data
11*635a8641SAndroid Build Coastguard Worker // copying.  Systematic use of StringPiece for arguments reduces data
12*635a8641SAndroid Build Coastguard Worker // copies and strlen() calls.
13*635a8641SAndroid Build Coastguard Worker //
14*635a8641SAndroid Build Coastguard Worker // Prefer passing StringPieces by value:
15*635a8641SAndroid Build Coastguard Worker //   void MyFunction(StringPiece arg);
16*635a8641SAndroid Build Coastguard Worker // If circumstances require, you may also pass by const reference:
17*635a8641SAndroid Build Coastguard Worker //   void MyFunction(const StringPiece& arg);  // not preferred
18*635a8641SAndroid Build Coastguard Worker // Both of these have the same lifetime semantics.  Passing by value
19*635a8641SAndroid Build Coastguard Worker // generates slightly smaller code.  For more discussion, Googlers can see
20*635a8641SAndroid Build Coastguard Worker // the thread go/stringpiecebyvalue on c-users.
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker #ifndef BASE_STRINGS_STRING_PIECE_H_
23*635a8641SAndroid Build Coastguard Worker #define BASE_STRINGS_STRING_PIECE_H_
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker #include <iosfwd>
28*635a8641SAndroid Build Coastguard Worker #include <string>
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/strings/char_traits.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/strings/string16.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece_forward.h"
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker namespace base {
37*635a8641SAndroid Build Coastguard Worker 
38*635a8641SAndroid Build Coastguard Worker // internal --------------------------------------------------------------------
39*635a8641SAndroid Build Coastguard Worker 
40*635a8641SAndroid Build Coastguard Worker // Many of the StringPiece functions use different implementations for the
41*635a8641SAndroid Build Coastguard Worker // 8-bit and 16-bit versions, and we don't want lots of template expansions in
42*635a8641SAndroid Build Coastguard Worker // this (very common) header that will slow down compilation.
43*635a8641SAndroid Build Coastguard Worker //
44*635a8641SAndroid Build Coastguard Worker // So here we define overloaded functions called by the StringPiece template.
45*635a8641SAndroid Build Coastguard Worker // For those that share an implementation, the two versions will expand to a
46*635a8641SAndroid Build Coastguard Worker // template internal to the .cc file.
47*635a8641SAndroid Build Coastguard Worker namespace internal {
48*635a8641SAndroid Build Coastguard Worker 
49*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
50*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target);
51*635a8641SAndroid Build Coastguard Worker 
52*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
53*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target);
54*635a8641SAndroid Build Coastguard Worker 
55*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t copy(const StringPiece& self,
56*635a8641SAndroid Build Coastguard Worker                         char* buf,
57*635a8641SAndroid Build Coastguard Worker                         size_t n,
58*635a8641SAndroid Build Coastguard Worker                         size_t pos);
59*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t copy(const StringPiece16& self,
60*635a8641SAndroid Build Coastguard Worker                         char16* buf,
61*635a8641SAndroid Build Coastguard Worker                         size_t n,
62*635a8641SAndroid Build Coastguard Worker                         size_t pos);
63*635a8641SAndroid Build Coastguard Worker 
64*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece& self,
65*635a8641SAndroid Build Coastguard Worker                         const StringPiece& s,
66*635a8641SAndroid Build Coastguard Worker                         size_t pos);
67*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece16& self,
68*635a8641SAndroid Build Coastguard Worker                         const StringPiece16& s,
69*635a8641SAndroid Build Coastguard Worker                         size_t pos);
70*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece& self,
71*635a8641SAndroid Build Coastguard Worker                         char c,
72*635a8641SAndroid Build Coastguard Worker                         size_t pos);
73*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece16& self,
74*635a8641SAndroid Build Coastguard Worker                         char16 c,
75*635a8641SAndroid Build Coastguard Worker                         size_t pos);
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece& self,
78*635a8641SAndroid Build Coastguard Worker                          const StringPiece& s,
79*635a8641SAndroid Build Coastguard Worker                          size_t pos);
80*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece16& self,
81*635a8641SAndroid Build Coastguard Worker                          const StringPiece16& s,
82*635a8641SAndroid Build Coastguard Worker                          size_t pos);
83*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece& self,
84*635a8641SAndroid Build Coastguard Worker                          char c,
85*635a8641SAndroid Build Coastguard Worker                          size_t pos);
86*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece16& self,
87*635a8641SAndroid Build Coastguard Worker                          char16 c,
88*635a8641SAndroid Build Coastguard Worker                          size_t pos);
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_of(const StringPiece& self,
91*635a8641SAndroid Build Coastguard Worker                                  const StringPiece& s,
92*635a8641SAndroid Build Coastguard Worker                                  size_t pos);
93*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_of(const StringPiece16& self,
94*635a8641SAndroid Build Coastguard Worker                                  const StringPiece16& s,
95*635a8641SAndroid Build Coastguard Worker                                  size_t pos);
96*635a8641SAndroid Build Coastguard Worker 
97*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
98*635a8641SAndroid Build Coastguard Worker                                      const StringPiece& s,
99*635a8641SAndroid Build Coastguard Worker                                      size_t pos);
100*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
101*635a8641SAndroid Build Coastguard Worker                                      const StringPiece16& s,
102*635a8641SAndroid Build Coastguard Worker                                      size_t pos);
103*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
104*635a8641SAndroid Build Coastguard Worker                                      char c,
105*635a8641SAndroid Build Coastguard Worker                                      size_t pos);
106*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
107*635a8641SAndroid Build Coastguard Worker                                      char16 c,
108*635a8641SAndroid Build Coastguard Worker                                      size_t pos);
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece& self,
111*635a8641SAndroid Build Coastguard Worker                                 const StringPiece& s,
112*635a8641SAndroid Build Coastguard Worker                                 size_t pos);
113*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece16& self,
114*635a8641SAndroid Build Coastguard Worker                                 const StringPiece16& s,
115*635a8641SAndroid Build Coastguard Worker                                 size_t pos);
116*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece& self,
117*635a8641SAndroid Build Coastguard Worker                                 char c,
118*635a8641SAndroid Build Coastguard Worker                                 size_t pos);
119*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece16& self,
120*635a8641SAndroid Build Coastguard Worker                                 char16 c,
121*635a8641SAndroid Build Coastguard Worker                                 size_t pos);
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
124*635a8641SAndroid Build Coastguard Worker                                     const StringPiece& s,
125*635a8641SAndroid Build Coastguard Worker                                     size_t pos);
126*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
127*635a8641SAndroid Build Coastguard Worker                                     const StringPiece16& s,
128*635a8641SAndroid Build Coastguard Worker                                     size_t pos);
129*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
130*635a8641SAndroid Build Coastguard Worker                                     char16 c,
131*635a8641SAndroid Build Coastguard Worker                                     size_t pos);
132*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
133*635a8641SAndroid Build Coastguard Worker                                     char c,
134*635a8641SAndroid Build Coastguard Worker                                     size_t pos);
135*635a8641SAndroid Build Coastguard Worker 
136*635a8641SAndroid Build Coastguard Worker BASE_EXPORT StringPiece substr(const StringPiece& self,
137*635a8641SAndroid Build Coastguard Worker                                size_t pos,
138*635a8641SAndroid Build Coastguard Worker                                size_t n);
139*635a8641SAndroid Build Coastguard Worker BASE_EXPORT StringPiece16 substr(const StringPiece16& self,
140*635a8641SAndroid Build Coastguard Worker                                  size_t pos,
141*635a8641SAndroid Build Coastguard Worker                                  size_t n);
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
144*635a8641SAndroid Build Coastguard Worker // Asserts that begin <= end to catch some errors with iterator usage.
145*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AssertIteratorsInOrder(std::string::const_iterator begin,
146*635a8641SAndroid Build Coastguard Worker                                         std::string::const_iterator end);
147*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AssertIteratorsInOrder(string16::const_iterator begin,
148*635a8641SAndroid Build Coastguard Worker                                         string16::const_iterator end);
149*635a8641SAndroid Build Coastguard Worker #endif
150*635a8641SAndroid Build Coastguard Worker 
151*635a8641SAndroid Build Coastguard Worker }  // namespace internal
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker // BasicStringPiece ------------------------------------------------------------
154*635a8641SAndroid Build Coastguard Worker 
155*635a8641SAndroid Build Coastguard Worker // Defines the types, methods, operators, and data members common to both
156*635a8641SAndroid Build Coastguard Worker // StringPiece and StringPiece16. Do not refer to this class directly, but
157*635a8641SAndroid Build Coastguard Worker // rather to BasicStringPiece, StringPiece, or StringPiece16.
158*635a8641SAndroid Build Coastguard Worker //
159*635a8641SAndroid Build Coastguard Worker // This is templatized by string class type rather than character type, so
160*635a8641SAndroid Build Coastguard Worker // BasicStringPiece<std::string> or BasicStringPiece<base::string16>.
161*635a8641SAndroid Build Coastguard Worker template <typename STRING_TYPE> class BasicStringPiece {
162*635a8641SAndroid Build Coastguard Worker  public:
163*635a8641SAndroid Build Coastguard Worker   // Standard STL container boilerplate.
164*635a8641SAndroid Build Coastguard Worker   typedef size_t size_type;
165*635a8641SAndroid Build Coastguard Worker   typedef typename STRING_TYPE::value_type value_type;
166*635a8641SAndroid Build Coastguard Worker   typedef const value_type* pointer;
167*635a8641SAndroid Build Coastguard Worker   typedef const value_type& reference;
168*635a8641SAndroid Build Coastguard Worker   typedef const value_type& const_reference;
169*635a8641SAndroid Build Coastguard Worker   typedef ptrdiff_t difference_type;
170*635a8641SAndroid Build Coastguard Worker   typedef const value_type* const_iterator;
171*635a8641SAndroid Build Coastguard Worker   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
172*635a8641SAndroid Build Coastguard Worker 
173*635a8641SAndroid Build Coastguard Worker   static const size_type npos;
174*635a8641SAndroid Build Coastguard Worker 
175*635a8641SAndroid Build Coastguard Worker  public:
176*635a8641SAndroid Build Coastguard Worker   // We provide non-explicit singleton constructors so users can pass
177*635a8641SAndroid Build Coastguard Worker   // in a "const char*" or a "string" wherever a "StringPiece" is
178*635a8641SAndroid Build Coastguard Worker   // expected (likewise for char16, string16, StringPiece16).
BasicStringPiece()179*635a8641SAndroid Build Coastguard Worker   constexpr BasicStringPiece() : ptr_(NULL), length_(0) {}
180*635a8641SAndroid Build Coastguard Worker   // TODO(dcheng): Construction from nullptr is not allowed for
181*635a8641SAndroid Build Coastguard Worker   // std::basic_string_view, so remove the special handling for it.
182*635a8641SAndroid Build Coastguard Worker   // Note: This doesn't just use STRING_TYPE::traits_type::length(), since that
183*635a8641SAndroid Build Coastguard Worker   // isn't constexpr until C++17.
BasicStringPiece(const value_type * str)184*635a8641SAndroid Build Coastguard Worker   constexpr BasicStringPiece(const value_type* str)
185*635a8641SAndroid Build Coastguard Worker       : ptr_(str), length_(!str ? 0 : CharTraits<value_type>::length(str)) {}
BasicStringPiece(const STRING_TYPE & str)186*635a8641SAndroid Build Coastguard Worker   BasicStringPiece(const STRING_TYPE& str)
187*635a8641SAndroid Build Coastguard Worker       : ptr_(str.data()), length_(str.size()) {}
BasicStringPiece(const value_type * offset,size_type len)188*635a8641SAndroid Build Coastguard Worker   constexpr BasicStringPiece(const value_type* offset, size_type len)
189*635a8641SAndroid Build Coastguard Worker       : ptr_(offset), length_(len) {}
BasicStringPiece(const typename STRING_TYPE::const_iterator & begin,const typename STRING_TYPE::const_iterator & end)190*635a8641SAndroid Build Coastguard Worker   BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
191*635a8641SAndroid Build Coastguard Worker                    const typename STRING_TYPE::const_iterator& end) {
192*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
193*635a8641SAndroid Build Coastguard Worker     // This assertion is done out-of-line to avoid bringing in logging.h and
194*635a8641SAndroid Build Coastguard Worker     // instantiating logging macros for every instantiation.
195*635a8641SAndroid Build Coastguard Worker     internal::AssertIteratorsInOrder(begin, end);
196*635a8641SAndroid Build Coastguard Worker #endif
197*635a8641SAndroid Build Coastguard Worker     length_ = static_cast<size_t>(std::distance(begin, end));
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker     // The length test before assignment is to avoid dereferencing an iterator
200*635a8641SAndroid Build Coastguard Worker     // that may point to the end() of a string.
201*635a8641SAndroid Build Coastguard Worker     ptr_ = length_ > 0 ? &*begin : nullptr;
202*635a8641SAndroid Build Coastguard Worker   }
203*635a8641SAndroid Build Coastguard Worker 
204*635a8641SAndroid Build Coastguard Worker   // data() may return a pointer to a buffer with embedded NULs, and the
205*635a8641SAndroid Build Coastguard Worker   // returned buffer may or may not be null terminated.  Therefore it is
206*635a8641SAndroid Build Coastguard Worker   // typically a mistake to pass data() to a routine that expects a NUL
207*635a8641SAndroid Build Coastguard Worker   // terminated string.
data()208*635a8641SAndroid Build Coastguard Worker   constexpr const value_type* data() const { return ptr_; }
size()209*635a8641SAndroid Build Coastguard Worker   constexpr size_type size() const { return length_; }
length()210*635a8641SAndroid Build Coastguard Worker   constexpr size_type length() const { return length_; }
empty()211*635a8641SAndroid Build Coastguard Worker   bool empty() const { return length_ == 0; }
212*635a8641SAndroid Build Coastguard Worker 
clear()213*635a8641SAndroid Build Coastguard Worker   void clear() {
214*635a8641SAndroid Build Coastguard Worker     ptr_ = NULL;
215*635a8641SAndroid Build Coastguard Worker     length_ = 0;
216*635a8641SAndroid Build Coastguard Worker   }
set(const value_type * data,size_type len)217*635a8641SAndroid Build Coastguard Worker   void set(const value_type* data, size_type len) {
218*635a8641SAndroid Build Coastguard Worker     ptr_ = data;
219*635a8641SAndroid Build Coastguard Worker     length_ = len;
220*635a8641SAndroid Build Coastguard Worker   }
set(const value_type * str)221*635a8641SAndroid Build Coastguard Worker   void set(const value_type* str) {
222*635a8641SAndroid Build Coastguard Worker     ptr_ = str;
223*635a8641SAndroid Build Coastguard Worker     length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
224*635a8641SAndroid Build Coastguard Worker   }
225*635a8641SAndroid Build Coastguard Worker 
226*635a8641SAndroid Build Coastguard Worker   constexpr value_type operator[](size_type i) const {
227*635a8641SAndroid Build Coastguard Worker     CHECK(i < length_);
228*635a8641SAndroid Build Coastguard Worker     return ptr_[i];
229*635a8641SAndroid Build Coastguard Worker   }
230*635a8641SAndroid Build Coastguard Worker 
front()231*635a8641SAndroid Build Coastguard Worker   value_type front() const {
232*635a8641SAndroid Build Coastguard Worker     CHECK_NE(0UL, length_);
233*635a8641SAndroid Build Coastguard Worker     return ptr_[0];
234*635a8641SAndroid Build Coastguard Worker   }
235*635a8641SAndroid Build Coastguard Worker 
back()236*635a8641SAndroid Build Coastguard Worker   value_type back() const {
237*635a8641SAndroid Build Coastguard Worker     CHECK_NE(0UL, length_);
238*635a8641SAndroid Build Coastguard Worker     return ptr_[length_ - 1];
239*635a8641SAndroid Build Coastguard Worker   }
240*635a8641SAndroid Build Coastguard Worker 
remove_prefix(size_type n)241*635a8641SAndroid Build Coastguard Worker   constexpr void remove_prefix(size_type n) {
242*635a8641SAndroid Build Coastguard Worker     CHECK(n <= length_);
243*635a8641SAndroid Build Coastguard Worker     ptr_ += n;
244*635a8641SAndroid Build Coastguard Worker     length_ -= n;
245*635a8641SAndroid Build Coastguard Worker   }
246*635a8641SAndroid Build Coastguard Worker 
remove_suffix(size_type n)247*635a8641SAndroid Build Coastguard Worker   constexpr void remove_suffix(size_type n) {
248*635a8641SAndroid Build Coastguard Worker     CHECK(n <= length_);
249*635a8641SAndroid Build Coastguard Worker     length_ -= n;
250*635a8641SAndroid Build Coastguard Worker   }
251*635a8641SAndroid Build Coastguard Worker 
compare(BasicStringPiece x)252*635a8641SAndroid Build Coastguard Worker   constexpr int compare(BasicStringPiece x) const noexcept {
253*635a8641SAndroid Build Coastguard Worker     int r = CharTraits<value_type>::compare(
254*635a8641SAndroid Build Coastguard Worker         ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
255*635a8641SAndroid Build Coastguard Worker     if (r == 0) {
256*635a8641SAndroid Build Coastguard Worker       if (length_ < x.length_) r = -1;
257*635a8641SAndroid Build Coastguard Worker       else if (length_ > x.length_) r = +1;
258*635a8641SAndroid Build Coastguard Worker     }
259*635a8641SAndroid Build Coastguard Worker     return r;
260*635a8641SAndroid Build Coastguard Worker   }
261*635a8641SAndroid Build Coastguard Worker 
262*635a8641SAndroid Build Coastguard Worker   // This is the style of conversion preferred by std::string_view in C++17.
STRING_TYPE()263*635a8641SAndroid Build Coastguard Worker   explicit operator STRING_TYPE() const { return as_string(); }
264*635a8641SAndroid Build Coastguard Worker 
as_string()265*635a8641SAndroid Build Coastguard Worker   STRING_TYPE as_string() const {
266*635a8641SAndroid Build Coastguard Worker     // std::string doesn't like to take a NULL pointer even with a 0 size.
267*635a8641SAndroid Build Coastguard Worker     return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
268*635a8641SAndroid Build Coastguard Worker   }
269*635a8641SAndroid Build Coastguard Worker 
begin()270*635a8641SAndroid Build Coastguard Worker   const_iterator begin() const { return ptr_; }
end()271*635a8641SAndroid Build Coastguard Worker   const_iterator end() const { return ptr_ + length_; }
rbegin()272*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rbegin() const {
273*635a8641SAndroid Build Coastguard Worker     return const_reverse_iterator(ptr_ + length_);
274*635a8641SAndroid Build Coastguard Worker   }
rend()275*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rend() const {
276*635a8641SAndroid Build Coastguard Worker     return const_reverse_iterator(ptr_);
277*635a8641SAndroid Build Coastguard Worker   }
278*635a8641SAndroid Build Coastguard Worker 
max_size()279*635a8641SAndroid Build Coastguard Worker   size_type max_size() const { return length_; }
capacity()280*635a8641SAndroid Build Coastguard Worker   size_type capacity() const { return length_; }
281*635a8641SAndroid Build Coastguard Worker 
282*635a8641SAndroid Build Coastguard Worker   // Sets the value of the given string target type to be the current string.
283*635a8641SAndroid Build Coastguard Worker   // This saves a temporary over doing |a = b.as_string()|
CopyToString(STRING_TYPE * target)284*635a8641SAndroid Build Coastguard Worker   void CopyToString(STRING_TYPE* target) const {
285*635a8641SAndroid Build Coastguard Worker     internal::CopyToString(*this, target);
286*635a8641SAndroid Build Coastguard Worker   }
287*635a8641SAndroid Build Coastguard Worker 
AppendToString(STRING_TYPE * target)288*635a8641SAndroid Build Coastguard Worker   void AppendToString(STRING_TYPE* target) const {
289*635a8641SAndroid Build Coastguard Worker     internal::AppendToString(*this, target);
290*635a8641SAndroid Build Coastguard Worker   }
291*635a8641SAndroid Build Coastguard Worker 
292*635a8641SAndroid Build Coastguard Worker   size_type copy(value_type* buf, size_type n, size_type pos = 0) const {
293*635a8641SAndroid Build Coastguard Worker     return internal::copy(*this, buf, n, pos);
294*635a8641SAndroid Build Coastguard Worker   }
295*635a8641SAndroid Build Coastguard Worker 
296*635a8641SAndroid Build Coastguard Worker   // Does "this" start with "x"
starts_with(BasicStringPiece x)297*635a8641SAndroid Build Coastguard Worker   constexpr bool starts_with(BasicStringPiece x) const noexcept {
298*635a8641SAndroid Build Coastguard Worker     return (
299*635a8641SAndroid Build Coastguard Worker         (this->length_ >= x.length_) &&
300*635a8641SAndroid Build Coastguard Worker         (CharTraits<value_type>::compare(this->ptr_, x.ptr_, x.length_) == 0));
301*635a8641SAndroid Build Coastguard Worker   }
302*635a8641SAndroid Build Coastguard Worker 
303*635a8641SAndroid Build Coastguard Worker   // Does "this" end with "x"
ends_with(BasicStringPiece x)304*635a8641SAndroid Build Coastguard Worker   constexpr bool ends_with(BasicStringPiece x) const noexcept {
305*635a8641SAndroid Build Coastguard Worker     return ((this->length_ >= x.length_) &&
306*635a8641SAndroid Build Coastguard Worker             (CharTraits<value_type>::compare(
307*635a8641SAndroid Build Coastguard Worker                  this->ptr_ + (this->length_ - x.length_), x.ptr_, x.length_) ==
308*635a8641SAndroid Build Coastguard Worker              0));
309*635a8641SAndroid Build Coastguard Worker   }
310*635a8641SAndroid Build Coastguard Worker 
311*635a8641SAndroid Build Coastguard Worker   // find: Search for a character or substring at a given offset.
312*635a8641SAndroid Build Coastguard Worker   size_type find(const BasicStringPiece<STRING_TYPE>& s,
313*635a8641SAndroid Build Coastguard Worker                  size_type pos = 0) const {
314*635a8641SAndroid Build Coastguard Worker     return internal::find(*this, s, pos);
315*635a8641SAndroid Build Coastguard Worker   }
316*635a8641SAndroid Build Coastguard Worker   size_type find(value_type c, size_type pos = 0) const {
317*635a8641SAndroid Build Coastguard Worker     return internal::find(*this, c, pos);
318*635a8641SAndroid Build Coastguard Worker   }
319*635a8641SAndroid Build Coastguard Worker 
320*635a8641SAndroid Build Coastguard Worker   // rfind: Reverse find.
321*635a8641SAndroid Build Coastguard Worker   size_type rfind(const BasicStringPiece& s,
322*635a8641SAndroid Build Coastguard Worker                   size_type pos = BasicStringPiece::npos) const {
323*635a8641SAndroid Build Coastguard Worker     return internal::rfind(*this, s, pos);
324*635a8641SAndroid Build Coastguard Worker   }
325*635a8641SAndroid Build Coastguard Worker   size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const {
326*635a8641SAndroid Build Coastguard Worker     return internal::rfind(*this, c, pos);
327*635a8641SAndroid Build Coastguard Worker   }
328*635a8641SAndroid Build Coastguard Worker 
329*635a8641SAndroid Build Coastguard Worker   // find_first_of: Find the first occurence of one of a set of characters.
330*635a8641SAndroid Build Coastguard Worker   size_type find_first_of(const BasicStringPiece& s,
331*635a8641SAndroid Build Coastguard Worker                           size_type pos = 0) const {
332*635a8641SAndroid Build Coastguard Worker     return internal::find_first_of(*this, s, pos);
333*635a8641SAndroid Build Coastguard Worker   }
334*635a8641SAndroid Build Coastguard Worker   size_type find_first_of(value_type c, size_type pos = 0) const {
335*635a8641SAndroid Build Coastguard Worker     return find(c, pos);
336*635a8641SAndroid Build Coastguard Worker   }
337*635a8641SAndroid Build Coastguard Worker 
338*635a8641SAndroid Build Coastguard Worker   // find_first_not_of: Find the first occurence not of a set of characters.
339*635a8641SAndroid Build Coastguard Worker   size_type find_first_not_of(const BasicStringPiece& s,
340*635a8641SAndroid Build Coastguard Worker                               size_type pos = 0) const {
341*635a8641SAndroid Build Coastguard Worker     return internal::find_first_not_of(*this, s, pos);
342*635a8641SAndroid Build Coastguard Worker   }
343*635a8641SAndroid Build Coastguard Worker   size_type find_first_not_of(value_type c, size_type pos = 0) const {
344*635a8641SAndroid Build Coastguard Worker     return internal::find_first_not_of(*this, c, pos);
345*635a8641SAndroid Build Coastguard Worker   }
346*635a8641SAndroid Build Coastguard Worker 
347*635a8641SAndroid Build Coastguard Worker   // find_last_of: Find the last occurence of one of a set of characters.
348*635a8641SAndroid Build Coastguard Worker   size_type find_last_of(const BasicStringPiece& s,
349*635a8641SAndroid Build Coastguard Worker                          size_type pos = BasicStringPiece::npos) const {
350*635a8641SAndroid Build Coastguard Worker     return internal::find_last_of(*this, s, pos);
351*635a8641SAndroid Build Coastguard Worker   }
352*635a8641SAndroid Build Coastguard Worker   size_type find_last_of(value_type c,
353*635a8641SAndroid Build Coastguard Worker                          size_type pos = BasicStringPiece::npos) const {
354*635a8641SAndroid Build Coastguard Worker     return rfind(c, pos);
355*635a8641SAndroid Build Coastguard Worker   }
356*635a8641SAndroid Build Coastguard Worker 
357*635a8641SAndroid Build Coastguard Worker   // find_last_not_of: Find the last occurence not of a set of characters.
358*635a8641SAndroid Build Coastguard Worker   size_type find_last_not_of(const BasicStringPiece& s,
359*635a8641SAndroid Build Coastguard Worker                              size_type pos = BasicStringPiece::npos) const {
360*635a8641SAndroid Build Coastguard Worker     return internal::find_last_not_of(*this, s, pos);
361*635a8641SAndroid Build Coastguard Worker   }
362*635a8641SAndroid Build Coastguard Worker   size_type find_last_not_of(value_type c,
363*635a8641SAndroid Build Coastguard Worker                              size_type pos = BasicStringPiece::npos) const {
364*635a8641SAndroid Build Coastguard Worker     return internal::find_last_not_of(*this, c, pos);
365*635a8641SAndroid Build Coastguard Worker   }
366*635a8641SAndroid Build Coastguard Worker 
367*635a8641SAndroid Build Coastguard Worker   // substr.
368*635a8641SAndroid Build Coastguard Worker   BasicStringPiece substr(size_type pos,
369*635a8641SAndroid Build Coastguard Worker                           size_type n = BasicStringPiece::npos) const {
370*635a8641SAndroid Build Coastguard Worker     return internal::substr(*this, pos, n);
371*635a8641SAndroid Build Coastguard Worker   }
372*635a8641SAndroid Build Coastguard Worker 
373*635a8641SAndroid Build Coastguard Worker  protected:
374*635a8641SAndroid Build Coastguard Worker   const value_type* ptr_;
375*635a8641SAndroid Build Coastguard Worker   size_type length_;
376*635a8641SAndroid Build Coastguard Worker };
377*635a8641SAndroid Build Coastguard Worker 
378*635a8641SAndroid Build Coastguard Worker template <typename STRING_TYPE>
379*635a8641SAndroid Build Coastguard Worker const typename BasicStringPiece<STRING_TYPE>::size_type
380*635a8641SAndroid Build Coastguard Worker BasicStringPiece<STRING_TYPE>::npos =
381*635a8641SAndroid Build Coastguard Worker     typename BasicStringPiece<STRING_TYPE>::size_type(-1);
382*635a8641SAndroid Build Coastguard Worker 
383*635a8641SAndroid Build Coastguard Worker // MSVC doesn't like complex extern templates and DLLs.
384*635a8641SAndroid Build Coastguard Worker #if !defined(COMPILER_MSVC)
385*635a8641SAndroid Build Coastguard Worker extern template class BASE_EXPORT BasicStringPiece<std::string>;
386*635a8641SAndroid Build Coastguard Worker extern template class BASE_EXPORT BasicStringPiece<string16>;
387*635a8641SAndroid Build Coastguard Worker #endif
388*635a8641SAndroid Build Coastguard Worker 
389*635a8641SAndroid Build Coastguard Worker // StingPiece operators --------------------------------------------------------
390*635a8641SAndroid Build Coastguard Worker 
391*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
392*635a8641SAndroid Build Coastguard Worker 
393*635a8641SAndroid Build Coastguard Worker inline bool operator!=(const StringPiece& x, const StringPiece& y) {
394*635a8641SAndroid Build Coastguard Worker   return !(x == y);
395*635a8641SAndroid Build Coastguard Worker }
396*635a8641SAndroid Build Coastguard Worker 
397*635a8641SAndroid Build Coastguard Worker inline bool operator<(const StringPiece& x, const StringPiece& y) {
398*635a8641SAndroid Build Coastguard Worker   const int r = CharTraits<StringPiece::value_type>::compare(
399*635a8641SAndroid Build Coastguard Worker       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
400*635a8641SAndroid Build Coastguard Worker   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
401*635a8641SAndroid Build Coastguard Worker }
402*635a8641SAndroid Build Coastguard Worker 
403*635a8641SAndroid Build Coastguard Worker inline bool operator>(const StringPiece& x, const StringPiece& y) {
404*635a8641SAndroid Build Coastguard Worker   return y < x;
405*635a8641SAndroid Build Coastguard Worker }
406*635a8641SAndroid Build Coastguard Worker 
407*635a8641SAndroid Build Coastguard Worker inline bool operator<=(const StringPiece& x, const StringPiece& y) {
408*635a8641SAndroid Build Coastguard Worker   return !(x > y);
409*635a8641SAndroid Build Coastguard Worker }
410*635a8641SAndroid Build Coastguard Worker 
411*635a8641SAndroid Build Coastguard Worker inline bool operator>=(const StringPiece& x, const StringPiece& y) {
412*635a8641SAndroid Build Coastguard Worker   return !(x < y);
413*635a8641SAndroid Build Coastguard Worker }
414*635a8641SAndroid Build Coastguard Worker 
415*635a8641SAndroid Build Coastguard Worker // StringPiece16 operators -----------------------------------------------------
416*635a8641SAndroid Build Coastguard Worker 
417*635a8641SAndroid Build Coastguard Worker inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
418*635a8641SAndroid Build Coastguard Worker   if (x.size() != y.size())
419*635a8641SAndroid Build Coastguard Worker     return false;
420*635a8641SAndroid Build Coastguard Worker 
421*635a8641SAndroid Build Coastguard Worker   return CharTraits<StringPiece16::value_type>::compare(x.data(), y.data(),
422*635a8641SAndroid Build Coastguard Worker                                                         x.size()) == 0;
423*635a8641SAndroid Build Coastguard Worker }
424*635a8641SAndroid Build Coastguard Worker 
425*635a8641SAndroid Build Coastguard Worker inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
426*635a8641SAndroid Build Coastguard Worker   return !(x == y);
427*635a8641SAndroid Build Coastguard Worker }
428*635a8641SAndroid Build Coastguard Worker 
429*635a8641SAndroid Build Coastguard Worker inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
430*635a8641SAndroid Build Coastguard Worker   const int r = CharTraits<StringPiece16::value_type>::compare(
431*635a8641SAndroid Build Coastguard Worker       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
432*635a8641SAndroid Build Coastguard Worker   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
433*635a8641SAndroid Build Coastguard Worker }
434*635a8641SAndroid Build Coastguard Worker 
435*635a8641SAndroid Build Coastguard Worker inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
436*635a8641SAndroid Build Coastguard Worker   return y < x;
437*635a8641SAndroid Build Coastguard Worker }
438*635a8641SAndroid Build Coastguard Worker 
439*635a8641SAndroid Build Coastguard Worker inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
440*635a8641SAndroid Build Coastguard Worker   return !(x > y);
441*635a8641SAndroid Build Coastguard Worker }
442*635a8641SAndroid Build Coastguard Worker 
443*635a8641SAndroid Build Coastguard Worker inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
444*635a8641SAndroid Build Coastguard Worker   return !(x < y);
445*635a8641SAndroid Build Coastguard Worker }
446*635a8641SAndroid Build Coastguard Worker 
447*635a8641SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& o,
448*635a8641SAndroid Build Coastguard Worker                                      const StringPiece& piece);
449*635a8641SAndroid Build Coastguard Worker 
450*635a8641SAndroid Build Coastguard Worker // Hashing ---------------------------------------------------------------------
451*635a8641SAndroid Build Coastguard Worker 
452*635a8641SAndroid Build Coastguard Worker // We provide appropriate hash functions so StringPiece and StringPiece16 can
453*635a8641SAndroid Build Coastguard Worker // be used as keys in hash sets and maps.
454*635a8641SAndroid Build Coastguard Worker 
455*635a8641SAndroid Build Coastguard Worker // This hash function is copied from base/strings/string16.h. We don't use the
456*635a8641SAndroid Build Coastguard Worker // ones already defined for string and string16 directly because it would
457*635a8641SAndroid Build Coastguard Worker // require the string constructors to be called, which we don't want.
458*635a8641SAndroid Build Coastguard Worker #define HASH_STRING_PIECE(StringPieceType, string_piece)         \
459*635a8641SAndroid Build Coastguard Worker   std::size_t result = 0;                                        \
460*635a8641SAndroid Build Coastguard Worker   for (StringPieceType::const_iterator i = string_piece.begin(); \
461*635a8641SAndroid Build Coastguard Worker        i != string_piece.end(); ++i)                             \
462*635a8641SAndroid Build Coastguard Worker     result = (result * 131) + *i;                                \
463*635a8641SAndroid Build Coastguard Worker   return result;
464*635a8641SAndroid Build Coastguard Worker 
465*635a8641SAndroid Build Coastguard Worker struct StringPieceHash {
operatorStringPieceHash466*635a8641SAndroid Build Coastguard Worker   std::size_t operator()(const StringPiece& sp) const {
467*635a8641SAndroid Build Coastguard Worker     HASH_STRING_PIECE(StringPiece, sp);
468*635a8641SAndroid Build Coastguard Worker   }
469*635a8641SAndroid Build Coastguard Worker };
470*635a8641SAndroid Build Coastguard Worker struct StringPiece16Hash {
operatorStringPiece16Hash471*635a8641SAndroid Build Coastguard Worker   std::size_t operator()(const StringPiece16& sp16) const {
472*635a8641SAndroid Build Coastguard Worker     HASH_STRING_PIECE(StringPiece16, sp16);
473*635a8641SAndroid Build Coastguard Worker   }
474*635a8641SAndroid Build Coastguard Worker };
475*635a8641SAndroid Build Coastguard Worker struct WStringPieceHash {
operatorWStringPieceHash476*635a8641SAndroid Build Coastguard Worker   std::size_t operator()(const WStringPiece& wsp) const {
477*635a8641SAndroid Build Coastguard Worker     HASH_STRING_PIECE(WStringPiece, wsp);
478*635a8641SAndroid Build Coastguard Worker   }
479*635a8641SAndroid Build Coastguard Worker };
480*635a8641SAndroid Build Coastguard Worker 
481*635a8641SAndroid Build Coastguard Worker }  // namespace base
482*635a8641SAndroid Build Coastguard Worker 
483*635a8641SAndroid Build Coastguard Worker #endif  // BASE_STRINGS_STRING_PIECE_H_
484