Home | History | Annotate | Download | only in include
      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