15ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// Copyright 2014 The Android Open Source Project
25ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner//
35ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// This software is licensed under the terms of the GNU General Public
45ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// License version 2, as published by the Free Software Foundation, and
55ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// may be copied, distributed, and modified under those terms.
65ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner//
75ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// This program is distributed in the hope that it will be useful,
85ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of
95ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
105ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner// GNU General Public License for more details.
115ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
12d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#ifndef ANDROID_BASE_STRING_H
13d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#define ANDROID_BASE_STRING_H
14d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
15d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#include <stddef.h>
16d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
17d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnernamespace android {
18d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnernamespace base {
19d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
20d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerclass StringView;
21d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
22d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// Custom string implementation:
23d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// - Not a template, hence much better compiler error messages.
24d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// - Uses short-string-optimization on all platforms.
25d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner// - No iterators (for now).
26d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerclass String {
27d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerpublic:
28d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Empty constructor.
29d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String();
30d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
31d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Regular constructor from a C string.
32d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String(const char* string);
33d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
34d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Copy constructor.
35d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String(const String& other);
36d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
37d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Constructor from a StringView.
38d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    explicit String(const StringView& other);
39d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
40d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Constructor from a sized C string.
41d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String(const char* str, size_t len);
42d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
43d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Fill-constructor.
44d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String(size_t count, char fill);
45d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
46d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Destructor.
47d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    ~String();
48d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
49d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Return string as a zero-terminated C string.
50d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    const char* c_str() const { return mStr; }
51d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
52d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    void* data() { return mStr; }
53d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
54d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    const void* data() const { return mStr; }
55d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
56d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Return size of string in bytes, not including terminating zero.
57d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    size_t size() const { return mSize; }
58d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
59d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Return true if the string is empty, i.e. its size is 0.
60d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Note that a non-empty string can embed 0 bytes.
61d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool empty() const { return mSize == 0; }
62d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
63d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Return current capacity.
64d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    size_t capacity() const {
6597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner        return (mStr == mStorage) ?
6697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner                static_cast<size_t>(kMinCapacity) : mCapacity;
67d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
68d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
6997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner    // Clear the content of a given instance.
7097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner    void clear() { resize(0); }
7197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner
72d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Array indexing operators.
73d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    char& operator[](size_t index) { return mStr[index]; }
74d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    const char& operator[](size_t index) const { return mStr[index]; }
75d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
76d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Assign new values to strings.
77d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(const char* str);
78d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(const char* str, size_t len);
79d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(const String& other);
80d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(const StringView& other);
81d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(size_t count, char fill);
82d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& assign(char ch);
83d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
84d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Assignment operators.
85d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator=(const char* str) {
86d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->assign(str);
87d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
88d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
89d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator=(const String& other) {
90d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->assign(other);
91d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
92d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
93d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator=(const StringView& other) {
94d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->assign(other);
95d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
96d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
97d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator=(char ch) {
98d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->assign(ch);
99d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
100d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
101d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Append new values to current string.
102d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& append(const char* str);
103d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& append(const char* str, size_t len);
104d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& append(const String& other);
105d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& append(const StringView& other);
106d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& append(char ch);
107d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
108d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Addition-Assignment operators.
109d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator+=(const char* str) {
110d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->append(str);
111d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
112d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
113d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator+=(const String& other) {
114d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->append(other);
115d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
116d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
117d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator+=(const StringView& other) {
118d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->append(other);
119d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
120d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
121d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    String& operator+=(char ch) {
122d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return this->append(ch);
123d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
124d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
125d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Resize to a new size.
126d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    void resize(size_t newSize);
127d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
128d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Reserve enough room for |newSize| characters, followed by a
129d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // terminating zero.
130d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    void reserve(size_t newSize);
131d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
132d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Compare to something, return -1, 0 or +1 based on byte values.
133d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    int compare(const char* str, size_t len) const;
134d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    int compare(const char* str) const;
135d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    int compare(const String& other) const;
136d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    int compare(const StringView& other) const;
137d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    int compare(char ch) const;
138d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
139d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Compare for equality.
140d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool equals(const char* str, size_t len) const;
141d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool equals(const char* str) const;
142d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool equals(const String& other) const;
143d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool equals(const StringView& other) const;
144d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool equals(char ch) const;
145d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
146d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Binary operators.
147d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator==(const char* str) const {
148d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return equals(str);
149d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
150d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
151d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator==(const String& other) const {
152d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return equals(other);
153d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
154d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
155d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator==(const StringView& other) const {
156d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return equals(other);
157d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
158d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
159d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator==(char ch) const {
160d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return equals(ch);
161d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
162d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
163d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator!=(const char* str) const {
164d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return !operator==(str);
165d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
166d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
167d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator!=(const String& other) const {
168d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return !operator==(other);
169d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
170d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
171d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator!=(const StringView& other) const {
172d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return !operator==(other);
173d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
174d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
175d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    bool operator!=(char ch) const {
176d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        return !operator==(ch);
177d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    }
178d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
179d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Swap the content of this string with another one.
180d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    void swap(String* other);
181d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
182d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turnerprotected:
183d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    friend class StringVector;
184d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
185d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Internal helper routine to be used when |count| strings objects
186d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // have been moved or copied from |fromStrings| to |toStrings|.
187d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // This adjusts any internal |mStr| pointer to |mStorage| to the
188d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // new appropriate region. Used by StringVector to implement
189d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // optimized insert/copy/remove operations.
190d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    static void adjustMovedSlice(String* fromStrings,
191d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner                                 String* toStrings,
192d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner                                 size_t count);
193d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
194d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Move |count| strings from |strings + from| to |strings + to|
195d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // in memory. Used by StringVector to implement insert/delete
196d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // operations.
197d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    static void moveSlice(String* strings,
198d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner                          size_t from,
199d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner                          size_t to,
200d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner                          size_t count);
201d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
202d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Finalize |count| String instances from |strings|.
203d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Used by StringVector to implement resize/reserve operations.
204d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    static void finalizeSlice(String* strings, size_t count);
205d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
206d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // Minimum capacity for the in-object storage array |mStorage|,
207d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // not including the terminating zero. With a value of 16,
208d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // each String instance is 24 bytes on a 32-bit system, and
209d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    // 32-bytes on a 64-bit one.
210d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    enum {
211d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        kMinCapacity = 15
212d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    };
213d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
214d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    char* mStr;
215d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    size_t mSize;
216d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    union {
217d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        size_t mCapacity;
218d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner        char mStorage[kMinCapacity + 1U];
219d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner    };
220d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner};
221d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
222d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner}  // namespace base
223d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner}  // namespace android
224d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner
225d3f2c27ff9f611e5047a35cb20ed53f548214fedDavid 'Digit' Turner#endif  // ANDROID_BASE_STRING_H
226