00001 #ifndef GSGL_DATA_STRING_H
00002 #define GSGL_DATA_STRING_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "data/data.hpp"
00038 #include "data/iterable.hpp"
00039 #include "data/indexable.hpp"
00040 #include "data/comparable.hpp"
00041 #include "data/printable.hpp"
00042 #include "data/serializable.hpp"
00043 #include "data/exception.hpp"
00044
00045 namespace gsgl
00046 {
00047
00048 namespace data
00049 {
00050 template <typename T>
00051 class list;
00052 }
00053
00054
00055 class string_iterator;
00056 class string_impl;
00057
00058
00059
00060 class DATA_API string
00061 : public data_object,
00062 public data::comparable,
00063 public data::iterable<wchar_t, string_iterator>,
00064 public data::indexable<wchar_t, gsgl::index_t>,
00065 public io::printable,
00066 public io::serializable
00067 {
00068 friend class string_iterator;
00069
00070 enum string_mode
00071 {
00072 STRING_NULL = 0,
00073 STRING_CONST_REF = 1,
00074 STRING_SHARED_IMPL = 2,
00075 STRING_INVALID = 3
00076 };
00077
00078 mutable string_mode mode;
00079
00080
00081
00082 union
00083 {
00084 mutable string_impl *impl;
00085 const wchar_t *ref;
00086 };
00087
00088 #ifdef DEBUG
00089 mutable const wchar_t *wchar_ptr;
00090 #endif
00091
00092 public:
00093 string();
00094 string(const string &);
00095 string(const wchar_t *);
00096 string(wchar_t *);
00097 explicit string(const char *);
00098
00099 string & operator= (const wchar_t *);
00100 string & operator= (wchar_t *);
00101 string & operator= (const string &);
00102
00103 virtual ~string();
00104
00105
00106
00107
00108 virtual gsgl::index_t size() const;
00109 virtual void clear();
00110
00111
00112
00113
00114
00115 virtual void append(const wchar_t &);
00116
00117 void append(const wchar_t *);
00118 void append(const string &);
00119 virtual void insert(const iterator &, const wchar_t &);
00120 virtual void remove(const iterator &);
00121
00122
00123
00124
00125
00126 virtual const wchar_t & item(const gsgl::index_t & index) const;
00127 virtual wchar_t & item(const gsgl::index_t & index);
00128
00129 virtual bool contains_index(const gsgl::index_t & index) const;
00130
00131
00132
00133
00134
00135 virtual int compare(const data::comparable &) const;
00136 int compare(const wchar_t *) const;
00137
00138 inline bool operator== (const wchar_t *s) const { return compare(s) == 0; }
00139 inline bool operator!= (const wchar_t *s) const { return compare(s) != 0; }
00140 inline bool operator< (const wchar_t *s) const { return compare(s) < 0; }
00141 inline bool operator<= (const wchar_t *s) const { return compare(s) <= 0; }
00142 inline bool operator> (const wchar_t *s) const { return compare(s) > 0; }
00143 inline bool operator>= (const wchar_t *s) const { return compare(s) >= 0; }
00144
00145
00146
00147
00148
00149 virtual void to_stream(io::text_stream &) const;
00150 virtual void from_stream(io::text_stream &);
00151
00152
00153
00154
00155
00156 virtual void to_stream(io::data_stream &) const;
00157 virtual void from_stream(io::data_stream &);
00158
00159
00160
00161
00162
00163 const wchar_t *w_string() const;
00164 const char *c_string() const;
00165 const unsigned char *p_string() const;
00166
00167
00168
00169
00170
00171 string & operator+= (const wchar_t &);
00172 string & operator+= (const wchar_t *);
00173 string & operator+= (const string &);
00174
00175 string operator+ (const wchar_t &) const;
00176 string operator+ (const wchar_t *) const;
00177 string operator+ (const string &) const;
00178
00179
00180
00181
00182
00183 string substring(const gsgl::index_t index, const gsgl::index_t length = -1) const;
00184 string left_substring(const gsgl::index_t length) const;
00185 string right_substring(const gsgl::index_t length) const;
00186
00187 gsgl::index_t find(const wchar_t *substr, const gsgl::index_t index = 0) const;
00188 gsgl::index_t find(const string & substr, const gsgl::index_t index = 0) const;
00189
00190 gsgl::index_t find_reverse(const wchar_t *substr, const gsgl::index_t index = -1) const;
00191 gsgl::index_t find_reverse(const string & substr, const gsgl::index_t index = -1) const;
00192
00193
00194
00195
00196
00197 string copy();
00198 string & trim();
00199
00200 string & make_upper();
00201 string & make_lower();
00202
00203 bool to_bool() const;
00204 int to_int() const;
00205 double to_double() const;
00206
00207 data::list<string> split(const wchar_t *separator) const;
00208 data::list<string> split(const string & separator) const;
00209
00210 static string format(const wchar_t *format, ...);
00211 static string format(const string & format, ...);
00212
00213
00214 static const string EMPTY_STRING;
00215
00216 private:
00217 void make_null();
00218 void unshare() const;
00219 };
00220
00221
00222 class DATA_API string_iterator
00223 {
00224 friend class gsgl::string;
00225 const gsgl::string & parent;
00226 gsgl::index_t position;
00227
00228 protected:
00229 string_iterator(const data::iterable<wchar_t, string_iterator> & parent_iterable)
00230 : parent(dynamic_cast<const gsgl::string &>(parent_iterable)), position(0) {}
00231
00232 string_iterator(const string_iterator & si)
00233 : parent(si.parent), position(si.position) {}
00234
00235 inline string_iterator & operator= (const string_iterator & si)
00236 {
00237 const_cast<gsgl::string &>(parent) = si.parent;
00238 position = si.position;
00239 return *this;
00240 }
00241
00242 inline bool is_valid() const { return position < parent.size(); }
00243
00244 inline const wchar_t & operator* () const
00245 {
00246 if (position < parent.size())
00247 return const_cast<wchar_t &>(parent[position]);
00248 else
00249 throw memory_exception(__FILE__, __LINE__, L"Array index out of bounds in string iterator dereference.");
00250 }
00251
00252 inline string_iterator operator++()
00253 {
00254 if (position < parent.size())
00255 ++position;
00256 else
00257 throw memory_exception(__FILE__, __LINE__, L"Array index out of bounds in string iterator preincrement.");
00258 return *this;
00259 }
00260 };
00261
00262
00263 }
00264
00265 #endif