/* -*- c++ -*- */
/*
 * Copyright (C) 2009 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef ANDROID_ASTL_STRING__
#define ANDROID_ASTL_STRING__

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <char_traits.h>

namespace std {

class ostream;

// Simple string implementation. Its purpose is to be able to compile code that
// uses the STL and requires std::string.
//
// IMPORTANT:
// . This class it is not fully STL compliant. Some constructors/methods maybe
// missing, they will be added on demand.
// . We don't provide a std::basic_string template that std::string extends
// because we use only char (wchar is not supported on Android).
// . The memory allocation scheme uses the heap. Since Android has the concept
// of SharedBuffer, we may, in the future, templatize this class and add an
// allocation parameter.
// . The implementation is not optimized in any way (no copy on write support),
// temporary instance may be expensive.
// . Currently there is limited support for iterators.
//

class string
{
  public:
    typedef char_traits<char>      traits_type;
    typedef traits_type::char_type value_type;
    typedef size_t                 size_type;
    typedef ptrdiff_t              difference_type;
    typedef value_type&            reference;
    typedef const value_type&      const_reference;
    typedef value_type*            pointer;
    typedef const value_type*      const_pointer;
    typedef __wrapper_iterator<pointer,string>  iterator;
    typedef __wrapper_iterator<const_pointer,string> const_iterator;

    static const size_type npos = static_cast<size_type>(-1);

    // Constructors
    string();

    string(const string& str);

    // Construct a string from a source's substring.
    // @param str The source string.
    // @param pos The index of the character to start the copy at.
    // @param n The number of characters to copy. Use string::npos for the
    // remainder.
    string(const string& str, size_t pos, size_type n);

    // Same as above but implicitly copy from pos to the end of the str.
    string(const string& str, size_type pos);

    // Construct a string from a C string.
    // @param str The source string, must be '\0' terminated.
    string(const value_type *str);

    // Construct a string from a char array.
    // @param str The source C string. '\0' are ignored.
    // @param n The number of characters to copy.
    string(const value_type *str, size_type n);

    // Construct a string from a repetition of a character.
    // @param n The number of characters.
    // @param c The character to use.
    string(size_t n, char c);

    // Construct a string from a char array.
    // @param begin The start of the source C string. '\0' are ignored.
    // @param end The end of source C string. Points just pass the last
    // character.
    string(const value_type *begin, const value_type *end);

    ~string();

    // @return The number of characters in the string, not including any
    // null-termination.
    size_type length() const { return mLength; }
    size_type size() const { return mLength; }

    // @return A pointer to null-terminated contents.
    const value_type *c_str() const { return mData; }
    const value_type *data() const { return mData; }

    // Empty the string on return. Release the internal buffer. Length
    // and capacity are both 0 on return. If you want to keep the
    // internal buffer around for reuse, call 'erase' instead.
    void clear();

    // @return true if the string is empty.
    bool empty() const { return this->size() == 0; }

    // Remove 'len' characters from the string starting at 'pos'. The
    // string length is reduced by 'len'. If len is greater or equal
    // to the number of characters in the string, it is truncated at
    // 'pos'. If 'pos' is beyond the end of the string, 'erase' does
    // nothing. Note, regular STL implementations throw a out_of_range
    // exception in this case.
    // Internally, the capacity of the buffer remains unchanged. If
    // you wanted to recover the deleted chars' memory you should call
    // 'reserve' explicitly (see also 'clear').
    // @param pos Index of the first character to remove (default to 0)
    // @param n Number of characters to delete. (default to remainder)
    // @return a reference to this string.
    string& erase(size_type pos = 0, size_type n = npos);

    // @param str The string to be append.
    // @return A reference to this string.
    string& operator+=(const string& str) { return this->append(str); }

    // @param str The C string to be append.
    // @return A reference to this string.
    string& operator+=(const value_type *str) { return this->append(str); }

    // @param c A character to be append.
    // @return A reference to this string.
    string& operator+=(const char c) { this->push_back(c); return *this; }

    // @param c A character to be append.
    void push_back(const char c);

    // no-op if str is NULL.
    string& append(const value_type *str);
    // no-op if str is NULL. n must be >= 0.
    string& append(const value_type *str, size_type n);
    // no-op if str is NULL. pos and n must be >= 0.
    string& append(const value_type *str, size_type pos, size_type n);
    string& append(const string& str);

    template<typename _InputIterator>
    string& append(_InputIterator first, _InputIterator last);

    // Comparison.
    // @return 0 if this==other, < 0 if this < other and > 0 if this > other.
    // Don't assume the values are -1, 0, 1
    int compare(const string& other) const;
    int compare(const value_type *other) const;

    friend bool operator==(const string& left, const string& right);
    friend bool operator==(const string& left, const value_type *right);
    friend bool operator==(const value_type *left, const string& right) { return right == left; }
    friend bool operator!=(const string& left, const string& right) { return !(left == right); }
    friend bool operator!=(const string& left, const char* right) { return !(left == right); }
    friend bool operator!=(const value_type *left, const string& right) { return !(left == right); }

    // @return Number of elements for which memory has been allocated. capacity >= size().
    size_type capacity() const { return mCapacity; }

    // Change the capacity to new_size. No effect if new_size < size().
    // 0 means Shrink to fit.
    // @param new_size number of character to be allocated.
    void reserve(size_type new_size = 0);

    // Exchange the content of this with the content of other.
    // @param other Instance to swap this one with.
    void swap(string& other);

    // Accessors.
    // @param pos of the char. No boundary, signed checks are done.
    // @return a const reference to the char.
    const char& operator[](const size_type pos) const;

    // @param pos of the char. No boundary, signed checks are done.
    // @return a reference to the char.
    char& operator[](const size_type pos);

    // 'at' is similar to operator[] except that it does check bounds.
    const char& at(const size_type pos) const;
    char& at(const size_type pos);

    // Assignments.
    string& operator=(const string& str) { return assign(str); }
    string& operator=(const char* str) { return assign(str); }
    string& operator=(char c);

    string& assign(const string& str);
    // Assign a substring of the original.
    // @param str Original string.
    // @param pos Index of the start of the copy.
    // @param n Number of character to be copied.
    string& assign(const string& str, size_type pos, size_type n);
    string& assign(const value_type *str);

    // Assign a non-nul terminated array of chars.
    // @param array Of chars non-nul terminated.
    // @param len Length of the array.
    string& assign(const value_type *array, size_type len);

    // Concat. Prefer using += or append.
    // Uses unnamed object for return value optimization.
    friend string operator+(const string& left, const string& right) {
        return string(left).append(right);
    }
    friend string operator+(const string& left, const value_type *right) {
        return string(left).append(right);
    }
    friend string operator+(const value_type *left, const string& right) {
        return string(left).append(right);
    }
    friend string operator+(const string& left, char right) {
        return string(left).operator+=(right);
    }
    friend string operator+(char left, const string& right) {
        return string(&left, 1).append(right);
    }

    // Insert a copy of c before the character referred to by pos.
    // @param pos A valid iterator on *this.
    // @return An iterator which refers to the copy of the inserted
    // character. Because internally some reallocation may occur, the
    // returned iterator may be different from 'pos'.
    iterator insert(iterator pos, char c);

    // Find the position of a sub-string. The empty string is always
    // found at the requested position except when it's beyond the
    // string's end.
    // @param str String to locate.
    // @param pos Index of the character to search from. Default to 0.
    // @return Index of start of the first occurrence of the
    // string. string::npos if no occurrence of str was found from the
    // starting position.
    size_type find(const string& str, size_type pos = 0) const {
        return find(str.mData, pos);
    }

    // Find the position of a C sub-string. The empty string is always
    // found at the requested position except when it's beyond the
    // string's end.
    // @param str C string to locate.
    // @param pos Index of the character to search from. Default to 0.
    // @return Index of start of the first occurrence of the
    // string. string::npos if no occurrence of str was found from the
    // starting position.
    size_type find(const value_type *str, size_type pos = 0) const;

    // Find the lowest position xpos, if possible, such that:
    //   pos <= xpos && xpos < size()
    //   at(xpos) == c
    // @return xpos if it exists, npos otherwise.
    size_type find(const value_type c, size_type pos = 0) const {
        return find_first_of(c, pos);
    }

    // Find the highest position xpos, if possible, such that:
    //   xpos <= pos && xpos < size()
    //   at(xpos) == c
    // @return xpos if it exists, npos otherwise.
    size_type rfind(const value_type c, size_type pos = npos) const {
        return find_last_of(c, pos);
    }

    // Iterators
    iterator begin() {return iterator(mData);}
    const_iterator begin() const {return const_iterator(mData);}
    iterator end() {return iterator(mData + mLength);}
    const_iterator end() const {return const_iterator(mData + mLength);}

    // @return the substring [pos, pos + n].
    // Requires pos <= size(). If n > size() - pos, size() - pos is used.
    string substr(size_type pos = 0, size_type n = npos) const;

    // Find char methods. Return the position or npos if the char was not found.
    size_type find_first_of(value_type c, size_type pos = 0) const;
    size_type find_last_of(value_type c, size_type pos = npos) const;
    size_type find_first_not_of(value_type c, size_type pos = 0) const;
    size_type find_last_not_of(value_type c, size_type pos = npos) const;

  private:
    bool SafeMalloc(size_type n);
    void SafeRealloc(size_type n);
    void SafeFree(value_type *str);
    void ResetTo(value_type *str);
    void ConstructEmptyString();
    void Constructor(const value_type *str, size_type n);
    void Constructor(const value_type *str, size_type pos, size_type n);
    void Constructor(size_type num, char c);
    void DeleteSafe();
    void Append(const value_type *str, size_type len);

    value_type *mData;  // pointer to the buffer
    size_type mCapacity;  // size of the buffer.
    size_type mLength;  // len of the string excl. null-terminator.
};

// Comparaison:
bool operator<(const string& lhs, const string& rhs);
bool operator<=(const string& lhs, const string& rhs);
bool operator>(const string& lhs, const string& rhs);
bool operator>=(const string& lhs, const string& rhs);

// Swap
void swap(string& lhs, string& rhs);

// I/O
ostream& operator<<(ostream& os, const string& str);


// Specialization of append(iterator, iterator) using string iterators
// (const and non const).
template<>
string& string::append<__wrapper_iterator<const char *,string> >(
    __wrapper_iterator<const char *,string> first,
    __wrapper_iterator<const char *,string> last);
template<>
string& string::append<__wrapper_iterator<char *,string> >(
    __wrapper_iterator<char *,string> first,
    __wrapper_iterator<char *,string> last);

// append(iterator,iterator) default implementation.
template<typename _InputIterator>
string& string::append(_InputIterator first, _InputIterator last) {
    size_type dist = std::distance(first, last);
    size_type new_len = mLength + dist;
    if (new_len <= mLength) {
        return *this;  // 0 / overflow
    }
    reserve(new_len);
    if (new_len > mCapacity) {
        return *this;  // memory allocation failed.
    }
    std::copy(first, last, mData + mLength);
    mLength = new_len;
    mData[mLength] = '\0';
    return *this;
}


}  // namespace std

#endif  // ANDROID_ASTL_STRING__
