string revision 44d38f3d1ae0fd02030e259c4f93a265f91e96fc
1fe47ae56a8808c836923466e44704db3a8371593Niko Catania/* -*- c++ -*- */
2fe47ae56a8808c836923466e44704db3a8371593Niko Catania/*
3fe47ae56a8808c836923466e44704db3a8371593Niko Catania * Copyright (C) 2009 The Android Open Source Project
4fe47ae56a8808c836923466e44704db3a8371593Niko Catania * All rights reserved.
5fe47ae56a8808c836923466e44704db3a8371593Niko Catania *
6fe47ae56a8808c836923466e44704db3a8371593Niko Catania * Redistribution and use in source and binary forms, with or without
7fe47ae56a8808c836923466e44704db3a8371593Niko Catania * modification, are permitted provided that the following conditions
8fe47ae56a8808c836923466e44704db3a8371593Niko Catania * are met:
9fe47ae56a8808c836923466e44704db3a8371593Niko Catania *  * Redistributions of source code must retain the above copyright
10fe47ae56a8808c836923466e44704db3a8371593Niko Catania *    notice, this list of conditions and the following disclaimer.
11fe47ae56a8808c836923466e44704db3a8371593Niko Catania *  * Redistributions in binary form must reproduce the above copyright
12fe47ae56a8808c836923466e44704db3a8371593Niko Catania *    notice, this list of conditions and the following disclaimer in
13fe47ae56a8808c836923466e44704db3a8371593Niko Catania *    the documentation and/or other materials provided with the
14fe47ae56a8808c836923466e44704db3a8371593Niko Catania *    distribution.
15fe47ae56a8808c836923466e44704db3a8371593Niko Catania *
16fe47ae56a8808c836923466e44704db3a8371593Niko Catania * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17fe47ae56a8808c836923466e44704db3a8371593Niko Catania * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18fe47ae56a8808c836923466e44704db3a8371593Niko Catania * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19fe47ae56a8808c836923466e44704db3a8371593Niko Catania * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20fe47ae56a8808c836923466e44704db3a8371593Niko Catania * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21fe47ae56a8808c836923466e44704db3a8371593Niko Catania * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22fe47ae56a8808c836923466e44704db3a8371593Niko Catania * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23fe47ae56a8808c836923466e44704db3a8371593Niko Catania * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24fe47ae56a8808c836923466e44704db3a8371593Niko Catania * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25fe47ae56a8808c836923466e44704db3a8371593Niko Catania * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26fe47ae56a8808c836923466e44704db3a8371593Niko Catania * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27fe47ae56a8808c836923466e44704db3a8371593Niko Catania * SUCH DAMAGE.
28fe47ae56a8808c836923466e44704db3a8371593Niko Catania */
29fe47ae56a8808c836923466e44704db3a8371593Niko Catania
30fe47ae56a8808c836923466e44704db3a8371593Niko Catania#ifndef ANDROID_ASTL_STRING__
31fe47ae56a8808c836923466e44704db3a8371593Niko Catania#define ANDROID_ASTL_STRING__
32fe47ae56a8808c836923466e44704db3a8371593Niko Catania
33fe47ae56a8808c836923466e44704db3a8371593Niko Catania#include <cstddef>
3491ea6c037471a1acd97b03c3097223777906f748Nicolas Catania#include <iterator>
35f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania#include <char_traits.h>
36fe47ae56a8808c836923466e44704db3a8371593Niko Catania
37fe47ae56a8808c836923466e44704db3a8371593Niko Catanianamespace std {
38fe47ae56a8808c836923466e44704db3a8371593Niko Catania
3944d38f3d1ae0fd02030e259c4f93a265f91e96fcNicolas Cataniaclass ostream;
4044d38f3d1ae0fd02030e259c4f93a265f91e96fcNicolas Catania
41fe47ae56a8808c836923466e44704db3a8371593Niko Catania// Simple string implementation. Its purpose is to be able to compile code that
42fe47ae56a8808c836923466e44704db3a8371593Niko Catania// uses the STL and requires std::string.
43fe47ae56a8808c836923466e44704db3a8371593Niko Catania//
44fe47ae56a8808c836923466e44704db3a8371593Niko Catania// IMPORTANT:
45fe47ae56a8808c836923466e44704db3a8371593Niko Catania// . This class it is not fully STL compliant. Some constructors/methods maybe
46fe47ae56a8808c836923466e44704db3a8371593Niko Catania// missing, they will be added on demand.
47fe47ae56a8808c836923466e44704db3a8371593Niko Catania// . We don't provide a std::basic_string template that std::string extends
48fe47ae56a8808c836923466e44704db3a8371593Niko Catania// because we use only char (wchar is not supported on Android).
49fe47ae56a8808c836923466e44704db3a8371593Niko Catania// . The memory allocation scheme uses the heap. Since Android has the concept
50fe47ae56a8808c836923466e44704db3a8371593Niko Catania// of SharedBuffer, we may, in the future, templatize this class and add an
51fe47ae56a8808c836923466e44704db3a8371593Niko Catania// allocation parameter.
52fe47ae56a8808c836923466e44704db3a8371593Niko Catania// . The implementation is not optimized in any way (no copy on write support),
53fe47ae56a8808c836923466e44704db3a8371593Niko Catania// temporary instance may be expensive.
5491ea6c037471a1acd97b03c3097223777906f748Nicolas Catania// . Currently there is limited support for iterators.
55d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania//
56fe47ae56a8808c836923466e44704db3a8371593Niko Catania
57fe47ae56a8808c836923466e44704db3a8371593Niko Cataniaclass string
58fe47ae56a8808c836923466e44704db3a8371593Niko Catania{
59fe47ae56a8808c836923466e44704db3a8371593Niko Catania  public:
60743c6a2694bf16bf29d516c906363199a7bccf86Nicolas Catania    typedef char_traits<char>      traits_type;
61f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef traits_type::char_type value_type;
62f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef size_t                 size_type;
63f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef ptrdiff_t              difference_type;
64f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef value_type&            reference;
65f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef const value_type&      const_reference;
66f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef value_type*            pointer;
67f31fdb2e57186a552855e27f55036369ec1c279aNicolas Catania    typedef const value_type*      const_pointer;
6891ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    typedef __wrapper_iterator<pointer,string>  iterator;
6991ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    typedef __wrapper_iterator<const_pointer,string> const_iterator;
70fe47ae56a8808c836923466e44704db3a8371593Niko Catania
717618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    static const size_type npos = static_cast<size_type>(-1);
72fe47ae56a8808c836923466e44704db3a8371593Niko Catania
73fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Constructors
74fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string();
75fe47ae56a8808c836923466e44704db3a8371593Niko Catania
76fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string(const string& str);
77fe47ae56a8808c836923466e44704db3a8371593Niko Catania
78fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Construct a string from a source's substring.
79fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str The source string.
80d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param pos The index of the character to start the copy at.
81d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param n The number of characters to copy. Use string::npos for the
82fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // remainder.
83d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string(const string& str, size_t pos, size_type n);
84fe47ae56a8808c836923466e44704db3a8371593Niko Catania
85d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // Same as above but implicitly copy from pos to the end of the str.
86d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string(const string& str, size_type pos);
87fe47ae56a8808c836923466e44704db3a8371593Niko Catania
88fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Construct a string from a C string.
89fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str The source string, must be '\0' terminated.
907618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string(const value_type *str);
91fe47ae56a8808c836923466e44704db3a8371593Niko Catania
92fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Construct a string from a char array.
93fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str The source C string. '\0' are ignored.
94d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param n The number of characters to copy.
95d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string(const value_type *str, size_type n);
96fe47ae56a8808c836923466e44704db3a8371593Niko Catania
97fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Construct a string from a repetition of a character.
98d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param n The number of characters.
99fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param c The character to use.
100d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string(size_t n, char c);
101fe47ae56a8808c836923466e44704db3a8371593Niko Catania
102fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Construct a string from a char array.
103fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param begin The start of the source C string. '\0' are ignored.
104fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param end The end of source C string. Points just pass the last
105fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // character.
1067618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string(const value_type *begin, const value_type *end);
107fe47ae56a8808c836923466e44704db3a8371593Niko Catania
108fe47ae56a8808c836923466e44704db3a8371593Niko Catania    ~string();
109fe47ae56a8808c836923466e44704db3a8371593Niko Catania
110fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return The number of characters in the string, not including any
111fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // null-termination.
1127618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type length() const { return mLength; }
1137618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type size() const { return mLength; }
114fe47ae56a8808c836923466e44704db3a8371593Niko Catania
115fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return A pointer to null-terminated contents.
1167618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    const value_type *c_str() const { return mData; }
1177618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    const value_type *data() const { return mData; }
118fe47ae56a8808c836923466e44704db3a8371593Niko Catania
11960fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // Empty the string on return. Release the internal buffer. Length
12060fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // and capacity are both 0 on return. If you want to keep the
12160fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // internal buffer around for reuse, call 'erase' instead.
122fe47ae56a8808c836923466e44704db3a8371593Niko Catania    void clear();
123fe47ae56a8808c836923466e44704db3a8371593Niko Catania
124fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return true if the string is empty.
125fe47ae56a8808c836923466e44704db3a8371593Niko Catania    bool empty() const { return this->size() == 0; }
126fe47ae56a8808c836923466e44704db3a8371593Niko Catania
12760fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // Remove 'len' characters from the string starting at 'pos'. The
12860fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // string length is reduced by 'len'. If len is greater or equal
12960fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // to the number of characters in the string, it is truncated at
13060fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // 'pos'. If 'pos' is beyond the end of the string, 'erase' does
13160fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // nothing. Note, regular STL implementations throw a out_of_range
13260fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // exception in this case.
13360fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // Internally, the capacity of the buffer remains unchanged. If
13460fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // you wanted to recover the deleted chars' memory you should call
13560fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // 'reserve' explicitly (see also 'clear').
13660fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // @param pos Index of the first character to remove (default to 0)
137d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param n Number of characters to delete. (default to remainder)
13860fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // @return a reference to this string.
139d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string& erase(size_type pos = 0, size_type n = npos);
14060fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania
141fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str The string to be append.
142fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return A reference to this string.
143fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& operator+=(const string& str) { return this->append(str); }
144fe47ae56a8808c836923466e44704db3a8371593Niko Catania
145fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str The C string to be append.
146fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return A reference to this string.
1477618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string& operator+=(const value_type *str) { return this->append(str); }
148fe47ae56a8808c836923466e44704db3a8371593Niko Catania
149fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param c A character to be append.
150fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return A reference to this string.
151fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& operator+=(const char c) { this->push_back(c); return *this; }
152fe47ae56a8808c836923466e44704db3a8371593Niko Catania
153fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param c A character to be append.
154fe47ae56a8808c836923466e44704db3a8371593Niko Catania    void push_back(const char c);
155fe47ae56a8808c836923466e44704db3a8371593Niko Catania
156fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // no-op if str is NULL.
1577618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string& append(const value_type *str);
158d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // no-op if str is NULL. n must be >= 0.
159d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string& append(const value_type *str, size_type n);
160d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // no-op if str is NULL. pos and n must be >= 0.
161d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string& append(const value_type *str, size_type pos, size_type n);
162fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& append(const string& str);
163fe47ae56a8808c836923466e44704db3a8371593Niko Catania
16460fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // Comparison.
165fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return 0 if this==other, < 0 if this < other and > 0 if this > other.
166fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Don't assume the values are -1, 0, 1
167fe47ae56a8808c836923466e44704db3a8371593Niko Catania    int compare(const string& other) const;
1687618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    int compare(const value_type *other) const;
169fe47ae56a8808c836923466e44704db3a8371593Niko Catania
170fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend bool operator==(const string& left, const string& right);
1717618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    friend bool operator==(const string& left, const value_type *right);
1727618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    friend bool operator==(const value_type *left, const string& right) { return right == left; }
173fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend bool operator!=(const string& left, const string& right) { return !(left == right); }
174fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend bool operator!=(const string& left, const char* right) { return !(left == right); }
1757618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    friend bool operator!=(const value_type *left, const string& right) { return !(left == right); }
176fe47ae56a8808c836923466e44704db3a8371593Niko Catania
177fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return Number of elements for which memory has been allocated. capacity >= size().
1787618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type capacity() const { return mCapacity; }
179fe47ae56a8808c836923466e44704db3a8371593Niko Catania
180d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // Change the capacity to new_size. No effect if new_size < size().
181d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // 0 means Shrink to fit.
182fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param new_size number of character to be allocated.
1837618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    void reserve(size_type new_size = 0);
184fe47ae56a8808c836923466e44704db3a8371593Niko Catania
185fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Exchange the content of this with the content of other.
186fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param other Instance to swap this one with.
187fe47ae56a8808c836923466e44704db3a8371593Niko Catania    void swap(string& other);
188fe47ae56a8808c836923466e44704db3a8371593Niko Catania
189fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Accessors.
190d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param pos of the char. No boundary, signed checks are done.
191fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return a const reference to the char.
192d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    const char& operator[](const size_type pos) const;
193d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania
194d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param pos of the char. No boundary, signed checks are done.
195fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @return a reference to the char.
196d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    char& operator[](const size_type pos);
197fe47ae56a8808c836923466e44704db3a8371593Niko Catania
19874a6fdea77d52a17be4bc38831fe02a31cefbf34Nicolas Catania    // 'at' is similar to operator[] except that it does check bounds.
19974a6fdea77d52a17be4bc38831fe02a31cefbf34Nicolas Catania    const char& at(const size_type pos) const;
20074a6fdea77d52a17be4bc38831fe02a31cefbf34Nicolas Catania    char& at(const size_type pos);
20174a6fdea77d52a17be4bc38831fe02a31cefbf34Nicolas Catania
202fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Assignments.
203fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& operator=(const string& str) { return assign(str); }
204fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& operator=(const char* str) { return assign(str); }
205fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& operator=(char c);
206fe47ae56a8808c836923466e44704db3a8371593Niko Catania
207fe47ae56a8808c836923466e44704db3a8371593Niko Catania    string& assign(const string& str);
208d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // Assign a substring of the original.
209fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param str Original string.
210fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param pos Index of the start of the copy.
211d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param n Number of character to be copied.
212d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    string& assign(const string& str, size_type pos, size_type n);
2137618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string& assign(const value_type *str);
214d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania
215d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // Assign a non-nul terminated array of chars.
216d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    // @param array Of chars non-nul terminated.
217fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // @param len Length of the array.
2187618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    string& assign(const value_type *array, size_type len);
219fe47ae56a8808c836923466e44704db3a8371593Niko Catania
220fe47ae56a8808c836923466e44704db3a8371593Niko Catania    // Concat. Prefer using += or append.
22160fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // Uses unnamed object for return value optimization.
222fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend string operator+(const string& left, const string& right) {
223fe47ae56a8808c836923466e44704db3a8371593Niko Catania        return string(left).append(right);
224fe47ae56a8808c836923466e44704db3a8371593Niko Catania    }
2257618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    friend string operator+(const string& left, const value_type *right) {
226fe47ae56a8808c836923466e44704db3a8371593Niko Catania        return string(left).append(right);
227fe47ae56a8808c836923466e44704db3a8371593Niko Catania    }
2287618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    friend string operator+(const value_type *left, const string& right) {
229fe47ae56a8808c836923466e44704db3a8371593Niko Catania        return string(left).append(right);
230fe47ae56a8808c836923466e44704db3a8371593Niko Catania    }
231fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend string operator+(const string& left, char right) {
232fe47ae56a8808c836923466e44704db3a8371593Niko Catania        return string(left).operator+=(right);
233fe47ae56a8808c836923466e44704db3a8371593Niko Catania    }
234fe47ae56a8808c836923466e44704db3a8371593Niko Catania    friend string operator+(char left, const string& right) {
235fe47ae56a8808c836923466e44704db3a8371593Niko Catania        return string(&left, 1).append(right);
236fe47ae56a8808c836923466e44704db3a8371593Niko Catania    }
237fe47ae56a8808c836923466e44704db3a8371593Niko Catania
238d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // Find the position of a sub-string. The empty string is always
239d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // found at the requested position except when it's beyond the
240d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // string's end.
241d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // @param str String to locate.
242d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // @param pos Index of the character to search from. Default to 0.
24360fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // @return Index of start of the first occurrence of the
24460fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // string. string::npos if no occurrence of str was found from the
245d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // starting position.
246d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    size_type find(const string& str, size_type pos = 0) const {
24760fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania        return find(str.mData, pos);
248d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    }
249d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania
250d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // Find the position of a C sub-string. The empty string is always
251d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // found at the requested position except when it's beyond the
252d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // string's end.
253d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // @param str C string to locate.
254d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // @param pos Index of the character to search from. Default to 0.
25560fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // @return Index of start of the first occurrence of the
25660fd0f758a63e74980d712a13c91bc24d98cedc6Nicolas Catania    // string. string::npos if no occurrence of str was found from the
257d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania    // starting position.
2587618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type find(const value_type *str, size_type pos = 0) const;
259d738d268c8f915bde451bba52e0c3996113ba9f0Nicolas Catania
26091ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    // Iterators
26191ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    iterator begin() {return iterator(mData);}
26291ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    const_iterator begin() const {return const_iterator(mData);}
26391ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    iterator end() {return iterator(mData + mLength);}
26491ea6c037471a1acd97b03c3097223777906f748Nicolas Catania    const_iterator end() const {return const_iterator(mData + mLength);}
26591ea6c037471a1acd97b03c3097223777906f748Nicolas Catania
266fe47ae56a8808c836923466e44704db3a8371593Niko Catania  private:
267d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    bool SafeMalloc(size_type n);
268d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    void SafeRealloc(size_type n);
2697618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    void SafeFree(value_type *str);
2707618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    void ResetTo(value_type *str);
271fe47ae56a8808c836923466e44704db3a8371593Niko Catania    void ConstructEmptyString();
272d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    void Constructor(const value_type *str, size_type n);
273d881e3f36a074eb9fd8e353fb5e5e3e539f2d460Nicolas Catania    void Constructor(const value_type *str, size_type pos, size_type n);
2747618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    void Constructor(size_type num, char c);
275fe47ae56a8808c836923466e44704db3a8371593Niko Catania    void DeleteSafe();
2767618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    void Append(const value_type *str, size_type len);
277fe47ae56a8808c836923466e44704db3a8371593Niko Catania
2787618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    value_type *mData;  // pointer to the buffer
2797618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type mCapacity;  // size of the buffer.
2807618d7b9a011b1158ef868d6ae3ead242ddaccacNicolas Catania    size_type mLength;  // len of the string excl. null-terminator.
281fe47ae56a8808c836923466e44704db3a8371593Niko Catania};
282fe47ae56a8808c836923466e44704db3a8371593Niko Catania
28344d38f3d1ae0fd02030e259c4f93a265f91e96fcNicolas Catania// I/O
28444d38f3d1ae0fd02030e259c4f93a265f91e96fcNicolas Cataniaostream& operator<<(ostream& os, const string& str);
28544d38f3d1ae0fd02030e259c4f93a265f91e96fcNicolas Catania
286fe47ae56a8808c836923466e44704db3a8371593Niko Catania}  // namespace std
287fe47ae56a8808c836923466e44704db3a8371593Niko Catania
288fe47ae56a8808c836923466e44704db3a8371593Niko Catania#endif  // ANDROID_ASTL_STRING__
289