OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // Copied from strings/stringpiece.h with modifications | 4 // Copied from strings/stringpiece.h with modifications |
5 // | 5 // |
6 // A string-like object that points to a sized piece of memory. | 6 // A string-like object that points to a sized piece of memory. |
7 // | 7 // |
8 // Functions or methods may use const StringPiece& parameters to accept either | 8 // Functions or methods may use const StringPiece& parameters to accept either |
9 // a "const char*" or a "string" value that will be implicitly converted to | 9 // a "const char*" or a "string" value that will be implicitly converted to |
10 // a StringPiece. The implicit conversion means that it is often appropriate | 10 // a StringPiece. The implicit conversion means that it is often appropriate |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "base/basictypes.h" | 32 #include "base/basictypes.h" |
33 #include "base/containers/hash_tables.h" | 33 #include "base/containers/hash_tables.h" |
34 #include "base/strings/string16.h" | 34 #include "base/strings/string16.h" |
35 | 35 |
36 namespace base { | 36 namespace base { |
37 | 37 |
38 template <typename STRING_TYPE> class BasicStringPiece; | 38 template <typename STRING_TYPE> class BasicStringPiece; |
39 typedef BasicStringPiece<std::string> StringPiece; | 39 typedef BasicStringPiece<std::string> StringPiece; |
40 typedef BasicStringPiece<string16> StringPiece16; | 40 typedef BasicStringPiece<string16> StringPiece16; |
41 | 41 |
42 // internal -------------------------------------------------------------------- | |
43 | |
44 // Many of the StringPiece functions use different implementations for the | |
45 // 8-bit and 16-bit versions, and we don't want lots of template expansions in | |
46 // this (very common) header that will slow down compilation. | |
47 // | |
48 // So here we define overloaded functions called by the StringPiece template. | |
49 // For those that share an implementation, the two versions will expand to a | |
50 // template internal to the .cc file. | |
51 namespace internal { | 42 namespace internal { |
52 | 43 |
53 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); | |
54 BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target); | |
55 | |
56 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); | |
57 BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target); | |
58 | |
59 BASE_EXPORT size_t copy(const StringPiece& self, | |
60 char* buf, | |
61 size_t n, | |
62 size_t pos); | |
63 BASE_EXPORT size_t copy(const StringPiece16& self, | |
64 char16* buf, | |
65 size_t n, | |
66 size_t pos); | |
67 | |
68 BASE_EXPORT size_t find(const StringPiece& self, | |
69 const StringPiece& s, | |
70 size_t pos); | |
71 BASE_EXPORT size_t find(const StringPiece16& self, | |
72 const StringPiece16& s, | |
73 size_t pos); | |
74 BASE_EXPORT size_t find(const StringPiece& self, | |
75 char c, | |
76 size_t pos); | |
77 BASE_EXPORT size_t find(const StringPiece16& self, | |
78 char16 c, | |
79 size_t pos); | |
80 | |
81 BASE_EXPORT size_t rfind(const StringPiece& self, | |
82 const StringPiece& s, | |
83 size_t pos); | |
84 BASE_EXPORT size_t rfind(const StringPiece16& self, | |
85 const StringPiece16& s, | |
86 size_t pos); | |
87 BASE_EXPORT size_t rfind(const StringPiece& self, | |
88 char c, | |
89 size_t pos); | |
90 BASE_EXPORT size_t rfind(const StringPiece16& self, | |
91 char16 c, | |
92 size_t pos); | |
93 | |
94 BASE_EXPORT size_t find_first_of(const StringPiece& self, | |
95 const StringPiece& s, | |
96 size_t pos); | |
97 BASE_EXPORT size_t find_first_of(const StringPiece16& self, | |
98 const StringPiece16& s, | |
99 size_t pos); | |
100 | |
101 BASE_EXPORT size_t find_first_not_of(const StringPiece& self, | |
102 const StringPiece& s, | |
103 size_t pos); | |
104 BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, | |
105 const StringPiece16& s, | |
106 size_t pos); | |
107 BASE_EXPORT size_t find_first_not_of(const StringPiece& self, | |
108 char c, | |
109 size_t pos); | |
110 BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, | |
111 char16 c, | |
112 size_t pos); | |
113 | |
114 BASE_EXPORT size_t find_last_of(const StringPiece& self, | |
115 const StringPiece& s, | |
116 size_t pos); | |
117 BASE_EXPORT size_t find_last_of(const StringPiece16& self, | |
118 const StringPiece16& s, | |
119 size_t pos); | |
120 BASE_EXPORT size_t find_last_of(const StringPiece& self, | |
121 char c, | |
122 size_t pos); | |
123 BASE_EXPORT size_t find_last_of(const StringPiece16& self, | |
124 char16 c, | |
125 size_t pos); | |
126 | |
127 BASE_EXPORT size_t find_last_not_of(const StringPiece& self, | |
128 const StringPiece& s, | |
129 size_t pos); | |
130 BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, | |
131 const StringPiece16& s, | |
132 size_t pos); | |
133 BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, | |
134 char16 c, | |
135 size_t pos); | |
136 BASE_EXPORT size_t find_last_not_of(const StringPiece& self, | |
137 char c, | |
138 size_t pos); | |
139 | |
140 BASE_EXPORT StringPiece substr(const StringPiece& self, | |
141 size_t pos, | |
142 size_t n); | |
143 BASE_EXPORT StringPiece16 substr(const StringPiece16& self, | |
144 size_t pos, | |
145 size_t n); | |
146 | |
147 } // namespace internal | |
148 | |
149 // BasicStringPiece ------------------------------------------------------------ | |
150 | |
151 // Defines the types, methods, operators, and data members common to both | 44 // Defines the types, methods, operators, and data members common to both |
152 // StringPiece and StringPiece16. Do not refer to this class directly, but | 45 // StringPiece and StringPiece16. Do not refer to this class directly, but |
153 // rather to BasicStringPiece, StringPiece, or StringPiece16. | 46 // rather to BasicStringPiece, StringPiece, or StringPiece16. |
154 // | 47 template <typename STRING_TYPE> class StringPieceDetail { |
155 // This is templatized by string class type rather than character type, so | |
156 // BasicStringPiece<std::string> or BasicStringPiece<base::string16>. | |
157 template <typename STRING_TYPE> class BasicStringPiece { | |
158 public: | 48 public: |
159 // Standard STL container boilerplate. | 49 // standard STL container boilerplate |
160 typedef size_t size_type; | 50 typedef size_t size_type; |
161 typedef typename STRING_TYPE::value_type value_type; | 51 typedef typename STRING_TYPE::value_type value_type; |
162 typedef const value_type* pointer; | 52 typedef const value_type* pointer; |
163 typedef const value_type& reference; | 53 typedef const value_type& reference; |
164 typedef const value_type& const_reference; | 54 typedef const value_type& const_reference; |
165 typedef ptrdiff_t difference_type; | 55 typedef ptrdiff_t difference_type; |
166 typedef const value_type* const_iterator; | 56 typedef const value_type* const_iterator; |
167 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 57 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
168 | 58 |
169 static const size_type npos; | 59 static const size_type npos; |
170 | 60 |
171 public: | 61 public: |
172 // We provide non-explicit singleton constructors so users can pass | 62 // We provide non-explicit singleton constructors so users can pass |
173 // in a "const char*" or a "string" wherever a "StringPiece" is | 63 // in a "const char*" or a "string" wherever a "StringPiece" is |
174 // expected (likewise for char16, string16, StringPiece16). | 64 // expected (likewise for char16, string16, StringPiece16). |
175 BasicStringPiece() : ptr_(NULL), length_(0) {} | 65 StringPieceDetail() : ptr_(NULL), length_(0) {} |
176 BasicStringPiece(const value_type* str) | 66 StringPieceDetail(const value_type* str) |
177 : ptr_(str), | 67 : ptr_(str), |
178 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} | 68 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} |
179 BasicStringPiece(const STRING_TYPE& str) | 69 StringPieceDetail(const STRING_TYPE& str) |
180 : ptr_(str.data()), length_(str.size()) {} | 70 : ptr_(str.data()), length_(str.size()) {} |
181 BasicStringPiece(const value_type* offset, size_type len) | 71 StringPieceDetail(const value_type* offset, size_type len) |
182 : ptr_(offset), length_(len) {} | 72 : ptr_(offset), length_(len) {} |
183 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, | 73 StringPieceDetail(const typename STRING_TYPE::const_iterator& begin, |
184 const typename STRING_TYPE::const_iterator& end) | 74 const typename STRING_TYPE::const_iterator& end) |
185 : ptr_((end > begin) ? &(*begin) : NULL), | 75 : ptr_((end > begin) ? &(*begin) : NULL), |
186 length_((end > begin) ? (size_type)(end - begin) : 0) {} | 76 length_((end > begin) ? (size_type)(end - begin) : 0) {} |
187 | 77 |
188 // data() may return a pointer to a buffer with embedded NULs, and the | 78 // data() may return a pointer to a buffer with embedded NULs, and the |
189 // returned buffer may or may not be null terminated. Therefore it is | 79 // returned buffer may or may not be null terminated. Therefore it is |
190 // typically a mistake to pass data() to a routine that expects a NUL | 80 // typically a mistake to pass data() to a routine that expects a NUL |
191 // terminated string. | 81 // terminated string. |
192 const value_type* data() const { return ptr_; } | 82 const value_type* data() const { return ptr_; } |
193 size_type size() const { return length_; } | 83 size_type size() const { return length_; } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 | 134 |
245 size_type max_size() const { return length_; } | 135 size_type max_size() const { return length_; } |
246 size_type capacity() const { return length_; } | 136 size_type capacity() const { return length_; } |
247 | 137 |
248 static int wordmemcmp(const value_type* p, | 138 static int wordmemcmp(const value_type* p, |
249 const value_type* p2, | 139 const value_type* p2, |
250 size_type N) { | 140 size_type N) { |
251 return STRING_TYPE::traits_type::compare(p, p2, N); | 141 return STRING_TYPE::traits_type::compare(p, p2, N); |
252 } | 142 } |
253 | 143 |
254 // Sets the value of the given string target type to be the current string. | |
255 // This saves a temporary over doing |a = b.as_string()| | |
256 void CopyToString(STRING_TYPE* target) const { | |
257 internal::CopyToString(*this, target); | |
258 } | |
259 | |
260 void AppendToString(STRING_TYPE* target) const { | |
261 internal::AppendToString(*this, target); | |
262 } | |
263 | |
264 size_type copy(value_type* buf, size_type n, size_type pos = 0) const { | |
265 return internal::copy(*this, buf, n, pos); | |
266 } | |
267 | |
268 // Does "this" start with "x" | |
269 bool starts_with(const BasicStringPiece& x) const { | |
270 return ((this->length_ >= x.length_) && | |
271 (wordmemcmp(this->ptr_, x.ptr_, x.length_) == 0)); | |
272 } | |
273 | |
274 // Does "this" end with "x" | |
275 bool ends_with(const BasicStringPiece& x) const { | |
276 return ((this->length_ >= x.length_) && | |
277 (wordmemcmp(this->ptr_ + (this->length_-x.length_), | |
278 x.ptr_, x.length_) == 0)); | |
279 } | |
280 | |
281 // find: Search for a character or substring at a given offset. | |
282 size_type find(const BasicStringPiece<STRING_TYPE>& s, | |
283 size_type pos = 0) const { | |
284 return internal::find(*this, s, pos); | |
285 } | |
286 size_type find(value_type c, size_type pos = 0) const { | |
287 return internal::find(*this, c, pos); | |
288 } | |
289 | |
290 // rfind: Reverse find. | |
291 size_type rfind(const BasicStringPiece& s, | |
292 size_type pos = BasicStringPiece::npos) const { | |
293 return internal::rfind(*this, s, pos); | |
294 } | |
295 size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const { | |
296 return internal::rfind(*this, c, pos); | |
297 } | |
298 | |
299 // find_first_of: Find the first occurence of one of a set of characters. | |
300 size_type find_first_of(const BasicStringPiece& s, | |
301 size_type pos = 0) const { | |
302 return internal::find_first_of(*this, s, pos); | |
303 } | |
304 size_type find_first_of(value_type c, size_type pos = 0) const { | |
305 return find(c, pos); | |
306 } | |
307 | |
308 // find_first_not_of: Find the first occurence not of a set of characters. | |
309 size_type find_first_not_of(const BasicStringPiece& s, | |
310 size_type pos = 0) const { | |
311 return internal::find_first_not_of(*this, s, pos); | |
312 } | |
313 size_type find_first_not_of(value_type c, size_type pos = 0) const { | |
314 return internal::find_first_not_of(*this, c, pos); | |
315 } | |
316 | |
317 // find_last_of: Find the last occurence of one of a set of characters. | |
318 size_type find_last_of(const BasicStringPiece& s, | |
319 size_type pos = BasicStringPiece::npos) const { | |
320 return internal::find_last_of(*this, s, pos); | |
321 } | |
322 size_type find_last_of(value_type c, | |
323 size_type pos = BasicStringPiece::npos) const { | |
324 return rfind(c, pos); | |
325 } | |
326 | |
327 // find_last_not_of: Find the last occurence not of a set of characters. | |
328 size_type find_last_not_of(const BasicStringPiece& s, | |
329 size_type pos = BasicStringPiece::npos) const { | |
330 return internal::find_last_not_of(*this, s, pos); | |
331 } | |
332 size_type find_last_not_of(value_type c, | |
333 size_type pos = BasicStringPiece::npos) const { | |
334 return internal::find_last_not_of(*this, c, pos); | |
335 } | |
336 | |
337 // substr. | |
338 BasicStringPiece substr(size_type pos, | |
339 size_type n = BasicStringPiece::npos) const { | |
340 return internal::substr(*this, pos, n); | |
341 } | |
342 | |
343 protected: | 144 protected: |
344 const value_type* ptr_; | 145 const value_type* ptr_; |
345 size_type length_; | 146 size_type length_; |
346 }; | 147 }; |
347 | 148 |
348 template <typename STRING_TYPE> | 149 template <typename STRING_TYPE> |
349 const typename BasicStringPiece<STRING_TYPE>::size_type | 150 const typename StringPieceDetail<STRING_TYPE>::size_type |
350 BasicStringPiece<STRING_TYPE>::npos = | 151 StringPieceDetail<STRING_TYPE>::npos = |
351 typename BasicStringPiece<STRING_TYPE>::size_type(-1); | 152 typename StringPieceDetail<STRING_TYPE>::size_type(-1); |
352 | 153 |
353 // MSVC doesn't like complex extern templates and DLLs. | 154 // MSVC doesn't like complex extern templates and DLLs. |
354 #if !defined(COMPILER_MSVC) | 155 #if !defined(COMPILER_MSVC) |
355 extern template class BASE_EXPORT BasicStringPiece<std::string>; | 156 extern template class BASE_EXPORT StringPieceDetail<std::string>; |
| 157 extern template class BASE_EXPORT StringPieceDetail<string16>; |
| 158 #endif |
| 159 |
| 160 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); |
| 161 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); |
| 162 BASE_EXPORT StringPieceDetail<std::string>::size_type copy( |
| 163 const StringPiece& self, |
| 164 char* buf, |
| 165 StringPieceDetail<std::string>::size_type n, |
| 166 StringPieceDetail<std::string>::size_type pos); |
| 167 BASE_EXPORT StringPieceDetail<std::string>::size_type find( |
| 168 const StringPiece& self, |
| 169 const StringPiece& s, |
| 170 StringPieceDetail<std::string>::size_type pos); |
| 171 BASE_EXPORT StringPieceDetail<std::string>::size_type find( |
| 172 const StringPiece& self, |
| 173 char c, |
| 174 StringPieceDetail<std::string>::size_type pos); |
| 175 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( |
| 176 const StringPiece& self, |
| 177 const StringPiece& s, |
| 178 StringPieceDetail<std::string>::size_type pos); |
| 179 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( |
| 180 const StringPiece& self, |
| 181 char c, |
| 182 StringPieceDetail<std::string>::size_type pos); |
| 183 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of( |
| 184 const StringPiece& self, |
| 185 const StringPiece& s, |
| 186 StringPieceDetail<std::string>::size_type pos); |
| 187 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( |
| 188 const StringPiece& self, |
| 189 const StringPiece& s, |
| 190 StringPieceDetail<std::string>::size_type pos); |
| 191 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( |
| 192 const StringPiece& self, |
| 193 char c, |
| 194 StringPieceDetail<std::string>::size_type pos); |
| 195 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( |
| 196 const StringPiece& self, |
| 197 const StringPiece& s, |
| 198 StringPieceDetail<std::string>::size_type pos); |
| 199 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( |
| 200 const StringPiece& self, |
| 201 char c, |
| 202 StringPieceDetail<std::string>::size_type pos); |
| 203 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( |
| 204 const StringPiece& self, |
| 205 const StringPiece& s, |
| 206 StringPieceDetail<std::string>::size_type pos); |
| 207 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( |
| 208 const StringPiece& self, |
| 209 char c, |
| 210 StringPieceDetail<std::string>::size_type pos); |
| 211 BASE_EXPORT StringPiece substr(const StringPiece& self, |
| 212 StringPieceDetail<std::string>::size_type pos, |
| 213 StringPieceDetail<std::string>::size_type n); |
| 214 } // namespace internal |
| 215 |
| 216 // Defines the template type that is instantiated as either StringPiece or |
| 217 // StringPiece16. |
| 218 template <typename STRING_TYPE> class BasicStringPiece : |
| 219 public internal::StringPieceDetail<STRING_TYPE> { |
| 220 public: |
| 221 typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type |
| 222 value_type; |
| 223 typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type |
| 224 size_type; |
| 225 |
| 226 BasicStringPiece() {} |
| 227 BasicStringPiece(const value_type*str) |
| 228 : internal::StringPieceDetail<STRING_TYPE>(str) {} |
| 229 BasicStringPiece(const STRING_TYPE& str) |
| 230 : internal::StringPieceDetail<STRING_TYPE>(str) {} |
| 231 BasicStringPiece(const value_type* offset, size_type len) |
| 232 : internal::StringPieceDetail<STRING_TYPE>(offset, len) {} |
| 233 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, |
| 234 const typename STRING_TYPE::const_iterator& end) |
| 235 : internal::StringPieceDetail<STRING_TYPE>(begin, end) {} |
| 236 }; |
| 237 |
| 238 // Specializes BasicStringPiece for std::string to add a few operations that |
| 239 // are not needed for string16. |
| 240 template <> class BasicStringPiece<std::string> : |
| 241 public internal::StringPieceDetail<std::string> { |
| 242 public: |
| 243 BasicStringPiece() {} |
| 244 BasicStringPiece(const char* str) |
| 245 : internal::StringPieceDetail<std::string>(str) {} |
| 246 BasicStringPiece(const std::string& str) |
| 247 : internal::StringPieceDetail<std::string>(str) {} |
| 248 BasicStringPiece(const char* offset, size_type len) |
| 249 : internal::StringPieceDetail<std::string>(offset, len) {} |
| 250 BasicStringPiece(const std::string::const_iterator& begin, |
| 251 const std::string::const_iterator& end) |
| 252 : internal::StringPieceDetail<std::string>(begin, end) {} |
| 253 |
| 254 // Prevent the following overload of set() from hiding the definitions in the |
| 255 // base class. |
| 256 using internal::StringPieceDetail<std::string>::set; |
| 257 |
| 258 void set(const void* data, size_type len) { |
| 259 ptr_ = reinterpret_cast<const value_type*>(data); |
| 260 length_ = len; |
| 261 } |
| 262 |
| 263 void CopyToString(std::string* target) const { |
| 264 internal::CopyToString(*this, target); |
| 265 } |
| 266 |
| 267 void AppendToString(std::string* target) const { |
| 268 internal::AppendToString(*this, target); |
| 269 } |
| 270 |
| 271 // Does "this" start with "x" |
| 272 bool starts_with(const BasicStringPiece& x) const { |
| 273 return ((length_ >= x.length_) && |
| 274 (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); |
| 275 } |
| 276 |
| 277 // Does "this" end with "x" |
| 278 bool ends_with(const BasicStringPiece& x) const { |
| 279 return ((length_ >= x.length_) && |
| 280 (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); |
| 281 } |
| 282 |
| 283 size_type copy(char* buf, size_type n, size_type pos = 0) const { |
| 284 return internal::copy(*this, buf, n, pos); |
| 285 } |
| 286 |
| 287 size_type find(const BasicStringPiece& s, size_type pos = 0) const { |
| 288 return internal::find(*this, s, pos); |
| 289 } |
| 290 |
| 291 size_type find(char c, size_type pos = 0) const { |
| 292 return internal::find(*this, c, pos); |
| 293 } |
| 294 |
| 295 size_type rfind(const BasicStringPiece& s, size_type pos = npos) const { |
| 296 return internal::rfind(*this, s, pos); |
| 297 } |
| 298 |
| 299 size_type rfind(char c, size_type pos = npos) const { |
| 300 return internal::rfind(*this, c, pos); |
| 301 } |
| 302 |
| 303 size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const { |
| 304 return internal::find_first_of(*this, s, pos); |
| 305 } |
| 306 |
| 307 size_type find_first_of(char c, size_type pos = 0) const { |
| 308 return find(c, pos); |
| 309 } |
| 310 |
| 311 size_type find_first_not_of(const BasicStringPiece& s, |
| 312 size_type pos = 0) const { |
| 313 return internal::find_first_not_of(*this, s, pos); |
| 314 } |
| 315 |
| 316 size_type find_first_not_of(char c, size_type pos = 0) const { |
| 317 return internal::find_first_not_of(*this, c, pos); |
| 318 } |
| 319 |
| 320 size_type find_last_of(const BasicStringPiece& s, |
| 321 size_type pos = npos) const { |
| 322 return internal::find_last_of(*this, s, pos); |
| 323 } |
| 324 |
| 325 size_type find_last_of(char c, size_type pos = npos) const { |
| 326 return rfind(c, pos); |
| 327 } |
| 328 |
| 329 size_type find_last_not_of(const BasicStringPiece& s, |
| 330 size_type pos = npos) const { |
| 331 return internal::find_last_not_of(*this, s, pos); |
| 332 } |
| 333 |
| 334 size_type find_last_not_of(char c, size_type pos = npos) const { |
| 335 return internal::find_last_not_of(*this, c, pos); |
| 336 } |
| 337 |
| 338 BasicStringPiece substr(size_type pos, size_type n = npos) const { |
| 339 return internal::substr(*this, pos, n); |
| 340 } |
| 341 }; |
| 342 |
| 343 // MSVC doesn't like complex extern templates and DLLs. |
| 344 #if !defined(COMPILER_MSVC) |
| 345 // We can't explicitly declare the std::string instantiation here because it was |
| 346 // already instantiated when specialized, above. Not only is it a no-op, but |
| 347 // currently it also crashes Clang (see http://crbug.com/107412). |
356 extern template class BASE_EXPORT BasicStringPiece<string16>; | 348 extern template class BASE_EXPORT BasicStringPiece<string16>; |
357 #endif | 349 #endif |
358 | 350 |
359 // StingPiece operators -------------------------------------------------------- | |
360 | |
361 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); | 351 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); |
362 | 352 |
363 inline bool operator!=(const StringPiece& x, const StringPiece& y) { | 353 inline bool operator!=(const StringPiece& x, const StringPiece& y) { |
364 return !(x == y); | 354 return !(x == y); |
365 } | 355 } |
366 | 356 |
367 inline bool operator<(const StringPiece& x, const StringPiece& y) { | 357 inline bool operator<(const StringPiece& x, const StringPiece& y) { |
368 const int r = StringPiece::wordmemcmp( | 358 const int r = StringPiece::wordmemcmp( |
369 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); | 359 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); |
370 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); | 360 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); |
371 } | 361 } |
372 | 362 |
373 inline bool operator>(const StringPiece& x, const StringPiece& y) { | 363 inline bool operator>(const StringPiece& x, const StringPiece& y) { |
374 return y < x; | 364 return y < x; |
375 } | 365 } |
376 | 366 |
377 inline bool operator<=(const StringPiece& x, const StringPiece& y) { | 367 inline bool operator<=(const StringPiece& x, const StringPiece& y) { |
378 return !(x > y); | 368 return !(x > y); |
379 } | 369 } |
380 | 370 |
381 inline bool operator>=(const StringPiece& x, const StringPiece& y) { | 371 inline bool operator>=(const StringPiece& x, const StringPiece& y) { |
382 return !(x < y); | 372 return !(x < y); |
383 } | 373 } |
384 | 374 |
385 // StringPiece16 operators ----------------------------------------------------- | |
386 | |
387 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { | 375 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { |
388 if (x.size() != y.size()) | 376 if (x.size() != y.size()) |
389 return false; | 377 return false; |
390 | 378 |
391 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; | 379 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; |
392 } | 380 } |
393 | 381 |
394 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { | 382 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { |
395 return !(x == y); | 383 return !(x == y); |
396 } | 384 } |
(...skipping 14 matching lines...) Expand all Loading... |
411 | 399 |
412 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { | 400 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { |
413 return !(x < y); | 401 return !(x < y); |
414 } | 402 } |
415 | 403 |
416 BASE_EXPORT std::ostream& operator<<(std::ostream& o, | 404 BASE_EXPORT std::ostream& operator<<(std::ostream& o, |
417 const StringPiece& piece); | 405 const StringPiece& piece); |
418 | 406 |
419 } // namespace base | 407 } // namespace base |
420 | 408 |
421 // Hashing --------------------------------------------------------------------- | |
422 | |
423 // We provide appropriate hash functions so StringPiece and StringPiece16 can | 409 // We provide appropriate hash functions so StringPiece and StringPiece16 can |
424 // be used as keys in hash sets and maps. | 410 // be used as keys in hash sets and maps. |
425 | 411 |
426 // This hash function is copied from base/containers/hash_tables.h. We don't | 412 // This hash function is copied from base/containers/hash_tables.h. We don't |
427 // use the ones already defined for string and string16 directly because it | 413 // use the ones already defined for string and string16 directly because it |
428 // would require the string constructors to be called, which we don't want. | 414 // would require the string constructors to be called, which we don't want. |
429 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ | 415 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ |
430 std::size_t result = 0; \ | 416 std::size_t result = 0; \ |
431 for (StringPieceType::const_iterator i = string_piece.begin(); \ | 417 for (StringPieceType::const_iterator i = string_piece.begin(); \ |
432 i != string_piece.end(); ++i) \ | 418 i != string_piece.end(); ++i) \ |
(...skipping 23 matching lines...) Expand all Loading... |
456 } | 442 } |
457 inline size_t hash_value(const base::StringPiece16& sp16) { | 443 inline size_t hash_value(const base::StringPiece16& sp16) { |
458 HASH_STRING_PIECE(base::StringPiece16, sp16); | 444 HASH_STRING_PIECE(base::StringPiece16, sp16); |
459 } | 445 } |
460 | 446 |
461 #endif // COMPILER | 447 #endif // COMPILER |
462 | 448 |
463 } // namespace BASE_HASH_NAMESPACE | 449 } // namespace BASE_HASH_NAMESPACE |
464 | 450 |
465 #endif // BASE_STRINGS_STRING_PIECE_H_ | 451 #endif // BASE_STRINGS_STRING_PIECE_H_ |
OLD | NEW |