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
23 #include <config.h> // needed at least for compilers that do not
24 #endif // understand `explicit' (JMarc)
32 /** A string class for LyX
34 This is a permanent String class. It is modeled closely after the C++ STL
35 string class. In comparison with STL string LString lack support for
36 reverse iterators and allocators, in all other senses it is written to be
37 a drop in replacement for STL string (or as a transition tool). So
38 documentation for STL string should be valid for LString too.
42 When you declare an LString, it is initially empty. There is no need to
43 do things like #LString a= "";#, especially not in constructors.
45 If you want to use a default empty LString as a parameter, use
47 #void foo(LString par = LString()); // Correct#
51 #void foo(LString par = ""); // WRONG!#
52 #void foo(LString par = 0); // WRONG!#
54 (The last one is only wrong because some compilers can't handle it.)
56 Methods that take an index as parameter all follow this rule: Valid indexes
57 go from 0 to length()-1.
59 Correct: & #foo.substring(0, length()-1);# \\
60 Wrong: & #bar.substring(0, length());#
63 It is important that you declare LStrings as const if possible, because
64 some methods are much more efficient in const versions.
66 If you want to check whether a string is empty, do
68 #if (foo.empty()) something right#
70 rather than something along the lines of
72 #if (!foo) completely wrong#
74 When you want to copy an LString, just do
76 #LString a, b = "String";#
77 #a = b; // That's it!#
81 #LString a, b = "String";#
82 #a = b.copy(); // This leaks.#
84 The class automatically handles deep copying when required.
92 typedef char value_type;
95 typedef value_type * pointer;
98 typedef value_type & reference;
101 typedef const reference const_reference;
104 typedef size_t size_type;
107 typedef int difference_type;
110 typedef value_type * iterator;
112 typedef const value_type * const_iterator;
115 typedef reverse_iterator<iterator, value_type, reference>
118 typedef reverse_iterator<const_iterator, const value_type,
119 const_reference> const_reverse_iterator;
127 const_iterator begin() const;
131 const_iterator end() const;
134 reverse_iterator rbegin();
136 const_reverse_iterator rbegin() const;
138 reverse_iterator rend();
140 const_reverse_iterator rend() const;
142 /**@name Constructors and Deconstructors. lyxstring has the same
143 constructors as STL, except the one using iterators, one other
144 difference is that lyxstring, do not allow the optional allocator
148 /// "all characters" marker
149 static const size_type npos;
154 /// #lyxstring x(lyxstring ...)#
155 lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
157 /// #lyxstring x("abc", 2) -> "ab"#
158 lyxstring(value_type const *, size_type n);
160 /// #lyxstring x("abc")#
161 lyxstring(value_type const *);
163 /// lyxstring(5, 'n') -> "nnnnn"
164 lyxstring(size_type n, value_type c);
167 lyxstring(iterator first, iterator last);
170 ~lyxstring() { if (--rep->ref == 0) delete rep; }
175 /**@name Size and Capacity */
178 /// number of characters
179 size_type size() const; // { return rep->sz; }
181 /// largest possible string
182 size_type max_size() const { return npos -1; }
185 size_type length() const { return size(); }
188 bool empty() const { return size() == 0; }
191 void resize(size_type n, value_type c);
194 void resize(size_type n) { resize(n, ' '); }
196 /// size of the memory (in number of elements) allocated.
197 size_type capacity() const;
200 void reserve(size_type res_arg = 0);
205 /**@name Assignment */
209 lyxstring & operator=(lyxstring const &);
212 lyxstring & operator=(value_type const *);
215 lyxstring & operator=(value_type);
218 lyxstring & assign(lyxstring const &);
221 lyxstring & assign(lyxstring const &, size_type pos, size_type n);
224 lyxstring & assign(value_type const * p, size_type n);
227 lyxstring & assign(value_type const * p);
230 lyxstring & assign(size_type n, value_type c);
233 lyxstring & assign(iterator first, iterator last);
237 /**@name Element Access. Since lyxstring does not use exceptions,
238 an abort is called on out-of-range access to at(). */
241 const_reference operator[](size_type) const;
244 reference operator[](size_type);
247 const_reference at(size_type) const;
250 reference at(size_type);
258 // add characters after (*this)[length()-1]:
261 lyxstring & operator+=(lyxstring const &);
264 lyxstring & operator+=(value_type const *);
267 inline lyxstring & operator+=(value_type);
270 void push_back(value_type);
273 lyxstring & append(lyxstring const &);
276 lyxstring & append(lyxstring const &, size_type pos, size_type n);
279 lyxstring & append(value_type const *, size_type n);
282 lyxstring & append(value_type const *);
285 lyxstring & append(size_type n, value_type);
288 lyxstring & append(iterator first, iterator last);
290 // insert characters before (*this)[pos]:
293 lyxstring & insert(size_type pos, lyxstring const &);
296 lyxstring & insert(size_type pos, lyxstring const &,
297 size_type pos2, size_type n);
300 lyxstring & insert(size_type pos, value_type const * p,
304 lyxstring & insert(size_type pos, value_type const * p);
307 lyxstring & insert(size_type pos, size_type n, value_type c);
309 // insert characters before p
312 iterator insert(iterator p, value_type c);
315 void insert(iterator p, size_type n , value_type c);
318 void insert(iterator p, iterator first, iterator last);
326 size_type find(lyxstring const &, size_type i = 0) const;
329 size_type find(value_type const * p,
330 size_type i, size_type n) const;
333 size_type find(value_type const * p, size_type i = 0) const;
336 size_type find(value_type c, size_type i = 0) const;
339 size_type rfind(lyxstring const &, size_type i = npos) const;
342 size_type rfind(value_type const * p, size_type i, size_type n) const;
345 size_type rfind(value_type const * p, size_type i = npos) const;
348 size_type rfind(value_type c, size_type i = npos) const;
351 size_type find_first_of(lyxstring const &, size_type i = 0) const;
354 size_type find_first_of(value_type const * p, size_type i, size_type n) const;
357 size_type find_first_of(value_type const * p, size_type i = 0) const;
360 size_type find_first_of(value_type c, size_type i = 0) const;
363 size_type find_last_of(lyxstring const &, size_type i = npos) const;
366 size_type find_last_of(value_type const * p, size_type i, size_type n) const;
369 size_type find_last_of(value_type const * p, size_type i = npos) const;
372 size_type find_last_of(value_type c, size_type i = npos) const;
375 size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
378 size_type find_first_not_of(value_type const * p, size_type i,
382 size_type find_first_not_of(value_type const * p, size_type i = 0) const;
385 size_type find_first_not_of(value_type c, size_type i = 0) const;
388 size_type find_last_not_of(lyxstring const &, size_type i = npos) const;
391 size_type find_last_not_of(value_type const * p, size_type i,
395 size_type find_last_not_of(value_type const * p, size_type i = npos) const;
398 size_type find_last_not_of(value_type c, size_type i = npos) const;
406 // replace [(*this)[i], (*this)[i+n]] with other characters:
409 lyxstring & replace(size_type i,size_type n, lyxstring const & str);
412 lyxstring & replace(size_type i,size_type n, lyxstring const & s,
413 size_type i2, size_type n2);
416 lyxstring & replace(size_type i,size_type n, value_type const * p,
420 lyxstring & replace(size_type i,size_type n, value_type const * p);
423 lyxstring & replace(size_type i, size_type n, size_type n2, value_type c);
426 lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
429 lyxstring & replace(iterator i, iterator i2,
430 value_type const * p, size_type n);
433 lyxstring & replace(iterator i, iterator i2, value_type const * p);
436 lyxstring & replace(iterator i, iterator i2, size_type n , value_type c);
439 lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
441 /// Erase n chars from position i.
442 lyxstring & erase(size_type i = 0, size_type n = npos);
445 lyxstring & clear() {
446 return erase(0, npos);
450 iterator erase(iterator i);
453 iterator erase(iterator first, iterator last);
458 /**@name Conversion to C-style Strings */
462 value_type const * c_str() const;
464 /** Note that this is STL compilant, so you can not assume
465 that the returned array has a trailing '\0'. */
466 value_type const * data() const;
468 /** This one returns a verbatim copy. Not the trailing '\0'
469 The caller must provide a buffer with engough room.
471 size_type copy(value_type * buf, size_type len, size_type pos = 0) const;
476 /**@name Comparisons. Combined > and == */
480 int compare(lyxstring const & str) const;
483 int compare(value_type const * p) const;
486 int compare(size_type pos, size_type n, lyxstring const & str) const;
489 int compare(size_type pos, size_type n, lyxstring const & str,
490 size_type pos2, size_type n2) const;
493 int compare(size_type pos, size_type n, value_type const * p,
494 size_type n2 = npos) const;
500 /**@name Substrings */
504 lyxstring substr(size_type i = 0, size_type n = npos) const;
510 lyxstring & operator+(int);
512 lyxstring & operator=(int);
514 /// A string representation
517 static lyxstring::size_type const xtra =
518 static_cast<lyxstring::size_type>(8);
520 lyxstring::size_type sz;
523 /// The total amount of data reserved for this representaion
524 lyxstring::size_type res;
525 /// Data. At least 1 char for trailing null.
526 lyxstring::value_type * s;
529 Srep(lyxstring::size_type nsz, const lyxstring::value_type * p);
531 Srep(lyxstring::size_type nsz, lyxstring::value_type ch);
533 ~Srep() { delete[] s; }
535 Srep * get_own_copy()
537 if (ref == 1) return this;
539 return new Srep(sz, s);
543 void assign(lyxstring::size_type nsz, const lyxstring::value_type * p);
545 void assign(lyxstring::size_type nsz, lyxstring::value_type ch);
547 void append(lyxstring::size_type asz, const lyxstring::value_type * p);
549 void push_back(lyxstring::value_type c);
551 void insert(lyxstring::size_type pos,
552 const lyxstring::value_type * p,
553 lyxstring::size_type n);
555 void resize(lyxstring::size_type n, lyxstring::value_type c);
557 void reserve(lyxstring::size_type res_arg);
559 void replace(lyxstring::size_type i, lyxstring::size_type n,
560 lyxstring::value_type const * p, lyxstring::size_type n2);
563 Srep & operator=(const Srep &);
566 /** The empty_rep is a local static in each function that
567 benefits from one. There is no "global" empty srep but lyxstring
568 doesn't need one (no code actually relies upon a single
570 This overcomes *all* "static initialization" problems,
571 at maximum speed, with a small overhead of a few local static
575 /// A string is a pointer to it's representation
579 /// lyxstringInvariant is used to test the lyxstring Invariant
580 friend class lyxstringInvariant;
581 #endif //DEVEL_VERSION
584 // The usual comparison operators ==, !=, >, <, >=, <= are
585 // provided for lyxstrings
587 bool operator==(lyxstring const &, lyxstring const &);
588 bool operator==(lyxstring::value_type const *, lyxstring const &);
589 bool operator==(lyxstring const &, lyxstring::value_type const *);
592 bool operator!=(lyxstring const &, lyxstring const &);
593 bool operator!=(lyxstring::value_type const *, lyxstring const &);
594 bool operator!=(lyxstring const &, lyxstring::value_type const *);
597 bool operator>(lyxstring const &, lyxstring const &);
598 bool operator>(lyxstring::value_type const *, lyxstring const &);
599 bool operator>(lyxstring const &, lyxstring::value_type const *);
602 bool operator<(lyxstring const &, lyxstring const &);
603 bool operator<(lyxstring::value_type const *, lyxstring const &);
604 bool operator<(lyxstring const &, lyxstring::value_type const *);
607 bool operator>=(lyxstring const &, lyxstring const &);
608 bool operator>=(lyxstring::value_type const *, lyxstring const &);
609 bool operator>=(lyxstring const &, lyxstring::value_type const *);
612 bool operator<=(lyxstring const &, lyxstring const &);
613 bool operator<=(lyxstring::value_type const *, lyxstring const &);
614 bool operator<=(lyxstring const &, lyxstring::value_type const *);
619 lyxstring operator+(lyxstring const & a, lyxstring const & b);
620 lyxstring operator+(char const * a, lyxstring const & b);
621 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
622 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
623 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
625 class istream; class ostream;
626 istream & operator>>(istream &, lyxstring &);
627 ostream & operator<<(ostream &, lyxstring const &);
628 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');