string revision cb8eb8e1390d1343563a55c117b5c39cfa87fe1d
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 <cstddef>
34#include <iterator>
35#include <char_traits.h>
36
37namespace std {
38
39class ostream;
40
41// Simple string implementation. Its purpose is to be able to compile code that
42// uses the STL and requires std::string.
43//
44// IMPORTANT:
45// . This class it is not fully STL compliant. Some constructors/methods maybe
46// missing, they will be added on demand.
47// . We don't provide a std::basic_string template that std::string extends
48// because we use only char (wchar is not supported on Android).
49// . The memory allocation scheme uses the heap. Since Android has the concept
50// of SharedBuffer, we may, in the future, templatize this class and add an
51// allocation parameter.
52// . The implementation is not optimized in any way (no copy on write support),
53// temporary instance may be expensive.
54// . Currently there is limited support for iterators.
55//
56
57class string
58{
59  public:
60    typedef char_traits<char>      traits_type;
61    typedef traits_type::char_type value_type;
62    typedef size_t                 size_type;
63    typedef ptrdiff_t              difference_type;
64    typedef value_type&            reference;
65    typedef const value_type&      const_reference;
66    typedef value_type*            pointer;
67    typedef const value_type*      const_pointer;
68    typedef __wrapper_iterator<pointer,string>  iterator;
69    typedef __wrapper_iterator<const_pointer,string> const_iterator;
70
71    static const size_type npos = static_cast<size_type>(-1);
72
73    // Constructors
74    string();
75
76    string(const string& str);
77
78    // Construct a string from a source's substring.
79    // @param str The source string.
80    // @param pos The index of the character to start the copy at.
81    // @param n The number of characters to copy. Use string::npos for the
82    // remainder.
83    string(const string& str, size_t pos, size_type n);
84
85    // Same as above but implicitly copy from pos to the end of the str.
86    string(const string& str, size_type pos);
87
88    // Construct a string from a C string.
89    // @param str The source string, must be '\0' terminated.
90    string(const value_type *str);
91
92    // Construct a string from a char array.
93    // @param str The source C string. '\0' are ignored.
94    // @param n The number of characters to copy.
95    string(const value_type *str, size_type n);
96
97    // Construct a string from a repetition of a character.
98    // @param n The number of characters.
99    // @param c The character to use.
100    string(size_t n, char c);
101
102    // Construct a string from a char array.
103    // @param begin The start of the source C string. '\0' are ignored.
104    // @param end The end of source C string. Points just pass the last
105    // character.
106    string(const value_type *begin, const value_type *end);
107
108    ~string();
109
110    // @return The number of characters in the string, not including any
111    // null-termination.
112    size_type length() const { return mLength; }
113    size_type size() const { return mLength; }
114
115    // @return A pointer to null-terminated contents.
116    const value_type *c_str() const { return mData; }
117    const value_type *data() const { return mData; }
118
119    // Empty the string on return. Release the internal buffer. Length
120    // and capacity are both 0 on return. If you want to keep the
121    // internal buffer around for reuse, call 'erase' instead.
122    void clear();
123
124    // @return true if the string is empty.
125    bool empty() const { return this->size() == 0; }
126
127    // Remove 'len' characters from the string starting at 'pos'. The
128    // string length is reduced by 'len'. If len is greater or equal
129    // to the number of characters in the string, it is truncated at
130    // 'pos'. If 'pos' is beyond the end of the string, 'erase' does
131    // nothing. Note, regular STL implementations throw a out_of_range
132    // exception in this case.
133    // Internally, the capacity of the buffer remains unchanged. If
134    // you wanted to recover the deleted chars' memory you should call
135    // 'reserve' explicitly (see also 'clear').
136    // @param pos Index of the first character to remove (default to 0)
137    // @param n Number of characters to delete. (default to remainder)
138    // @return a reference to this string.
139    string& erase(size_type pos = 0, size_type n = npos);
140
141    // @param str The string to be append.
142    // @return A reference to this string.
143    string& operator+=(const string& str) { return this->append(str); }
144
145    // @param str The C string to be append.
146    // @return A reference to this string.
147    string& operator+=(const value_type *str) { return this->append(str); }
148
149    // @param c A character to be append.
150    // @return A reference to this string.
151    string& operator+=(const char c) { this->push_back(c); return *this; }
152
153    // @param c A character to be append.
154    void push_back(const char c);
155
156    // no-op if str is NULL.
157    string& append(const value_type *str);
158    // no-op if str is NULL. n must be >= 0.
159    string& append(const value_type *str, size_type n);
160    // no-op if str is NULL. pos and n must be >= 0.
161    string& append(const value_type *str, size_type pos, size_type n);
162    string& append(const string& str);
163
164    // Comparison.
165    // @return 0 if this==other, < 0 if this < other and > 0 if this > other.
166    // Don't assume the values are -1, 0, 1
167    int compare(const string& other) const;
168    int compare(const value_type *other) const;
169
170    friend bool operator==(const string& left, const string& right);
171    friend bool operator==(const string& left, const value_type *right);
172    friend bool operator==(const value_type *left, const string& right) { return right == left; }
173    friend bool operator!=(const string& left, const string& right) { return !(left == right); }
174    friend bool operator!=(const string& left, const char* right) { return !(left == right); }
175    friend bool operator!=(const value_type *left, const string& right) { return !(left == right); }
176
177    // @return Number of elements for which memory has been allocated. capacity >= size().
178    size_type capacity() const { return mCapacity; }
179
180    // Change the capacity to new_size. No effect if new_size < size().
181    // 0 means Shrink to fit.
182    // @param new_size number of character to be allocated.
183    void reserve(size_type new_size = 0);
184
185    // Exchange the content of this with the content of other.
186    // @param other Instance to swap this one with.
187    void swap(string& other);
188
189    // Accessors.
190    // @param pos of the char. No boundary, signed checks are done.
191    // @return a const reference to the char.
192    const char& operator[](const size_type pos) const;
193
194    // @param pos of the char. No boundary, signed checks are done.
195    // @return a reference to the char.
196    char& operator[](const size_type pos);
197
198    // 'at' is similar to operator[] except that it does check bounds.
199    const char& at(const size_type pos) const;
200    char& at(const size_type pos);
201
202    // Assignments.
203    string& operator=(const string& str) { return assign(str); }
204    string& operator=(const char* str) { return assign(str); }
205    string& operator=(char c);
206
207    string& assign(const string& str);
208    // Assign a substring of the original.
209    // @param str Original string.
210    // @param pos Index of the start of the copy.
211    // @param n Number of character to be copied.
212    string& assign(const string& str, size_type pos, size_type n);
213    string& assign(const value_type *str);
214
215    // Assign a non-nul terminated array of chars.
216    // @param array Of chars non-nul terminated.
217    // @param len Length of the array.
218    string& assign(const value_type *array, size_type len);
219
220    // Concat. Prefer using += or append.
221    // Uses unnamed object for return value optimization.
222    friend string operator+(const string& left, const string& right) {
223        return string(left).append(right);
224    }
225    friend string operator+(const string& left, const value_type *right) {
226        return string(left).append(right);
227    }
228    friend string operator+(const value_type *left, const string& right) {
229        return string(left).append(right);
230    }
231    friend string operator+(const string& left, char right) {
232        return string(left).operator+=(right);
233    }
234    friend string operator+(char left, const string& right) {
235        return string(&left, 1).append(right);
236    }
237
238    // Find the position of a sub-string. The empty string is always
239    // found at the requested position except when it's beyond the
240    // string's end.
241    // @param str String to locate.
242    // @param pos Index of the character to search from. Default to 0.
243    // @return Index of start of the first occurrence of the
244    // string. string::npos if no occurrence of str was found from the
245    // starting position.
246    size_type find(const string& str, size_type pos = 0) const {
247        return find(str.mData, pos);
248    }
249
250    // Find the position of a C sub-string. The empty string is always
251    // found at the requested position except when it's beyond the
252    // string's end.
253    // @param str C string to locate.
254    // @param pos Index of the character to search from. Default to 0.
255    // @return Index of start of the first occurrence of the
256    // string. string::npos if no occurrence of str was found from the
257    // starting position.
258    size_type find(const value_type *str, size_type pos = 0) const;
259
260    // Find the lowest position xpos, if possible, such that:
261    //   pos <= xpos && xpos < size()
262    //   at(xpos) == c
263    // @return xpos if it exists, npos otherwise.
264    size_type find(const value_type c, size_type pos = 0) const {
265        return find_first_of(c, pos);
266    }
267
268    // Find the highest position xpos, if possible, such that:
269    //   xpos <= pos && xpos < size()
270    //   at(xpos) == c
271    // @return xpos if it exists, npos otherwise.
272    size_type rfind(const value_type c, size_type pos = npos) const {
273        return find_last_of(c, pos);
274    }
275
276    // Iterators
277    iterator begin() {return iterator(mData);}
278    const_iterator begin() const {return const_iterator(mData);}
279    iterator end() {return iterator(mData + mLength);}
280    const_iterator end() const {return const_iterator(mData + mLength);}
281
282    // @return the substring [pos, pos + n].
283    // Requires pos <= size(). If n > size() - pos, size() - pos is used.
284    string substr(size_type pos = 0, size_type n = npos) const;
285
286    // Find char methods. Return the position or npos if the char was not found.
287    size_type find_first_of(value_type c, size_type pos = 0) const;
288    size_type find_last_of(value_type c, size_type pos = npos) const;
289    size_type find_first_not_of(value_type c, size_type pos = 0) const;
290    size_type find_last_not_of(value_type c, size_type pos = npos) const;
291
292  private:
293    bool SafeMalloc(size_type n);
294    void SafeRealloc(size_type n);
295    void SafeFree(value_type *str);
296    void ResetTo(value_type *str);
297    void ConstructEmptyString();
298    void Constructor(const value_type *str, size_type n);
299    void Constructor(const value_type *str, size_type pos, size_type n);
300    void Constructor(size_type num, char c);
301    void DeleteSafe();
302    void Append(const value_type *str, size_type len);
303
304    value_type *mData;  // pointer to the buffer
305    size_type mCapacity;  // size of the buffer.
306    size_type mLength;  // len of the string excl. null-terminator.
307};
308
309// I/O
310ostream& operator<<(ostream& os, const string& str);
311
312}  // namespace std
313
314#endif  // ANDROID_ASTL_STRING__
315