]> git.lyx.org Git - lyx.git/blobdiff - src/support/lyxstring.h
the fstream/iostream changes and some small other things
[lyx.git] / src / support / lyxstring.h
index 48f08830094f819483e84004f09ec4731578158a..fdcdf71900c75d67a0a373204af3710d27909fbe 100644 (file)
@@ -7,11 +7,17 @@
  *         Copyright (C) 1995 Matthias Ettrich
  *          Copyright (C) 1995-1999 The LyX Team.
  *
- *======================================================*/
+ * ====================================================== */
 
 // This one is heavily based on the string class in The C++
 // Programming Language by Bjarne Stroustrup
 
+// This class is supposed to be functionaly equivalent to a
+// standard conformant string. This mean among others that we
+// are useing the same requirements. Before you change anything
+// in this file consult me and/or the standard to discover the
+// right behavior.
+
 #ifndef LYXSTRING_H
 #define LYXSTRING_H 
 
 #pragma interface
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include <config.h> // needed at least for compilers that do not
-#endif              // understand `explicit' (JMarc)
+#include "LOstream.h"
+#include "LIstream.h"
 
 #if 0
 #include <iterator>
 #endif
 
-#include <cstring>
-#include "LAssert.h"
+#include <cstring> // for size_t
+
 /** A string class for LyX
   
   This is a permanent String class. It is modeled closely after the C++ STL
-  string class. In comparison with STL string LString lack support for
-  reverse iterators and allocators, in all other senses it is written to be
-  a drop in replacement for STL string (or as a transition tool). So
-  documentation for STL string should be valid for LString too.
+  string class. In comparison with STL string lyxstring lack support for
+  reverse iterators and allocators, also char_traits is not used. In most
+  other senses it is written to be  a drop in replacement for STL string
+  (or as a transition tool). So documentation for STL string should be
+  valid for lyxstring too.
 
   Notes for usage:
 
-  When you declare an LString, it is initially empty. There is no need to
-  do things like #LString a= "";#, especially not in constructors.
+  When you declare an lyxstring, it is initially empty. There is no need to
+  do things like #lyxstring a= "";#, especially not in constructors.
 
-  If you want to use a default empty LString as a parameter, use
+  If you want to use a default empty lyxstring as a parameter, use
   
-       #void foo(LString par = LString());     // Correct#
+       #void foo(lyxstring par = lyxstring()); // Correct#
   
   rather than
 
-       #void foo(LString par = "");    // WRONG!#
-       #void foo(LString par = 0);     // WRONG!#
+       #void foo(lyxstring par = "");  // WRONG!#
+       #void foo(lyxstring par = 0);   // WRONG!#
 
   (The last one is only wrong because some compilers can't handle it.)
 
@@ -60,7 +66,7 @@
   Wrong:   & #bar.substring(0, length());#
   \end{tabular}
   
-  It is important that you declare LStrings as const if possible, because
+  It is important that you declare lyxstring as const if possible, because
   some methods are much more efficient in const versions.
   
   If you want to check whether a string is empty, do
 
        #if (!foo) completely wrong#
 
-When you want to copy an LString, just do
+When you want to copy an lyxstring, just do
   
-       #LString a, b = "String";#
+       #lyxstring a, b = "String";#
        #a = b; // That's it!#
 
   not something like
   
-       #LString a, b = "String";#
-       #a = b.copy(); // This leaks.#
+       #lyxstring a, b = "String";#
+       #a = b.copy(); // This leaks. // and does not work either. #
   
   The class automatically handles deep copying when required.
 */
@@ -113,10 +119,10 @@ public:
 #if 0
        ///
        typedef reverse_iterator<iterator, value_type, reference>
-reverse_iterator;
+       reverse_iterator;
        ///
        typedef reverse_iterator<const_iterator, const value_type,
-const_reference> const_reverse_iterator;
+               const_reference> const_reverse_iterator;
 
 #endif
        //@}
@@ -149,7 +155,7 @@ const_reference> const_reverse_iterator;
        static const size_type npos;
 
        /// #lyxstring x;# 
-       inline lyxstring();
+       lyxstring();
        
        /// #lyxstring x(lyxstring ...)# 
        lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
@@ -163,11 +169,21 @@ const_reference> const_reverse_iterator;
        /// lyxstring(5, 'n') -> "nnnnn"
        lyxstring(size_type n, value_type c);
 
+#if 1
        ///
-       lyxstring(iterator first, iterator last);
-       
+       lyxstring(const_iterator first, const_iterator last);
+#else
+       ///
+       template<class InputIterator>
+       lyxstring::lyxstring(InputIterator begin, InputIterator end) {
+               while (begin != end) {
+                       push_back((*begin));
+                       ++begin;
+               }
+       }
+#endif
        ///
-       ~lyxstring() { if (--rep->ref == 0) delete rep; }
+       ~lyxstring();
 
        //@}
 
@@ -176,10 +192,10 @@ const_reference> const_reverse_iterator;
        //@{
        
        /// number of characters
-       size_type size() const; // { return rep->sz; }
+       size_type size() const;
 
        /// largest possible string
-       size_type max_size() const { return npos -1; }
+       size_type max_size() const { return npos - 1; }
 
        ///
        size_type length() const { return size(); }
@@ -201,7 +217,6 @@ const_reference> const_reverse_iterator;
        
        //@}
 
-
        /**@name Assignment */
        //@{
 
@@ -229,9 +244,20 @@ const_reference> const_reverse_iterator;
        ///
        lyxstring & assign(size_type n, value_type c);
 
+#if 1
        ///
-       lyxstring & assign(iterator first, iterator last);
-       
+       lyxstring & assign(const_iterator first, const_iterator last);
+#else
+       ///
+       template<class InputIterator>
+       lyxstring & assign(InputIterator begin, InputIterator end) {
+               clear;
+               while (begin != end) {
+                       push_back((*begin));
+                       ++begin;
+               }
+       }
+#endif
        //@}
 
        /**@name Element Access. Since lyxstring does not use exceptions,
@@ -251,7 +277,6 @@ const_reference> const_reverse_iterator;
 
        //@}
 
-       
        /**@name Insert */
        //@{
        
@@ -264,7 +289,7 @@ const_reference> const_reverse_iterator;
        lyxstring & operator+=(value_type const *);
        
        ///
-       inline lyxstring & operator+=(value_type);
+       lyxstring & operator+=(value_type);
 
        ///
        void push_back(value_type);
@@ -284,9 +309,20 @@ const_reference> const_reverse_iterator;
        ///
        lyxstring & append(size_type n, value_type);
 
+#if 1
        ///
        lyxstring & append(iterator first, iterator last);
-       
+#else
+       ///
+       template<class InputIterator>
+       lyxstring & append(InputIterator begin, InputIterator end) {
+               while (begin != end) {
+                       push_back((*begin));
+                       ++begin;
+               }
+               return *this;
+       }
+#endif
        // insert characters before (*this)[pos]:
 
        ///
@@ -314,8 +350,20 @@ const_reference> const_reverse_iterator;
        ///
        void insert(iterator p, size_type n , value_type c);
 
+#if 1
        ///
        void insert(iterator p, iterator first, iterator last);
+#else
+       ///
+       template<class InputIterator>
+       void insert(iterator p, InputIterator begin, InputIterator end) {
+               iterator it;
+               while (begin != end) {
+                       it = insert(p, (*begin));
+                       ++begin;
+               }
+       }
+#endif
        
        //@}
 
@@ -351,7 +399,8 @@ const_reference> const_reverse_iterator;
        size_type find_first_of(lyxstring const &, size_type i = 0) const;
        
        ///
-       size_type find_first_of(value_type const * p, size_type i, size_type n) const;
+       size_type find_first_of(value_type const * p, size_type i,
+                               size_type n) const;
        
        ///
        size_type find_first_of(value_type const * p, size_type i = 0) const;
@@ -363,7 +412,8 @@ const_reference> const_reverse_iterator;
        size_type find_last_of(lyxstring const &, size_type i = npos) const;
        
        ///
-       size_type find_last_of(value_type const * p, size_type i, size_type n) const;
+       size_type find_last_of(value_type const * p, size_type i,
+                              size_type n) const;
        
        ///
        size_type find_last_of(value_type const * p, size_type i = npos) const;
@@ -379,20 +429,23 @@ const_reference> const_reverse_iterator;
                                    size_type n) const;
        
        ///
-       size_type find_first_not_of(value_type const * p, size_type i = 0) const;
+       size_type find_first_not_of(value_type const * p,
+                                   size_type i = 0) const;
        
        ///
        size_type find_first_not_of(value_type c, size_type i = 0) const;
 
        ///
-       size_type find_last_not_of(lyxstring const &, size_type i = npos) const;
+       size_type find_last_not_of(lyxstring const &,
+                                  size_type i = npos) const;
        
        ///
        size_type find_last_not_of(value_type const * p, size_type i,
                                   size_type n) const;
        
        ///
-       size_type find_last_not_of(value_type const * p, size_type i = npos) const;
+       size_type find_last_not_of(value_type const * p,
+                                  size_type i = npos) const;
        
        ///
        size_type find_last_not_of(value_type c, size_type i = npos) const;
@@ -406,21 +459,22 @@ const_reference> const_reverse_iterator;
        // replace [(*this)[i], (*this)[i+n]] with other characters:
 
        ///
-       lyxstring & replace(size_type i,size_type n, lyxstring const & str);
+       lyxstring & replace(size_type i, size_type n, lyxstring const & str);
 
        ///
-       lyxstring & replace(size_type i,size_type n, lyxstring const & s,
+       lyxstring & replace(size_type i, size_type n, lyxstring const & s,
                          size_type i2, size_type n2);
 
        ///
-       lyxstring & replace(size_type i,size_type n, value_type const * p,
+       lyxstring & replace(size_type i, size_type n, value_type const * p,
                          size_type n2);
 
        ///
-       lyxstring & replace(size_type i,size_type n, value_type const * p);
+       lyxstring & replace(size_type i, size_type n, value_type const * p);
 
        ///
-       lyxstring & replace(size_type i, size_type n, size_type n2, value_type c);
+       lyxstring & replace(size_type i, size_type n,
+                           size_type n2, value_type c);
 
        ///
        lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
@@ -433,11 +487,15 @@ const_reference> const_reverse_iterator;
        lyxstring & replace(iterator i, iterator i2, value_type const * p);
 
        ///
-       lyxstring & replace(iterator i, iterator i2, size_type n , value_type c);
-       
+       lyxstring & replace(iterator i, iterator i2,
+                           size_type n , value_type c);
+
        ///
        lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
 
+       ///
+       void swap(lyxstring & str);
+       
        /// Erase n chars from position i.
        lyxstring & erase(size_type i = 0, size_type n = npos);
 
@@ -468,7 +526,8 @@ const_reference> const_reverse_iterator;
        /** This one returns a verbatim copy. Not the trailing '\0'
          The caller must provide a buffer with engough room.
          */
-       size_type copy(value_type * buf, size_type len, size_type pos = 0) const;
+       size_type copy(value_type * buf, size_type len,
+                      size_type pos = 0) const;
 
        //@}
 
@@ -506,81 +565,44 @@ const_reference> const_reverse_iterator;
        //@}
 
 private:
-       ///
-       lyxstring & operator+(int);
-       ///
-       lyxstring & operator=(int);
-       ///
-       lyxstring & operator+=(int);
-       
-       /// A string representation
-       struct Srep {
-               ///
-               static lyxstring::size_type const xtra = 
-                                       static_cast<lyxstring::size_type>(8);
-               /// size
-               lyxstring::size_type sz;
-               /// Reference count
-               unsigned short ref;
-               /// The total amount of data reserved for this representaion
-               lyxstring::size_type res;
-               /// Data. At least 1 char for trailing null.
-               lyxstring::value_type * s;
-
-               ///
-               Srep(lyxstring::size_type nsz, const lyxstring::value_type * p);
-               ///
-               Srep(lyxstring::size_type nsz, lyxstring::value_type ch);
-               ///
-               ~Srep() { delete[] s; }
-               ///
-               Srep * get_own_copy()
-               {
-                       if (ref == 1) return this;
-                       ref--;
-                       return new Srep(sz, s);
-               }
+       // These three operators can be used to discover erronous use of
+       // ints and strings. However a conforming C++ compiler will flag
+       // a lot of char operations as ambigous when they are compiled
+       // in. Use them for debugging only (or perhaps not even then.)
+       // Lgb.
+       //
+       //lyxstring & operator+(int);
+       //
+       //lyxstring & operator=(int);
+       //
+       //lyxstring & operator+=(int);
+
+       /// Compare this with s. works with embedded '\0' chars also.
+       int internal_compare(size_type pos, size_type n,
+                            value_type const * s,
+                            size_type slen, size_type n2) const;
                
-               ///
-               void assign(lyxstring::size_type nsz, const lyxstring::value_type * p);
-               ///
-               void assign(lyxstring::size_type nsz, lyxstring::value_type ch);
-               ///
-               void append(lyxstring::size_type asz, const lyxstring::value_type * p);
-               ///
-               void push_back(lyxstring::value_type c);
-               ///
-               void insert(lyxstring::size_type pos,
-                           const lyxstring::value_type * p,
-                           lyxstring::size_type n);
-               ///
-               void resize(lyxstring::size_type n, lyxstring::value_type c);
-               ///
-               void reserve(lyxstring::size_type res_arg);
-               ///
-               void replace(lyxstring::size_type i, lyxstring::size_type n,
-                            lyxstring::value_type const * p, lyxstring::size_type n2);
-       private:
-               Srep(const Srep &);
-               Srep & operator=(const Srep &);
-       };
-
-       /** The empty_rep is a local static in each function that
+       /// Forward declaration of the string representation
+       struct Srep;
+       // DEC cxx requires this.
+       friend struct Srep;
+
+       /// A string is a pointer to it's representation
+       Srep * rep;
+
+       /** Note: The empty_rep is a local static in each function that
            benefits from one. There is no "global" empty srep but lyxstring
            doesn't need one (no code actually relies upon a single
            empty srep).
            This overcomes *all* "static initialization" problems,
            at maximum speed, with a small overhead of a few local static
            empty_reps.
-        */
-
-       /// A string is a pointer to it's representation
-       Srep * rep;
+       */
 
 #ifdef DEVEL_VERSION
        /// lyxstringInvariant is used to test the lyxstring Invariant
        friend class lyxstringInvariant;
-#endif //DEVEL_VERSION
+#endif
 };
 
 // The usual comparison operators ==, !=, >, <, >=, <= are
@@ -624,7 +646,8 @@ lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
 
-class istream; class ostream;
+void swap(lyxstring & s1, lyxstring & s2);
+
 istream & operator>>(istream &, lyxstring &);
 ostream & operator<<(ostream &, lyxstring const &);
 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');