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