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 17 namespace android { 18 namespace base { 19 20 class 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 // 63 class StringView { 64 public: 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 122 private: 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 130 bool operator==(const StringView& x, const StringView& y); 131 132 inline bool operator!=(const StringView& x, const StringView& y) { 133 return !(x == y); 134 } 135 136 inline bool operator<(const StringView& x, const StringView& y) { 137 return x.compare(y) < 0; 138 } 139 140 inline bool operator>=(const StringView& x, const StringView& y) { 141 return !(x < y); 142 } 143 144 inline bool operator >(const StringView& x, const StringView& y) { 145 return x.compare(y) > 0; 146 } 147 148 inline 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