2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright (C) 1995 Matthias Ettrich
8 * Copyright (C) 1995-1999 The LyX Team.
10 *======================================================*/
12 // This one is heavily based on the string class in The C++
13 // Programming Language by Bjarne Stroustrup
15 // This class is supposed to be functionaly equivalent to a
16 // standard conformant string. This mean among others that we
17 // are useing the same requirements. Before you change anything
18 // in this file consult me and/or the standard to discover the
29 #include <config.h> // needed at least for compilers that do not
30 #endif // understand `explicit' (JMarc)
36 #include <cstring> // for size_t
38 /** A string class for LyX
40 This is a permanent String class. It is modeled closely after the C++ STL
41 string class. In comparison with STL string lyxstring lack support for
42 reverse iterators and allocators, also char_traits is not used. In most
43 other senses it is written to be a drop in replacement for STL string
44 (or as a transition tool). So documentation for STL string should be
45 valid for lyxstring too.
49 When you declare an lyxstring, it is initially empty. There is no need to
50 do things like #lyxstring a= "";#, especially not in constructors.
52 If you want to use a default empty lyxstring as a parameter, use
54 #void foo(lyxstring par = lyxstring()); // Correct#
58 #void foo(lyxstring par = ""); // WRONG!#
59 #void foo(lyxstring par = 0); // WRONG!#
61 (The last one is only wrong because some compilers can't handle it.)
63 Methods that take an index as parameter all follow this rule: Valid indexes
64 go from 0 to length()-1.
66 Correct: & #foo.substring(0, length()-1);# \\
67 Wrong: & #bar.substring(0, length());#
70 It is important that you declare lyxstring as const if possible, because
71 some methods are much more efficient in const versions.
73 If you want to check whether a string is empty, do
75 #if (foo.empty()) something right#
77 rather than something along the lines of
79 #if (!foo) completely wrong#
81 When you want to copy an lyxstring, just do
83 #lyxstring a, b = "String";#
84 #a = b; // That's it!#
88 #lyxstring a, b = "String";#
89 #a = b.copy(); // This leaks. // and does not work either. #
91 The class automatically handles deep copying when required.
99 typedef char value_type;
102 typedef value_type * pointer;
105 typedef value_type & reference;
108 typedef value_type const & const_reference;
111 typedef size_t size_type;
114 typedef int difference_type;
117 typedef value_type * iterator;
119 typedef const value_type * const_iterator;
122 typedef reverse_iterator<iterator, value_type, reference>
125 typedef reverse_iterator<const_iterator, const value_type,
126 const_reference> const_reverse_iterator;
134 const_iterator begin() const;
138 const_iterator end() const;
141 reverse_iterator rbegin();
143 const_reverse_iterator rbegin() const;
145 reverse_iterator rend();
147 const_reverse_iterator rend() const;
149 /**@name Constructors and Deconstructors. lyxstring has the same
150 constructors as STL, except the one using iterators, one other
151 difference is that lyxstring, do not allow the optional allocator
155 /// "all characters" marker
156 static const size_type npos;
161 /// #lyxstring x(lyxstring ...)#
162 lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
164 /// #lyxstring x("abc", 2) -> "ab"#
165 lyxstring(value_type const *, size_type n);
167 /// #lyxstring x("abc")#
168 lyxstring(value_type const *);
170 /// lyxstring(5, 'n') -> "nnnnn"
171 lyxstring(size_type n, value_type c);
174 lyxstring(iterator first, iterator last);
182 /**@name Size and Capacity */
185 /// number of characters
186 size_type size() const;
188 /// largest possible string
189 size_type max_size() const { return npos -1; }
192 size_type length() const { return size(); }
195 bool empty() const { return size() == 0; }
198 void resize(size_type n, value_type c);
201 void resize(size_type n) { resize(n, ' '); }
203 /// size of the memory (in number of elements) allocated.
204 size_type capacity() const;
207 void reserve(size_type res_arg = 0);
211 /**@name Assignment */
215 lyxstring & operator=(lyxstring const &);
218 lyxstring & operator=(value_type const *);
221 lyxstring & operator=(value_type);
224 lyxstring & assign(lyxstring const &);
227 lyxstring & assign(lyxstring const &, size_type pos, size_type n);
230 lyxstring & assign(value_type const * p, size_type n);
233 lyxstring & assign(value_type const * p);
236 lyxstring & assign(size_type n, value_type c);
239 lyxstring & assign(iterator first, iterator last);
243 /**@name Element Access. Since lyxstring does not use exceptions,
244 an abort is called on out-of-range access to at(). */
247 const_reference operator[](size_type) const;
250 reference operator[](size_type);
253 const_reference at(size_type) const;
256 reference at(size_type);
263 // add characters after (*this)[length()-1]:
266 lyxstring & operator+=(lyxstring const &);
269 lyxstring & operator+=(value_type const *);
272 lyxstring & operator+=(value_type);
275 void push_back(value_type);
278 lyxstring & append(lyxstring const &);
281 lyxstring & append(lyxstring const &, size_type pos, size_type n);
284 lyxstring & append(value_type const *, size_type n);
287 lyxstring & append(value_type const *);
290 lyxstring & append(size_type n, value_type);
293 lyxstring & append(iterator first, iterator last);
295 // insert characters before (*this)[pos]:
298 lyxstring & insert(size_type pos, lyxstring const &);
301 lyxstring & insert(size_type pos, lyxstring const &,
302 size_type pos2, size_type n);
305 lyxstring & insert(size_type pos, value_type const * p,
309 lyxstring & insert(size_type pos, value_type const * p);
312 lyxstring & insert(size_type pos, size_type n, value_type c);
314 // insert characters before p
317 iterator insert(iterator p, value_type c);
320 void insert(iterator p, size_type n , value_type c);
323 void insert(iterator p, iterator first, iterator last);
331 size_type find(lyxstring const &, size_type i = 0) const;
334 size_type find(value_type const * p,
335 size_type i, size_type n) const;
338 size_type find(value_type const * p, size_type i = 0) const;
341 size_type find(value_type c, size_type i = 0) const;
344 size_type rfind(lyxstring const &, size_type i = npos) const;
347 size_type rfind(value_type const * p, size_type i, size_type n) const;
350 size_type rfind(value_type const * p, size_type i = npos) const;
353 size_type rfind(value_type c, size_type i = npos) const;
356 size_type find_first_of(lyxstring const &, size_type i = 0) const;
359 size_type find_first_of(value_type const * p, size_type i,
363 size_type find_first_of(value_type const * p, size_type i = 0) const;
366 size_type find_first_of(value_type c, size_type i = 0) const;
369 size_type find_last_of(lyxstring const &, size_type i = npos) const;
372 size_type find_last_of(value_type const * p, size_type i,
376 size_type find_last_of(value_type const * p, size_type i = npos) const;
379 size_type find_last_of(value_type c, size_type i = npos) const;
382 size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
385 size_type find_first_not_of(value_type const * p, size_type i,
389 size_type find_first_not_of(value_type const * p,
390 size_type i = 0) const;
393 size_type find_first_not_of(value_type c, size_type i = 0) const;
396 size_type find_last_not_of(lyxstring const &,
397 size_type i = npos) const;
400 size_type find_last_not_of(value_type const * p, size_type i,
404 size_type find_last_not_of(value_type const * p,
405 size_type i = npos) const;
408 size_type find_last_not_of(value_type c, size_type i = npos) const;
416 // replace [(*this)[i], (*this)[i+n]] with other characters:
419 lyxstring & replace(size_type i,size_type n, lyxstring const & str);
422 lyxstring & replace(size_type i,size_type n, lyxstring const & s,
423 size_type i2, size_type n2);
426 lyxstring & replace(size_type i,size_type n, value_type const * p,
430 lyxstring & replace(size_type i,size_type n, value_type const * p);
433 lyxstring & replace(size_type i, size_type n,
434 size_type n2, value_type c);
437 lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
440 lyxstring & replace(iterator i, iterator i2,
441 value_type const * p, size_type n);
444 lyxstring & replace(iterator i, iterator i2, value_type const * p);
447 lyxstring & replace(iterator i, iterator i2,
448 size_type n , value_type c);
451 lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
453 /// Erase n chars from position i.
454 lyxstring & erase(size_type i = 0, size_type n = npos);
457 lyxstring & clear() {
458 return erase(0, npos);
462 iterator erase(iterator i);
465 iterator erase(iterator first, iterator last);
470 /**@name Conversion to C-style Strings */
474 value_type const * c_str() const;
476 /** Note that this is STL compilant, so you can not assume
477 that the returned array has a trailing '\0'. */
478 value_type const * data() const;
480 /** This one returns a verbatim copy. Not the trailing '\0'
481 The caller must provide a buffer with engough room.
483 size_type copy(value_type * buf, size_type len,
484 size_type pos = 0) const;
489 /**@name Comparisons. Combined > and == */
493 int compare(lyxstring const & str) const;
496 int compare(value_type const * p) const;
499 int compare(size_type pos, size_type n, lyxstring const & str) const;
502 int compare(size_type pos, size_type n, lyxstring const & str,
503 size_type pos2, size_type n2) const;
506 int compare(size_type pos, size_type n, value_type const * p,
507 size_type n2 = npos) const;
513 /**@name Substrings */
517 lyxstring substr(size_type i = 0, size_type n = npos) const;
523 lyxstring & operator+(int);
525 lyxstring & operator=(int);
527 lyxstring & operator+=(int);
529 /// Forward declaration of the string representation
532 /// A string is a pointer to it's representation
535 /** Note: The empty_rep is a local static in each function that
536 benefits from one. There is no "global" empty srep but lyxstring
537 doesn't need one (no code actually relies upon a single
539 This overcomes *all* "static initialization" problems,
540 at maximum speed, with a small overhead of a few local static
545 /// lyxstringInvariant is used to test the lyxstring Invariant
546 friend class lyxstringInvariant;
550 // The usual comparison operators ==, !=, >, <, >=, <= are
551 // provided for lyxstrings
553 bool operator==(lyxstring const &, lyxstring const &);
554 bool operator==(lyxstring::value_type const *, lyxstring const &);
555 bool operator==(lyxstring const &, lyxstring::value_type const *);
558 bool operator!=(lyxstring const &, lyxstring const &);
559 bool operator!=(lyxstring::value_type const *, lyxstring const &);
560 bool operator!=(lyxstring const &, lyxstring::value_type const *);
563 bool operator>(lyxstring const &, lyxstring const &);
564 bool operator>(lyxstring::value_type const *, lyxstring const &);
565 bool operator>(lyxstring const &, lyxstring::value_type const *);
568 bool operator<(lyxstring const &, lyxstring const &);
569 bool operator<(lyxstring::value_type const *, lyxstring const &);
570 bool operator<(lyxstring const &, lyxstring::value_type const *);
573 bool operator>=(lyxstring const &, lyxstring const &);
574 bool operator>=(lyxstring::value_type const *, lyxstring const &);
575 bool operator>=(lyxstring const &, lyxstring::value_type const *);
578 bool operator<=(lyxstring const &, lyxstring const &);
579 bool operator<=(lyxstring::value_type const *, lyxstring const &);
580 bool operator<=(lyxstring const &, lyxstring::value_type const *);
585 lyxstring operator+(lyxstring const & a, lyxstring const & b);
586 lyxstring operator+(char const * a, lyxstring const & b);
587 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
588 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
589 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
591 class istream; class ostream;
592 istream & operator>>(istream &, lyxstring &);
593 ostream & operator<<(ostream &, lyxstring const &);
594 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');