OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 15 matching lines...) Expand all Loading... |
26 | 26 |
27 #include <string> | 27 #include <string> |
28 | 28 |
29 #include "base/base_export.h" | 29 #include "base/base_export.h" |
30 #include "base/basictypes.h" | 30 #include "base/basictypes.h" |
31 #include "base/hash_tables.h" | 31 #include "base/hash_tables.h" |
32 #include "base/string16.h" | 32 #include "base/string16.h" |
33 | 33 |
34 namespace base { | 34 namespace base { |
35 | 35 |
36 class BASE_EXPORT StringPiece { | 36 template <typename STRING_TYPE> class BasicStringPiece; |
| 37 typedef BasicStringPiece<std::string> StringPiece; |
| 38 typedef BasicStringPiece<string16> StringPiece16; |
| 39 |
| 40 namespace internal { |
| 41 |
| 42 // Defines the types, methods, operators, and data members common to both |
| 43 // StringPiece and StringPiece16. Do not refer to this class directly, but |
| 44 // rather to BasicStringPiece, StringPiece, or StringPiece16. |
| 45 template <typename STRING_TYPE> class StringPieceDetail { |
37 public: | 46 public: |
38 // standard STL container boilerplate | 47 // standard STL container boilerplate |
39 typedef size_t size_type; | 48 typedef size_t size_type; |
40 typedef char value_type; | 49 typedef typename STRING_TYPE::value_type value_type; |
41 typedef const char* pointer; | 50 typedef const value_type* pointer; |
42 typedef const char& reference; | 51 typedef const value_type& reference; |
43 typedef const char& const_reference; | 52 typedef const value_type& const_reference; |
44 typedef ptrdiff_t difference_type; | 53 typedef ptrdiff_t difference_type; |
45 typedef const char* const_iterator; | 54 typedef const value_type* const_iterator; |
46 typedef const char* iterator; | |
47 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 55 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
48 typedef std::reverse_iterator<iterator> reverse_iterator; | |
49 | 56 |
50 static const size_type npos; | 57 static const size_type npos; |
51 | 58 |
52 public: | 59 public: |
53 // We provide non-explicit singleton constructors so users can pass | 60 // We provide non-explicit singleton constructors so users can pass |
54 // in a "const char*" or a "string" wherever a "StringPiece" is | 61 // in a "const char*" or a "string" wherever a "StringPiece" is |
55 // expected. | 62 // expected (likewise for char16, string16, StringPiece16). |
56 StringPiece() : ptr_(NULL), length_(0) { } | 63 StringPieceDetail() : ptr_(NULL), length_(0) {} |
57 StringPiece(const char* str) | 64 StringPieceDetail(const value_type* str) |
58 : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { } | 65 : ptr_(str), |
59 StringPiece(const std::string& str) | 66 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} |
60 : ptr_(str.data()), length_(str.size()) { } | 67 StringPieceDetail(const STRING_TYPE& str) |
61 StringPiece(const char* offset, size_type len) | 68 : ptr_(str.data()), length_(str.size()) {} |
62 : ptr_(offset), length_(len) { } | 69 StringPieceDetail(const value_type* offset, size_type len) |
63 StringPiece(const std::string::const_iterator& begin, | 70 : ptr_(offset), length_(len) {} |
64 const std::string::const_iterator& end) | 71 StringPieceDetail(const typename STRING_TYPE::const_iterator& begin, |
65 : ptr_((end > begin) ? &(*begin) : NULL), | 72 const typename STRING_TYPE::const_iterator& end) |
66 length_((end > begin) ? (size_type)(end - begin) : 0) { } | 73 : ptr_((end > begin) ? &(*begin) : NULL), |
| 74 length_((end > begin) ? (size_type)(end - begin) : 0) {} |
67 | 75 |
68 // data() may return a pointer to a buffer with embedded NULs, and the | 76 // data() may return a pointer to a buffer with embedded NULs, and the |
69 // returned buffer may or may not be null terminated. Therefore it is | 77 // returned buffer may or may not be null terminated. Therefore it is |
70 // typically a mistake to pass data() to a routine that expects a NUL | 78 // typically a mistake to pass data() to a routine that expects a NUL |
71 // terminated string. | 79 // terminated string. |
72 const char* data() const { return ptr_; } | 80 const value_type* data() const { return ptr_; } |
73 size_type size() const { return length_; } | 81 size_type size() const { return length_; } |
74 size_type length() const { return length_; } | 82 size_type length() const { return length_; } |
75 bool empty() const { return length_ == 0; } | 83 bool empty() const { return length_ == 0; } |
76 | 84 |
77 void clear() { | 85 void clear() { |
78 ptr_ = NULL; | 86 ptr_ = NULL; |
79 length_ = 0; | 87 length_ = 0; |
80 } | 88 } |
81 void set(const char* data, size_type len) { | 89 void set(const value_type* data, size_type len) { |
82 ptr_ = data; | 90 ptr_ = data; |
83 length_ = len; | 91 length_ = len; |
84 } | 92 } |
85 void set(const char* str) { | 93 void set(const value_type* str) { |
86 ptr_ = str; | 94 ptr_ = str; |
87 length_ = str ? strlen(str) : 0; | 95 length_ = str ? STRING_TYPE::traits_type::length(str) : 0; |
88 } | |
89 void set(const void* data, size_type len) { | |
90 ptr_ = reinterpret_cast<const char*>(data); | |
91 length_ = len; | |
92 } | 96 } |
93 | 97 |
94 char operator[](size_type i) const { return ptr_[i]; } | 98 value_type operator[](size_type i) const { return ptr_[i]; } |
95 | 99 |
96 void remove_prefix(size_type n) { | 100 void remove_prefix(size_type n) { |
97 ptr_ += n; | 101 ptr_ += n; |
98 length_ -= n; | 102 length_ -= n; |
99 } | 103 } |
100 | 104 |
101 void remove_suffix(size_type n) { | 105 void remove_suffix(size_type n) { |
102 length_ -= n; | 106 length_ -= n; |
103 } | 107 } |
104 | 108 |
105 int compare(const StringPiece& x) const { | 109 int compare(const BasicStringPiece<STRING_TYPE>& x) const { |
106 int r = wordmemcmp( | 110 int r = wordmemcmp( |
107 ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); | 111 ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); |
108 if (r == 0) { | 112 if (r == 0) { |
109 if (length_ < x.length_) r = -1; | 113 if (length_ < x.length_) r = -1; |
110 else if (length_ > x.length_) r = +1; | 114 else if (length_ > x.length_) r = +1; |
111 } | 115 } |
112 return r; | 116 return r; |
113 } | 117 } |
114 | 118 |
115 std::string as_string() const { | 119 STRING_TYPE as_string() const { |
116 // std::string doesn't like to take a NULL pointer even with a 0 size. | 120 // std::string doesn't like to take a NULL pointer even with a 0 size. |
117 return std::string(!empty() ? data() : "", size()); | 121 return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); |
118 } | 122 } |
119 | 123 |
120 void CopyToString(std::string* target) const; | 124 const_iterator begin() const { return ptr_; } |
121 void AppendToString(std::string* target) const; | 125 const_iterator end() const { return ptr_ + length_; } |
122 | |
123 // Does "this" start with "x" | |
124 bool starts_with(const StringPiece& x) const { | |
125 return ((length_ >= x.length_) && | |
126 (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); | |
127 } | |
128 | |
129 // Does "this" end with "x" | |
130 bool ends_with(const StringPiece& x) const { | |
131 return ((length_ >= x.length_) && | |
132 (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); | |
133 } | |
134 | |
135 iterator begin() const { return ptr_; } | |
136 iterator end() const { return ptr_ + length_; } | |
137 const_reverse_iterator rbegin() const { | 126 const_reverse_iterator rbegin() const { |
138 return const_reverse_iterator(ptr_ + length_); | 127 return const_reverse_iterator(ptr_ + length_); |
139 } | 128 } |
140 const_reverse_iterator rend() const { | 129 const_reverse_iterator rend() const { |
141 return const_reverse_iterator(ptr_); | 130 return const_reverse_iterator(ptr_); |
142 } | 131 } |
143 | 132 |
144 size_type max_size() const { return length_; } | 133 size_type max_size() const { return length_; } |
145 size_type capacity() const { return length_; } | 134 size_type capacity() const { return length_; } |
146 | 135 |
147 size_type copy(char* buf, size_type n, size_type pos = 0) const; | 136 static int wordmemcmp(const value_type* p, |
148 | 137 const value_type* p2, |
149 size_type find(const StringPiece& s, size_type pos = 0) const; | 138 size_type N) { |
150 size_type find(char c, size_type pos = 0) const; | 139 return STRING_TYPE::traits_type::compare(p, p2, N); |
151 size_type rfind(const StringPiece& s, size_type pos = npos) const; | 140 } |
152 size_type rfind(char c, size_type pos = npos) const; | 141 |
153 | 142 protected: |
154 size_type find_first_of(const StringPiece& s, size_type pos = 0) const; | 143 const value_type* ptr_; |
| 144 size_type length_; |
| 145 }; |
| 146 |
| 147 template <typename STRING_TYPE> |
| 148 const typename StringPieceDetail<STRING_TYPE>::size_type |
| 149 StringPieceDetail<STRING_TYPE>::npos = |
| 150 typename StringPieceDetail<STRING_TYPE>::size_type(-1); |
| 151 |
| 152 // MSVC doesn't like complex extern templates and DLLs. |
| 153 #if !defined(COMPILER_MSVC) |
| 154 extern template class BASE_EXPORT StringPieceDetail<std::string>; |
| 155 extern template class BASE_EXPORT StringPieceDetail<string16>; |
| 156 #endif |
| 157 |
| 158 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); |
| 159 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); |
| 160 BASE_EXPORT StringPieceDetail<std::string>::size_type copy( |
| 161 const StringPiece& self, |
| 162 char* buf, |
| 163 StringPieceDetail<std::string>::size_type n, |
| 164 StringPieceDetail<std::string>::size_type pos); |
| 165 BASE_EXPORT StringPieceDetail<std::string>::size_type find( |
| 166 const StringPiece& self, |
| 167 const StringPiece& s, |
| 168 StringPieceDetail<std::string>::size_type pos); |
| 169 BASE_EXPORT StringPieceDetail<std::string>::size_type find( |
| 170 const StringPiece& self, |
| 171 char c, |
| 172 StringPieceDetail<std::string>::size_type pos); |
| 173 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( |
| 174 const StringPiece& self, |
| 175 const StringPiece& s, |
| 176 StringPieceDetail<std::string>::size_type pos); |
| 177 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( |
| 178 const StringPiece& self, |
| 179 char c, |
| 180 StringPieceDetail<std::string>::size_type pos); |
| 181 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of( |
| 182 const StringPiece& self, |
| 183 const StringPiece& s, |
| 184 StringPieceDetail<std::string>::size_type pos); |
| 185 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( |
| 186 const StringPiece& self, |
| 187 const StringPiece& s, |
| 188 StringPieceDetail<std::string>::size_type pos); |
| 189 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( |
| 190 const StringPiece& self, |
| 191 char c, |
| 192 StringPieceDetail<std::string>::size_type pos); |
| 193 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( |
| 194 const StringPiece& self, |
| 195 const StringPiece& s, |
| 196 StringPieceDetail<std::string>::size_type pos); |
| 197 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( |
| 198 const StringPiece& self, |
| 199 char c, |
| 200 StringPieceDetail<std::string>::size_type pos); |
| 201 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( |
| 202 const StringPiece& self, |
| 203 const StringPiece& s, |
| 204 StringPieceDetail<std::string>::size_type pos); |
| 205 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( |
| 206 const StringPiece& self, |
| 207 char c, |
| 208 StringPieceDetail<std::string>::size_type pos); |
| 209 BASE_EXPORT StringPiece substr(const StringPiece& self, |
| 210 StringPieceDetail<std::string>::size_type pos, |
| 211 StringPieceDetail<std::string>::size_type n); |
| 212 } // namespace internal |
| 213 |
| 214 // Defines the template type that is instantiated as either StringPiece or |
| 215 // StringPiece16. |
| 216 template <typename STRING_TYPE> class BasicStringPiece : |
| 217 public internal::StringPieceDetail<STRING_TYPE> { |
| 218 public: |
| 219 typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type |
| 220 value_type; |
| 221 typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type |
| 222 size_type; |
| 223 |
| 224 BasicStringPiece() {} |
| 225 BasicStringPiece(const value_type*str) |
| 226 : internal::StringPieceDetail<STRING_TYPE>(str) {} |
| 227 BasicStringPiece(const STRING_TYPE& str) |
| 228 : internal::StringPieceDetail<STRING_TYPE>(str) {} |
| 229 BasicStringPiece(const value_type* offset, size_type len) |
| 230 : internal::StringPieceDetail<STRING_TYPE>(offset, len) {} |
| 231 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, |
| 232 const typename STRING_TYPE::const_iterator& end) |
| 233 : internal::StringPieceDetail<STRING_TYPE>(begin, end) {} |
| 234 }; |
| 235 |
| 236 // Specializes BasicStringPiece for std::string to add a few operations that |
| 237 // are not needed for string16. |
| 238 template <> class BasicStringPiece<std::string> : |
| 239 public internal::StringPieceDetail<std::string> { |
| 240 public: |
| 241 BasicStringPiece() {} |
| 242 BasicStringPiece(const char* str) |
| 243 : internal::StringPieceDetail<std::string>(str) {} |
| 244 BasicStringPiece(const std::string& str) |
| 245 : internal::StringPieceDetail<std::string>(str) {} |
| 246 BasicStringPiece(const char* offset, size_type len) |
| 247 : internal::StringPieceDetail<std::string>(offset, len) {} |
| 248 BasicStringPiece(const std::string::const_iterator& begin, |
| 249 const std::string::const_iterator& end) |
| 250 : internal::StringPieceDetail<std::string>(begin, end) {} |
| 251 |
| 252 // Prevent the following overload of set() from hiding the definitions in the |
| 253 // base class. |
| 254 using internal::StringPieceDetail<std::string>::set; |
| 255 |
| 256 void set(const void* data, size_type len) { |
| 257 ptr_ = reinterpret_cast<const value_type*>(data); |
| 258 length_ = len; |
| 259 } |
| 260 |
| 261 void CopyToString(std::string* target) const { |
| 262 internal::CopyToString(*this, target); |
| 263 } |
| 264 |
| 265 void AppendToString(std::string* target) const { |
| 266 internal::AppendToString(*this, target); |
| 267 } |
| 268 |
| 269 // Does "this" start with "x" |
| 270 bool starts_with(const BasicStringPiece& x) const { |
| 271 return ((length_ >= x.length_) && |
| 272 (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); |
| 273 } |
| 274 |
| 275 // Does "this" end with "x" |
| 276 bool ends_with(const BasicStringPiece& x) const { |
| 277 return ((length_ >= x.length_) && |
| 278 (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); |
| 279 } |
| 280 |
| 281 size_type copy(char* buf, size_type n, size_type pos = 0) const { |
| 282 return internal::copy(*this, buf, n, pos); |
| 283 } |
| 284 |
| 285 size_type find(const BasicStringPiece& s, size_type pos = 0) const { |
| 286 return internal::find(*this, s, pos); |
| 287 } |
| 288 |
| 289 size_type find(char c, size_type pos = 0) const { |
| 290 return internal::find(*this, c, pos); |
| 291 } |
| 292 |
| 293 size_type rfind(const BasicStringPiece& s, size_type pos = npos) const { |
| 294 return internal::rfind(*this, s, pos); |
| 295 } |
| 296 |
| 297 size_type rfind(char c, size_type pos = npos) const { |
| 298 return internal::rfind(*this, c, pos); |
| 299 } |
| 300 |
| 301 size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const { |
| 302 return internal::find_first_of(*this, s, pos); |
| 303 } |
| 304 |
155 size_type find_first_of(char c, size_type pos = 0) const { | 305 size_type find_first_of(char c, size_type pos = 0) const { |
156 return find(c, pos); | 306 return find(c, pos); |
157 } | 307 } |
158 size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const; | 308 |
159 size_type find_first_not_of(char c, size_type pos = 0) const; | 309 size_type find_first_not_of(const BasicStringPiece& s, |
160 size_type find_last_of(const StringPiece& s, size_type pos = npos) const; | 310 size_type pos = 0) const { |
| 311 return internal::find_first_not_of(*this, s, pos); |
| 312 } |
| 313 |
| 314 size_type find_first_not_of(char c, size_type pos = 0) const { |
| 315 return internal::find_first_not_of(*this, c, pos); |
| 316 } |
| 317 |
| 318 size_type find_last_of(const BasicStringPiece& s, |
| 319 size_type pos = npos) const { |
| 320 return internal::find_last_of(*this, s, pos); |
| 321 } |
| 322 |
161 size_type find_last_of(char c, size_type pos = npos) const { | 323 size_type find_last_of(char c, size_type pos = npos) const { |
162 return rfind(c, pos); | 324 return rfind(c, pos); |
163 } | 325 } |
164 size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const; | 326 |
165 size_type find_last_not_of(char c, size_type pos = npos) const; | 327 size_type find_last_not_of(const BasicStringPiece& s, |
166 | 328 size_type pos = npos) const { |
167 StringPiece substr(size_type pos, size_type n = npos) const; | 329 return internal::find_last_not_of(*this, s, pos); |
168 | 330 } |
169 static int wordmemcmp(const char* p, const char* p2, size_type N) { | 331 |
170 return memcmp(p, p2, N); | 332 size_type find_last_not_of(char c, size_type pos = npos) const { |
171 } | 333 return internal::find_last_not_of(*this, c, pos); |
172 | 334 } |
173 private: | 335 |
174 const char* ptr_; | 336 BasicStringPiece substr(size_type pos, size_type n = npos) const { |
175 size_type length_; | 337 return internal::substr(*this, pos, n); |
| 338 } |
176 }; | 339 }; |
177 | 340 |
178 class BASE_EXPORT StringPiece16 { | 341 // MSVC doesn't like complex extern templates and DLLs. |
179 public: | 342 #if !defined(COMPILER_MSVC) |
180 // standard STL container boilerplate | 343 // We can't explicitly declare the std::string instantiation here because it was |
181 typedef size_t size_type; | 344 // already instantiated when specialized, above. Not only is it a no-op, but |
182 typedef char16 value_type; | 345 // currently it also crashes Clang (see http://crbug.com/107412). |
183 typedef const char16* pointer; | 346 extern template class BASE_EXPORT BasicStringPiece<string16>; |
184 typedef const char16& reference; | 347 #endif |
185 typedef const char16& const_reference; | |
186 typedef ptrdiff_t difference_type; | |
187 typedef const char16* const_iterator; | |
188 typedef const char16* iterator; | |
189 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
190 typedef std::reverse_iterator<iterator> reverse_iterator; | |
191 | |
192 public: | |
193 // We provide non-explicit singleton constructors so users can pass | |
194 // in a "const char16*" or a "string16" wherever a "StringPiece16" is | |
195 // expected. | |
196 StringPiece16() : ptr_(NULL), length_(0) { } | |
197 StringPiece16(const char16* str) | |
198 : ptr_(str), | |
199 length_((str == NULL) ? 0 : string16::traits_type::length(str)) { } | |
200 StringPiece16(const string16& str) | |
201 : ptr_(str.data()), length_(str.size()) { } | |
202 StringPiece16(const char16* offset, size_type len) | |
203 : ptr_(offset), length_(len) { } | |
204 StringPiece16(const string16::const_iterator& begin, | |
205 const string16::const_iterator& end) | |
206 : ptr_((end > begin) ? &(*begin) : NULL), | |
207 length_((end > begin) ? (size_type)(end - begin) : 0) { } | |
208 | |
209 // data() may return a pointer to a buffer with embedded NULs, and the | |
210 // returned buffer may or may not be null terminated. Therefore it is | |
211 // typically a mistake to pass data() to a routine that expects a NUL | |
212 // terminated string. | |
213 const char16* data() const { return ptr_; } | |
214 size_type size() const { return length_; } | |
215 size_type length() const { return length_; } | |
216 bool empty() const { return length_ == 0; } | |
217 | |
218 void clear() { | |
219 ptr_ = NULL; | |
220 length_ = 0; | |
221 } | |
222 void set(const char16* data, size_type len) { | |
223 ptr_ = data; | |
224 length_ = len; | |
225 } | |
226 void set(const char16* str) { | |
227 ptr_ = str; | |
228 length_ = str ? string16::traits_type::length(str) : 0; | |
229 } | |
230 | |
231 char16 operator[](size_type i) const { return ptr_[i]; } | |
232 | |
233 string16 as_string16() const { | |
234 // StringPiece claims that this is bad when data() is NULL, but unittesting | |
235 // seems to say otherwise. | |
236 return string16(data(), size()); | |
237 } | |
238 | |
239 iterator begin() const { return ptr_; } | |
240 iterator end() const { return ptr_ + length_; } | |
241 const_reverse_iterator rbegin() const { | |
242 return const_reverse_iterator(ptr_ + length_); | |
243 } | |
244 const_reverse_iterator rend() const { | |
245 return const_reverse_iterator(ptr_); | |
246 } | |
247 | |
248 size_type max_size() const { return length_; } | |
249 size_type capacity() const { return length_; } | |
250 | |
251 static int wordmemcmp(const char16* p, const char16* p2, size_type N) { | |
252 return string16::traits_type::compare(p, p2, N); | |
253 } | |
254 | |
255 private: | |
256 const char16* ptr_; | |
257 size_type length_; | |
258 }; | |
259 | 348 |
260 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); | 349 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); |
261 | 350 |
262 inline bool operator!=(const StringPiece& x, const StringPiece& y) { | 351 inline bool operator!=(const StringPiece& x, const StringPiece& y) { |
263 return !(x == y); | 352 return !(x == y); |
264 } | 353 } |
265 | 354 |
266 inline bool operator<(const StringPiece& x, const StringPiece& y) { | 355 inline bool operator<(const StringPiece& x, const StringPiece& y) { |
267 const int r = StringPiece::wordmemcmp( | 356 const int r = StringPiece::wordmemcmp( |
268 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); | 357 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 } | 437 } |
349 inline size_t hash_value(const base::StringPiece16& sp16) { | 438 inline size_t hash_value(const base::StringPiece16& sp16) { |
350 HASH_STRING_PIECE(base::StringPiece16, sp16); | 439 HASH_STRING_PIECE(base::StringPiece16, sp16); |
351 } | 440 } |
352 | 441 |
353 #endif // COMPILER | 442 #endif // COMPILER |
354 | 443 |
355 } // namespace BASE_HASH_NAMESPACE | 444 } // namespace BASE_HASH_NAMESPACE |
356 | 445 |
357 #endif // BASE_STRING_PIECE_H_ | 446 #endif // BASE_STRING_PIECE_H_ |
OLD | NEW |