00001
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
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 {
00047
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
00133
00147
00148
00149 class fstring
00150 {
00151 public:
00153 fstring();
00154
00156 fstring(const fstring& other) throw();
00157
00159 ~fstring() throw();
00160
00162 fstring(const char* s) :
00163 m_rep(0)
00164 {
00165 init_range(char_range(s, s ? strlen(s) : 0));
00166 }
00167
00169 explicit fstring(char_range r) :
00170 m_rep(0)
00171 {
00172 init_range(r);
00173 }
00174
00176 void swap(fstring& other) throw();
00177
00179 fstring& operator=(const char* text);
00180
00182 fstring& operator=(const fstring& other) throw();
00183
00185 const char* c_str() const throw() { return m_rep->text(); }
00186
00188 std::size_t length() const throw() { return m_rep->length(); }
00189
00191 bool is_empty() const throw() { return (length() == 0); }
00192
00194 bool empty() const throw() { return is_empty(); }
00195
00197 char operator[](unsigned int i) const { return m_rep->text()[i]; }
00198
00200 void clear();
00201
00202
00203
00204
00205
00207 bool ends_with(const fstring& ext) const throw();
00208
00209
00210
00211
00212
00214 bool equals(const char* other) const throw();
00216 bool equals(const fstring& other) const throw();
00217
00219 bool operator<(const char* other) const throw();
00220
00222 template <class string_type>
00223 bool operator<(const string_type& other) const throw()
00224 {
00225 return operator<(other.c_str());
00226 }
00227
00229 bool operator>(const char* other) const throw();
00230
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
00243 void read(std::istream& is);
00244
00246 void readsome(std::istream& is, unsigned int count);
00247
00249 void write(std::ostream& os) const;
00250
00252 void readline(std::istream& is, char eol = '\n');
00253
00254
00255
00256
00257
00259 bool operator==(const char* rhs) const throw() { return equals(rhs); }
00261 bool operator==(const fstring& rhs) const throw() { return equals(rhs); }
00262
00264 bool operator!=(const char* rhs) const throw() { return !equals(rhs); }
00266 bool operator!=(const fstring& rhs) const throw() { return !equals(rhs); }
00267
00269 void debug_dump() const throw();
00270
00271 private:
00272 void init_empty();
00273
00274 void init_range(char_range r);
00275
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
00297
00298
00299
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
00313
00314
00315
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
00339
00340
00341
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 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00356 #endif // !GROOVX_RUTZ_FSTRING_H_UTC20050626084021_DEFINED