fstring.h
Go to the documentation of this file.00001
00002
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 #ifndef GROOVX_RUTZ_FSTRING_H_UTC20050626084021_DEFINED
00036 #define GROOVX_RUTZ_FSTRING_H_UTC20050626084021_DEFINED
00037
00038 #include "rutz/atomic.h"
00039
00040 #include <cstddef>
00041 #include <cstring>
00042 #include <iosfwd>
00043
00044 namespace rutz
00045 {
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 class string_rep
00057 {
00058 public:
00059 static string_rep* make(std::size_t length, const char* text,
00060 std::size_t capacity=0);
00061
00062 static string_rep* read_from_stream(std::istream& is);
00063
00064 static string_rep* readsome_from_stream(std::istream& is, unsigned int count);
00065
00066 static string_rep* readline_from_stream(std::istream& is, char eol = '\n');
00067
00068 void incr_ref_count() throw() { m_refcount.atomic_incr(); }
00069
00070 int decr_ref_count() throw()
00071 {
00072 const int c = m_refcount.atomic_decr_return();
00073 if (c <= 0)
00074 delete this;
00075 return c;
00076 }
00077
00078 std::size_t length() const throw() { return m_length; }
00079 std::size_t capacity() const throw() { return m_capacity; }
00080 const char* text() const throw() { return m_text; }
00081
00082 void debug_dump() const throw();
00083
00084 private:
00085
00086 void* operator new(std::size_t bytes);
00087
00088
00089 void operator delete(void* space);
00090
00091
00092
00093 string_rep(std::size_t length, const char* text, std::size_t capacity=0);
00094
00095 ~string_rep() throw();
00096
00097
00098 static void initialize_empty_rep();
00099
00100
00101
00102
00103
00104
00105
00106 void uniq_append_no_terminate(char c);
00107 void add_terminator() throw();
00108 void uniq_set_length(std::size_t length) throw();
00109 void uniq_append(std::size_t length, const char* text);
00110 void uniq_realloc(std::size_t capacity);
00111
00112 string_rep(const string_rep& other);
00113 string_rep& operator=(const string_rep& other);
00114
00115 rutz::atomic_int_t m_refcount;
00116
00117 std::size_t m_capacity;
00118 std::size_t m_length;
00119 char* m_text;
00120 };
00121
00122 struct char_range
00123 {
00124 char_range(const char* t, unsigned int n) : text(t), len(n) {}
00125
00126
00127
00128 const char* const text;
00129 unsigned int const len;
00130 };
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 class fstring
00150 {
00151 public:
00152
00153 fstring();
00154
00155
00156 fstring(const fstring& other) throw();
00157
00158
00159 ~fstring() throw();
00160
00161
00162 fstring(const char* s) :
00163 m_rep(0)
00164 {
00165 init_range(char_range(s, s ? strlen(s) : 0));
00166 }
00167
00168
00169 explicit fstring(char_range r) :
00170 m_rep(0)
00171 {
00172 init_range(r);
00173 }
00174
00175
00176 void swap(fstring& other) throw();
00177
00178
00179 fstring& operator=(const char* text);
00180
00181
00182 fstring& operator=(const fstring& other) throw();
00183
00184
00185 const char* c_str() const throw() { return m_rep->text(); }
00186
00187
00188 std::size_t length() const throw() { return m_rep->length(); }
00189
00190
00191 bool is_empty() const throw() { return (length() == 0); }
00192
00193
00194 bool empty() const throw() { return is_empty(); }
00195
00196
00197 char operator[](unsigned int i) const { return m_rep->text()[i]; }
00198
00199
00200 void clear();
00201
00202
00203
00204
00205
00206
00207 bool ends_with(const fstring& ext) const throw();
00208
00209
00210
00211
00212
00213
00214 bool equals(const char* other) const throw();
00215
00216 bool equals(const fstring& other) const throw();
00217
00218
00219 bool operator<(const char* other) const throw();
00220
00221
00222 template <class string_type>
00223 bool operator<(const string_type& other) const throw()
00224 {
00225 return operator<(other.c_str());
00226 }
00227
00228
00229 bool operator>(const char* other) const throw();
00230
00231
00232 template <class string_type>
00233 bool operator>(const string_type& other) const throw()
00234 {
00235 return operator>(other.c_str());
00236 }
00237
00238
00239
00240
00241
00242
00243 void read(std::istream& is);
00244
00245
00246 void readsome(std::istream& is, unsigned int count);
00247
00248
00249 void write(std::ostream& os) const;
00250
00251
00252 void readline(std::istream& is, char eol = '\n');
00253
00254
00255
00256
00257
00258
00259 bool operator==(const char* rhs) const throw() { return equals(rhs); }
00260
00261 bool operator==(const fstring& rhs) const throw() { return equals(rhs); }
00262
00263
00264 bool operator!=(const char* rhs) const throw() { return !equals(rhs); }
00265
00266 bool operator!=(const fstring& rhs) const throw() { return !equals(rhs); }
00267
00268
00269 void debug_dump() const throw();
00270
00271 private:
00272 void init_empty();
00273
00274 void init_range(char_range r);
00275
00276
00277
00278 fstring(string_rep* r);
00279
00280 string_rep* m_rep;
00281 };
00282
00283
00284 fstring sconvert(char x);
00285 fstring sconvert(const char* x);
00286 fstring sconvert(const fstring& x);
00287
00288 fstring sconvert(bool x);
00289 fstring sconvert(int x);
00290 fstring sconvert(unsigned int x);
00291 fstring sconvert(long x);
00292 fstring sconvert(unsigned long x);
00293 fstring sconvert(double x);
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 inline bool operator==(const char* lhs, const fstring& rhs) throw()
00305 { return rhs.equals(lhs); }
00306
00307
00308
00309 inline bool operator!=(const char* lhs, const fstring& rhs) throw()
00310 { return !rhs.equals(lhs); }
00311
00312
00313
00314
00315
00316
00317
00318 inline std::istream& operator>>(std::istream& is, fstring& str)
00319 {
00320 str.read(is); return is;
00321 }
00322
00323 inline std::ostream& operator<<(std::ostream& os, const fstring& str)
00324 {
00325 str.write(os); return os;
00326 }
00327
00328 inline std::istream& getline(std::istream& is, fstring& str)
00329 {
00330 str.readline(is); return is;
00331 }
00332
00333 inline std::istream& getline(std::istream& is, fstring& str, char eol)
00334 {
00335 str.readline(is, eol); return is;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 namespace debug
00345 {
00346 inline void eval (const char* what, int level, const char* where,
00347 int line_no, bool nl, rutz::fstring expr) throw()
00348 {
00349 eval(what, level, where, line_no, nl, expr.c_str());
00350 }
00351 }
00352
00353 }
00354
00355 static const char __attribute__((used)) vcid_groovx_rutz_fstring_h_utc20050626084021[] = "$Id: fstring.h 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn:
00356 #endif // !GROOVX_RUTZ_FSTRING_H_UTC20050626084021_DEFINED