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)
39 #include <cstring> // for size_t
41 /** A string class for LyX
43 This is a permanent String class. It is modeled closely after the C++ STL
44 string class. In comparison with STL string lyxstring lack support for
45 reverse iterators and allocators, also char_traits is not used. In most
46 other senses it is written to be a drop in replacement for STL string
47 (or as a transition tool). So documentation for STL string should be
48 valid for lyxstring too.
52 When you declare an lyxstring, it is initially empty. There is no need to
53 do things like #lyxstring a= "";#, especially not in constructors.
55 If you want to use a default empty lyxstring as a parameter, use
57 #void foo(lyxstring par = lyxstring()); // Correct#
61 #void foo(lyxstring par = ""); // WRONG!#
62 #void foo(lyxstring par = 0); // WRONG!#
64 (The last one is only wrong because some compilers can't handle it.)
66 Methods that take an index as parameter all follow this rule: Valid indexes
67 go from 0 to length()-1.
69 Correct: & #foo.substring(0, length()-1);# \\
70 Wrong: & #bar.substring(0, length());#
73 It is important that you declare lyxstring as const if possible, because
74 some methods are much more efficient in const versions.
76 If you want to check whether a string is empty, do
78 #if (foo.empty()) something right#
80 rather than something along the lines of
82 #if (!foo) completely wrong#
84 When you want to copy an lyxstring, just do
86 #lyxstring a, b = "String";#
87 #a = b; // That's it!#
91 #lyxstring a, b = "String";#
92 #a = b.copy(); // This leaks. // and does not work either. #
94 The class automatically handles deep copying when required.
102 typedef char value_type;
105 typedef value_type * pointer;
108 typedef value_type & reference;
111 typedef value_type const & const_reference;
114 typedef size_t size_type;
117 typedef int difference_type;
120 typedef value_type * iterator;
122 typedef const value_type * const_iterator;
125 typedef reverse_iterator<iterator, value_type, reference>
128 typedef reverse_iterator<const_iterator, const value_type,
129 const_reference> const_reverse_iterator;
137 const_iterator begin() const;
141 const_iterator end() const;
144 reverse_iterator rbegin();
146 const_reverse_iterator rbegin() const;
148 reverse_iterator rend();
150 const_reverse_iterator rend() const;
152 /**@name Constructors and Deconstructors. lyxstring has the same
153 constructors as STL, except the one using iterators, one other
154 difference is that lyxstring, do not allow the optional allocator
158 /// "all characters" marker
159 static const size_type npos;
164 /// #lyxstring x(lyxstring ...)#
165 lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
167 /// #lyxstring x("abc", 2) -> "ab"#
168 lyxstring(value_type const *, size_type n);
170 /// #lyxstring x("abc")#
171 lyxstring(value_type const *);
173 /// lyxstring(5, 'n') -> "nnnnn"
174 lyxstring(size_type n, value_type c);
177 lyxstring(iterator first, iterator last);
185 /**@name Size and Capacity */
188 /// number of characters
189 size_type size() const;
191 /// largest possible string
192 size_type max_size() const { return npos -1; }
195 size_type length() const { return size(); }
198 bool empty() const { return size() == 0; }
201 void resize(size_type n, value_type c);
204 void resize(size_type n) { resize(n, ' '); }
206 /// size of the memory (in number of elements) allocated.
207 size_type capacity() const;
210 void reserve(size_type res_arg = 0);
214 /**@name Assignment */
218 lyxstring & operator=(lyxstring const &);
221 lyxstring & operator=(value_type const *);
224 lyxstring & operator=(value_type);
227 lyxstring & assign(lyxstring const &);
230 lyxstring & assign(lyxstring const &, size_type pos, size_type n);
233 lyxstring & assign(value_type const * p, size_type n);
236 lyxstring & assign(value_type const * p);
239 lyxstring & assign(size_type n, value_type c);
242 lyxstring & assign(iterator first, iterator last);
246 /**@name Element Access. Since lyxstring does not use exceptions,
247 an abort is called on out-of-range access to at(). */
250 const_reference operator[](size_type) const;
253 reference operator[](size_type);
256 const_reference at(size_type) const;
259 reference at(size_type);
266 // add characters after (*this)[length()-1]:
269 lyxstring & operator+=(lyxstring const &);
272 lyxstring & operator+=(value_type const *);
275 lyxstring & operator+=(value_type);
278 void push_back(value_type);
281 lyxstring & append(lyxstring const &);
284 lyxstring & append(lyxstring const &, size_type pos, size_type n);
287 lyxstring & append(value_type const *, size_type n);
290 lyxstring & append(value_type const *);
293 lyxstring & append(size_type n, value_type);
296 lyxstring & append(iterator first, iterator last);
298 // insert characters before (*this)[pos]:
301 lyxstring & insert(size_type pos, lyxstring const &);
304 lyxstring & insert(size_type pos, lyxstring const &,
305 size_type pos2, size_type n);
308 lyxstring & insert(size_type pos, value_type const * p,
312 lyxstring & insert(size_type pos, value_type const * p);
315 lyxstring & insert(size_type pos, size_type n, value_type c);
317 // insert characters before p
320 iterator insert(iterator p, value_type c);
323 void insert(iterator p, size_type n , value_type c);
326 void insert(iterator p, iterator first, iterator last);
334 size_type find(lyxstring const &, size_type i = 0) const;
337 size_type find(value_type const * p,
338 size_type i, size_type n) const;
341 size_type find(value_type const * p, size_type i = 0) const;
344 size_type find(value_type c, size_type i = 0) const;
347 size_type rfind(lyxstring const &, size_type i = npos) const;
350 size_type rfind(value_type const * p, size_type i, size_type n) const;
353 size_type rfind(value_type const * p, size_type i = npos) const;
356 size_type rfind(value_type c, size_type i = npos) const;
359 size_type find_first_of(lyxstring const &, size_type i = 0) const;
362 size_type find_first_of(value_type const * p, size_type i,
366 size_type find_first_of(value_type const * p, size_type i = 0) const;
369 size_type find_first_of(value_type c, size_type i = 0) const;
372 size_type find_last_of(lyxstring const &, size_type i = npos) const;
375 size_type find_last_of(value_type const * p, size_type i,
379 size_type find_last_of(value_type const * p, size_type i = npos) const;
382 size_type find_last_of(value_type c, size_type i = npos) const;
385 size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
388 size_type find_first_not_of(value_type const * p, size_type i,
392 size_type find_first_not_of(value_type const * p,
393 size_type i = 0) const;
396 size_type find_first_not_of(value_type c, size_type i = 0) const;
399 size_type find_last_not_of(lyxstring const &,
400 size_type i = npos) const;
403 size_type find_last_not_of(value_type const * p, size_type i,
407 size_type find_last_not_of(value_type const * p,
408 size_type i = npos) const;
411 size_type find_last_not_of(value_type c, size_type i = npos) const;
419 // replace [(*this)[i], (*this)[i+n]] with other characters:
422 lyxstring & replace(size_type i,size_type n, lyxstring const & str);
425 lyxstring & replace(size_type i,size_type n, lyxstring const & s,
426 size_type i2, size_type n2);
429 lyxstring & replace(size_type i,size_type n, value_type const * p,
433 lyxstring & replace(size_type i,size_type n, value_type const * p);
436 lyxstring & replace(size_type i, size_type n,
437 size_type n2, value_type c);
440 lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
443 lyxstring & replace(iterator i, iterator i2,
444 value_type const * p, size_type n);
447 lyxstring & replace(iterator i, iterator i2, value_type const * p);
450 lyxstring & replace(iterator i, iterator i2,
451 size_type n , value_type c);
454 lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
456 /// Erase n chars from position i.
457 lyxstring & erase(size_type i = 0, size_type n = npos);
460 lyxstring & clear() {
461 return erase(0, npos);
465 iterator erase(iterator i);
468 iterator erase(iterator first, iterator last);
473 /**@name Conversion to C-style Strings */
477 value_type const * c_str() const;
479 /** Note that this is STL compilant, so you can not assume
480 that the returned array has a trailing '\0'. */
481 value_type const * data() const;
483 /** This one returns a verbatim copy. Not the trailing '\0'
484 The caller must provide a buffer with engough room.
486 size_type copy(value_type * buf, size_type len,
487 size_type pos = 0) const;
492 /**@name Comparisons. Combined > and == */
496 int compare(lyxstring const & str) const;
499 int compare(value_type const * p) const;
502 int compare(size_type pos, size_type n, lyxstring const & str) const;
505 int compare(size_type pos, size_type n, lyxstring const & str,
506 size_type pos2, size_type n2) const;
509 int compare(size_type pos, size_type n, value_type const * p,
510 size_type n2 = npos) const;
516 /**@name Substrings */
520 lyxstring substr(size_type i = 0, size_type n = npos) const;
525 // These three operators can be used to discover erronous use of
526 // ints and strings. However a conforming C++ compiler will flag
527 // a lot of char operations as ambigous when they are compiled
528 // in. Use them for debugging only (or perhaps not even then.)
531 //lyxstring & operator+(int);
533 //lyxstring & operator=(int);
535 //lyxstring & operator+=(int);
537 /// Compare this with s. works with embedded '\0' chars also.
538 int internal_compare(size_type pos, size_type n,
539 value_type const * s,
540 size_type slen, size_type n2) const;
542 /// Forward declaration of the string representation
544 // DEC cxx requires this.
547 /// A string is a pointer to it's representation
550 /** Note: The empty_rep is a local static in each function that
551 benefits from one. There is no "global" empty srep but lyxstring
552 doesn't need one (no code actually relies upon a single
554 This overcomes *all* "static initialization" problems,
555 at maximum speed, with a small overhead of a few local static
560 /// lyxstringInvariant is used to test the lyxstring Invariant
561 friend class lyxstringInvariant;
565 // The usual comparison operators ==, !=, >, <, >=, <= are
566 // provided for lyxstrings
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 *);
583 bool operator<(lyxstring const &, lyxstring const &);
584 bool operator<(lyxstring::value_type const *, lyxstring const &);
585 bool operator<(lyxstring const &, lyxstring::value_type const *);
588 bool operator>=(lyxstring const &, lyxstring const &);
589 bool operator>=(lyxstring::value_type const *, lyxstring const &);
590 bool operator>=(lyxstring const &, lyxstring::value_type const *);
593 bool operator<=(lyxstring const &, lyxstring const &);
594 bool operator<=(lyxstring::value_type const *, lyxstring const &);
595 bool operator<=(lyxstring const &, lyxstring::value_type const *);
600 lyxstring operator+(lyxstring const & a, lyxstring const & b);
601 lyxstring operator+(char const * a, lyxstring const & b);
602 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
603 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
604 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
606 istream & operator>>(istream &, lyxstring &);
607 ostream & operator<<(ostream &, lyxstring const &);
608 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');