1// Copyright 2014 The Android Open Source Project 2// 3// This software is licensed under the terms of the GNU General Public 4// License version 2, as published by the Free Software Foundation, and 5// may be copied, distributed, and modified under those terms. 6// 7// This program is distributed in the hope that it will be useful, 8// but WITHOUT ANY WARRANTY; without even the implied warranty of 9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10// GNU General Public License for more details. 11 12#ifndef ANDROID_BASE_STRING_VIEW_H 13#define ANDROID_BASE_STRING_VIEW_H 14 15#include <string.h> 16 17namespace android { 18namespace base { 19 20class String; 21 22// A StringView is a simple (address, size) pair that points to an 23// existing read-only string. It's a convenience class used to hidden 24// creation of String() objects un-necessarily. 25// 26// Consider the two following functions: 27// 28// size_t count1(const String& str) { 29// size_t result = 0; 30// for (size_t n = 0; n < str.size(); ++n) { 31// if (str[n] == '1') { 32// count++; 33// } 34// } 35// } 36// 37// size_t count2(const StringView& str) { 38// size_t result = 0; 39// for (size_t n = 0; n < str.size(); ++n) { 40// if (str[n] == '2') { 41// count++; 42// } 43// } 44// } 45// 46// Then consider the following calls: 47// 48// size_t n1 = count1("There is 1 one in this string!"); 49// size_t n2 = count2("I can count 2 too"); 50// 51// In the first case, the compiler will silently create a temporary 52// String object, copy the input string into it (allocating memory in 53// the heap), call count1() and destroy the String upon its return. 54// 55// In the second case, the compiler will create a temporary StringView, 56// initialize it trivially before calling count2(), this results in 57// much less generated code, as well as better performance. 58// 59// Generally speaking, always use a reference or pointer to StringView 60// instead of a String if your function or method doesn't need to modify 61// its input. 62// 63class StringView { 64public: 65 StringView() : mString(NULL), mSize(0U) {} 66 67 StringView(const StringView& other) : 68 mString(other.data()), mSize(other.size()) {} 69 70 // IMPORTANT: This is intentionally not 'explicit'. 71 StringView(const char* string) : 72 mString(string), mSize(strlen(string)) {} 73 74 explicit StringView(const String& str); 75 76 StringView(const char* str, size_t len) : mString(str), mSize(len) {} 77 78 const char* str() const { return mString; } 79 const char* data() const { return mString; } 80 size_t size() const { return mSize; } 81 82 typedef const char* iterator; 83 typedef const char* const_iterator; 84 85 const_iterator begin() const { return mString; } 86 const_iterator end() const { return mString + mSize; } 87 88 bool empty() const { return !size(); } 89 90 void clear() { 91 mSize = 0; 92 mString = NULL; 93 } 94 95 char operator[](size_t index) { 96 return mString[index]; 97 } 98 99 void set(const char* data, size_t len) { 100 mString = data; 101 mSize = len; 102 } 103 104 void set(const char* str) { 105 mString = str; 106 mSize = ::strlen(str); 107 } 108 109 void set(const StringView& other) { 110 mString = other.mString; 111 mSize = other.mSize; 112 } 113 114 // Compare with another StringView. 115 int compare(const StringView& other) const; 116 117 StringView& operator=(const StringView& other) { 118 set(other); 119 return *this; 120 } 121 122private: 123 const char* mString; 124 size_t mSize; 125}; 126 127// Comparison operators. Defined as functions to allow automatic type 128// conversions with C strings and String objects. 129 130bool operator==(const StringView& x, const StringView& y); 131 132inline bool operator!=(const StringView& x, const StringView& y) { 133 return !(x == y); 134} 135 136inline bool operator<(const StringView& x, const StringView& y) { 137 return x.compare(y) < 0; 138} 139 140inline bool operator>=(const StringView& x, const StringView& y) { 141 return !(x < y); 142} 143 144inline bool operator >(const StringView& x, const StringView& y) { 145 return x.compare(y) > 0; 146} 147 148inline bool operator<=(const StringView& x, const StringView& y) { 149 return !(x > y); 150} 151 152} // namespace base 153} // namespace android 154 155#endif // ANDROID_BASE_STRING_VIEW_H 156