fstring.h

Go to the documentation of this file.
00001 
00004 
00005 //
00006 // Copyright (c) 2000-2004 California Institute of Technology
00007 // Copyright (c) 2004-2007 University of Southern California
00008 // Rob Peters <rjpeters at usc dot edu>
00009 //
00010 // created: Fri Oct 15 15:40:18 2004
00011 // commit: $Id: fstring.h 10065 2007-04-12 05:54:56Z rjpeters $
00012 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/fstring.h $
00013 //
00014 // --------------------------------------------------------------------
00015 //
00016 // This file is part of GroovX.
00017 //   [http://ilab.usc.edu/rjpeters/groovx/]
00018 //
00019 // GroovX is free software; you can redistribute it and/or modify it
00020 // under the terms of the GNU General Public License as published by
00021 // the Free Software Foundation; either version 2 of the License, or
00022 // (at your option) any later version.
00023 //
00024 // GroovX is distributed in the hope that it will be useful, but
00025 // WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027 // General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License
00030 // along with GroovX; if not, write to the Free Software Foundation,
00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
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     // Class-specific operator new.
00086     void* operator new(std::size_t bytes);
00087 
00088     // Class-specific operator delete.
00089     void operator delete(void* space);
00090 
00091     // Constructor builds a string_rep with ref-count 0. 'length' here
00092     // does NOT need to "+1" for a null-terminator
00093     string_rep(std::size_t length, const char* text, std::size_t capacity=0);
00094 
00095     ~string_rep() throw();
00096 
00097     // To be called once via pthread_once()
00098     static void initialize_empty_rep();
00099 
00100     // Member functions whose names are prefixed with "uniq_" require
00101     // as a precondition that the string_rep object be unshared. In
00102     // order to ensure thread safety, such mutating calls are private
00103     // and can be made only during the process of construction of a
00104     // string_rep object.
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); // not implemented
00113     string_rep& operator=(const string_rep& other); // not implemented
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     // default copy, dtor, assignment OK
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     // Substring operations
00204     //
00205 
00207     bool ends_with(const fstring& ext) const throw();
00208 
00209     //
00210     // Comparison operators
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     // Input/Output
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     // Operators
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   // Overloaded operators
00299   //
00301 
00302   // operator ==
00303 
00304   inline bool operator==(const char* lhs, const fstring& rhs) throw()
00305   { return rhs.equals(lhs); }
00306 
00307   // operator !=
00308 
00309   inline bool operator!=(const char* lhs, const fstring& rhs) throw()
00310   { return !rhs.equals(lhs); }
00311 
00313   //
00314   // Input/Output functions
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   // Overload of rutz::debug::eval() (used in dbg_eval macros)
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 } // end namespace rutz
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

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:40 2008 by Doxygen version 1.5.5.