1 /* -*- c++ -*- */ 2 /* 3 * Copyright (C) 2009 The Android Open Source Project 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef ANDROID_ASTL_STRING__ 31 #define ANDROID_ASTL_STRING__ 32 33 #include <algorithm> 34 #include <cstddef> 35 #include <iterator> 36 #include <char_traits.h> 37 38 namespace std { 39 40 class ostream; 41 42 // Simple string implementation. Its purpose is to be able to compile code that 43 // uses the STL and requires std::string. 44 // 45 // IMPORTANT: 46 // . This class it is not fully STL compliant. Some constructors/methods maybe 47 // missing, they will be added on demand. 48 // . We don't provide a std::basic_string template that std::string extends 49 // because we use only char (wchar is not supported on Android). 50 // . The memory allocation scheme uses the heap. Since Android has the concept 51 // of SharedBuffer, we may, in the future, templatize this class and add an 52 // allocation parameter. 53 // . The implementation is not optimized in any way (no copy on write support), 54 // temporary instance may be expensive. 55 // . Currently there is limited support for iterators. 56 // 57 58 class string 59 { 60 public: 61 typedef char_traits<char> traits_type; 62 typedef traits_type::char_type value_type; 63 typedef size_t size_type; 64 typedef ptrdiff_t difference_type; 65 typedef value_type& reference; 66 typedef const value_type& const_reference; 67 typedef value_type* pointer; 68 typedef const value_type* const_pointer; 69 typedef __wrapper_iterator<pointer,string> iterator; 70 typedef __wrapper_iterator<const_pointer,string> const_iterator; 71 72 static const size_type npos = static_cast<size_type>(-1); 73 74 // Constructors 75 string(); 76 77 string(const string& str); 78 79 // Construct a string from a source's substring. 80 // @param str The source string. 81 // @param pos The index of the character to start the copy at. 82 // @param n The number of characters to copy. Use string::npos for the 83 // remainder. 84 string(const string& str, size_t pos, size_type n); 85 86 // Same as above but implicitly copy from pos to the end of the str. 87 string(const string& str, size_type pos); 88 89 // Construct a string from a C string. 90 // @param str The source string, must be '\0' terminated. 91 string(const value_type *str); 92 93 // Construct a string from a char array. 94 // @param str The source C string. '\0' are ignored. 95 // @param n The number of characters to copy. 96 string(const value_type *str, size_type n); 97 98 // Construct a string from a repetition of a character. 99 // @param n The number of characters. 100 // @param c The character to use. 101 string(size_t n, char c); 102 103 // Construct a string from a char array. 104 // @param begin The start of the source C string. '\0' are ignored. 105 // @param end The end of source C string. Points just pass the last 106 // character. 107 string(const value_type *begin, const value_type *end); 108 109 ~string(); 110 111 // @return The number of characters in the string, not including any 112 // null-termination. 113 size_type length() const { return mLength; } 114 size_type size() const { return mLength; } 115 116 // @return A pointer to null-terminated contents. 117 const value_type *c_str() const { return mData; } 118 const value_type *data() const { return mData; } 119 120 // Empty the string on return. Release the internal buffer. Length 121 // and capacity are both 0 on return. If you want to keep the 122 // internal buffer around for reuse, call 'erase' instead. 123 void clear(); 124 125 // @return true if the string is empty. 126 bool empty() const { return this->size() == 0; } 127 128 // Remove 'len' characters from the string starting at 'pos'. The 129 // string length is reduced by 'len'. If len is greater or equal 130 // to the number of characters in the string, it is truncated at 131 // 'pos'. If 'pos' is beyond the end of the string, 'erase' does 132 // nothing. Note, regular STL implementations throw a out_of_range 133 // exception in this case. 134 // Internally, the capacity of the buffer remains unchanged. If 135 // you wanted to recover the deleted chars' memory you should call 136 // 'reserve' explicitly (see also 'clear'). 137 // @param pos Index of the first character to remove (default to 0) 138 // @param n Number of characters to delete. (default to remainder) 139 // @return a reference to this string. 140 string& erase(size_type pos = 0, size_type n = npos); 141 142 // @param str The string to be append. 143 // @return A reference to this string. 144 string& operator+=(const string& str) { return this->append(str); } 145 146 // @param str The C string to be append. 147 // @return A reference to this string. 148 string& operator+=(const value_type *str) { return this->append(str); } 149 150 // @param c A character to be append. 151 // @return A reference to this string. 152 string& operator+=(const char c) { this->push_back(c); return *this; } 153 154 // @param c A character to be append. 155 void push_back(const char c); 156 157 // no-op if str is NULL. 158 string& append(const value_type *str); 159 // no-op if str is NULL. n must be >= 0. 160 string& append(const value_type *str, size_type n); 161 // no-op if str is NULL. pos and n must be >= 0. 162 string& append(const value_type *str, size_type pos, size_type n); 163 string& append(const string& str); 164 165 template<typename _InputIterator> 166 string& append(_InputIterator first, _InputIterator last); 167 168 // Comparison. 169 // @return 0 if this==other, < 0 if this < other and > 0 if this > other. 170 // Don't assume the values are -1, 0, 1 171 int compare(const string& other) const; 172 int compare(const value_type *other) const; 173 174 friend bool operator==(const string& left, const string& right); 175 friend bool operator==(const string& left, const value_type *right); 176 friend bool operator==(const value_type *left, const string& right) { return right == left; } 177 friend bool operator!=(const string& left, const string& right) { return !(left == right); } 178 friend bool operator!=(const string& left, const char* right) { return !(left == right); } 179 friend bool operator!=(const value_type *left, const string& right) { return !(left == right); } 180 181 // @return Number of elements for which memory has been allocated. capacity >= size(). 182 size_type capacity() const { return mCapacity; } 183 184 // Change the capacity to new_size. No effect if new_size < size(). 185 // 0 means Shrink to fit. 186 // @param new_size number of character to be allocated. 187 void reserve(size_type new_size = 0); 188 189 // Exchange the content of this with the content of other. 190 // @param other Instance to swap this one with. 191 void swap(string& other); 192 193 // Accessors. 194 // @param pos of the char. No boundary, signed checks are done. 195 // @return a const reference to the char. 196 const char& operator[](const size_type pos) const; 197 198 // @param pos of the char. No boundary, signed checks are done. 199 // @return a reference to the char. 200 char& operator[](const size_type pos); 201 202 // 'at' is similar to operator[] except that it does check bounds. 203 const char& at(const size_type pos) const; 204 char& at(const size_type pos); 205 206 // Assignments. 207 string& operator=(const string& str) { return assign(str); } 208 string& operator=(const char* str) { return assign(str); } 209 string& operator=(char c); 210 211 string& assign(const string& str); 212 // Assign a substring of the original. 213 // @param str Original string. 214 // @param pos Index of the start of the copy. 215 // @param n Number of character to be copied. 216 string& assign(const string& str, size_type pos, size_type n); 217 string& assign(const value_type *str); 218 219 // Assign a non-nul terminated array of chars. 220 // @param array Of chars non-nul terminated. 221 // @param len Length of the array. 222 string& assign(const value_type *array, size_type len); 223 224 // Concat. Prefer using += or append. 225 // Uses unnamed object for return value optimization. 226 friend string operator+(const string& left, const string& right) { 227 return string(left).append(right); 228 } 229 friend string operator+(const string& left, const value_type *right) { 230 return string(left).append(right); 231 } 232 friend string operator+(const value_type *left, const string& right) { 233 return string(left).append(right); 234 } 235 friend string operator+(const string& left, char right) { 236 return string(left).operator+=(right); 237 } 238 friend string operator+(char left, const string& right) { 239 return string(&left, 1).append(right); 240 } 241 242 // Insert a copy of c before the character referred to by pos. 243 // @param pos A valid iterator on *this. 244 // @return An iterator which refers to the copy of the inserted 245 // character. Because internally some reallocation may occur, the 246 // returned iterator may be different from 'pos'. 247 iterator insert(iterator pos, char c); 248 249 // Find the position of a sub-string. The empty string is always 250 // found at the requested position except when it's beyond the 251 // string's end. 252 // @param str String to locate. 253 // @param pos Index of the character to search from. Default to 0. 254 // @return Index of start of the first occurrence of the 255 // string. string::npos if no occurrence of str was found from the 256 // starting position. 257 size_type find(const string& str, size_type pos = 0) const { 258 return find(str.mData, pos); 259 } 260 261 // Find the position of a C sub-string. The empty string is always 262 // found at the requested position except when it's beyond the 263 // string's end. 264 // @param str C string to locate. 265 // @param pos Index of the character to search from. Default to 0. 266 // @return Index of start of the first occurrence of the 267 // string. string::npos if no occurrence of str was found from the 268 // starting position. 269 size_type find(const value_type *str, size_type pos = 0) const; 270 271 // Find the lowest position xpos, if possible, such that: 272 // pos <= xpos && xpos < size() 273 // at(xpos) == c 274 // @return xpos if it exists, npos otherwise. 275 size_type find(const value_type c, size_type pos = 0) const { 276 return find_first_of(c, pos); 277 } 278 279 // Find the highest position xpos, if possible, such that: 280 // xpos <= pos && xpos < size() 281 // at(xpos) == c 282 // @return xpos if it exists, npos otherwise. 283 size_type rfind(const value_type c, size_type pos = npos) const { 284 return find_last_of(c, pos); 285 } 286 287 // Iterators 288 iterator begin() {return iterator(mData);} 289 const_iterator begin() const {return const_iterator(mData);} 290 iterator end() {return iterator(mData + mLength);} 291 const_iterator end() const {return const_iterator(mData + mLength);} 292 293 // @return the substring [pos, pos + n]. 294 // Requires pos <= size(). If n > size() - pos, size() - pos is used. 295 string substr(size_type pos = 0, size_type n = npos) const; 296 297 // Find char methods. Return the position or npos if the char was not found. 298 size_type find_first_of(value_type c, size_type pos = 0) const; 299 size_type find_last_of(value_type c, size_type pos = npos) const; 300 size_type find_first_not_of(value_type c, size_type pos = 0) const; 301 size_type find_last_not_of(value_type c, size_type pos = npos) const; 302 303 private: 304 bool SafeMalloc(size_type n); 305 void SafeRealloc(size_type n); 306 void SafeFree(value_type *str); 307 void ResetTo(value_type *str); 308 void ConstructEmptyString(); 309 void Constructor(const value_type *str, size_type n); 310 void Constructor(const value_type *str, size_type pos, size_type n); 311 void Constructor(size_type num, char c); 312 void DeleteSafe(); 313 void Append(const value_type *str, size_type len); 314 315 value_type *mData; // pointer to the buffer 316 size_type mCapacity; // size of the buffer. 317 size_type mLength; // len of the string excl. null-terminator. 318 }; 319 320 // Comparaison: 321 bool operator<(const string& lhs, const string& rhs); 322 bool operator<=(const string& lhs, const string& rhs); 323 bool operator>(const string& lhs, const string& rhs); 324 bool operator>=(const string& lhs, const string& rhs); 325 326 // Swap 327 void swap(string& lhs, string& rhs); 328 329 // I/O 330 ostream& operator<<(ostream& os, const string& str); 331 332 333 // Specialization of append(iterator, iterator) using string iterators 334 // (const and non const). 335 template<> 336 string& string::append<__wrapper_iterator<const char *,string> >( 337 __wrapper_iterator<const char *,string> first, 338 __wrapper_iterator<const char *,string> last); 339 template<> 340 string& string::append<__wrapper_iterator<char *,string> >( 341 __wrapper_iterator<char *,string> first, 342 __wrapper_iterator<char *,string> last); 343 344 // append(iterator,iterator) default implementation. 345 template<typename _InputIterator> 346 string& string::append(_InputIterator first, _InputIterator last) { 347 size_type dist = std::distance(first, last); 348 size_type new_len = mLength + dist; 349 if (new_len <= mLength) { 350 return *this; // 0 / overflow 351 } 352 reserve(new_len); 353 if (new_len > mCapacity) { 354 return *this; // memory allocation failed. 355 } 356 std::copy(first, last, mData + mLength); 357 mLength = new_len; 358 mData[mLength] = '\0'; 359 return *this; 360 } 361 362 363 } // namespace std 364 365 #endif // ANDROID_ASTL_STRING__ 366