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
35 #include <cstring> // for size_t
37 /** A string class for LyX
39 This is a permanent String class. It is modeled closely after the C++ STL
40 string class. In comparison with STL string lyxstring lack support for
41 reverse iterators and allocators, also char_traits is not used. In most
42 other senses it is written to be a drop in replacement for STL string
43 (or as a transition tool). So documentation for STL string should be
44 valid for lyxstring too.
48 When you declare an lyxstring, it is initially empty. There is no need to
49 do things like #lyxstring a= "";#, especially not in constructors.
51 If you want to use a default empty lyxstring as a parameter, use
53 #void foo(lyxstring par = lyxstring()); // Correct#
57 #void foo(lyxstring par = ""); // WRONG!#
58 #void foo(lyxstring par = 0); // WRONG!#
60 (The last one is only wrong because some compilers can't handle it.)
62 Methods that take an index as parameter all follow this rule: Valid indexes
63 go from 0 to length()-1.
65 Correct: & #foo.substring(0, length()-1);# \\
66 Wrong: & #bar.substring(0, length());#
69 It is important that you declare lyxstring as const if possible, because
70 some methods are much more efficient in const versions.
72 If you want to check whether a string is empty, do
74 #if (foo.empty()) something right#
76 rather than something along the lines of
78 #if (!foo) completely wrong#
80 When you want to copy an lyxstring, just do
82 #lyxstring a, b = "String";#
83 #a = b; // That's it!#
87 #lyxstring a, b = "String";#
88 #a = b.copy(); // This leaks. // and does not work either. #
90 The class automatically handles deep copying when required.
98 typedef char value_type;
101 typedef value_type * pointer;
104 typedef value_type & reference;
107 typedef value_type const & const_reference;
110 typedef size_t size_type;
113 typedef int difference_type;
116 typedef value_type * iterator;
118 typedef const value_type * const_iterator;
121 typedef reverse_iterator<iterator, value_type, reference>
124 typedef reverse_iterator<const_iterator, const value_type,
125 const_reference> const_reverse_iterator;
133 const_iterator begin() const;
137 const_iterator end() const;
140 reverse_iterator rbegin();
142 const_reverse_iterator rbegin() const;
144 reverse_iterator rend();
146 const_reverse_iterator rend() const;
148 /**@name Constructors and Deconstructors. lyxstring has the same
149 constructors as STL, except the one using iterators, one other
150 difference is that lyxstring, do not allow the optional allocator
154 /// "all characters" marker
155 static const size_type npos;
160 /// #lyxstring x(lyxstring ...)#
161 lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
163 /// #lyxstring x("abc", 2) -> "ab"#
164 lyxstring(value_type const *, size_type n);
166 /// #lyxstring x("abc")#
167 lyxstring(value_type const *);
169 /// lyxstring(5, 'n') -> "nnnnn"
170 lyxstring(size_type n, value_type c);
173 lyxstring(iterator first, iterator last);
181 /**@name Size and Capacity */
184 /// number of characters
185 size_type size() const;
187 /// largest possible string
188 size_type max_size() const { return npos -1; }
191 size_type length() const { return size(); }
194 bool empty() const { return size() == 0; }
197 void resize(size_type n, value_type c);
200 void resize(size_type n) { resize(n, ' '); }
202 /// size of the memory (in number of elements) allocated.
203 size_type capacity() const;
206 void reserve(size_type res_arg = 0);
210 /**@name Assignment */
214 lyxstring & operator=(lyxstring const &);
217 lyxstring & operator=(value_type const *);
220 lyxstring & operator=(value_type);
223 lyxstring & assign(lyxstring const &);
226 lyxstring & assign(lyxstring const &, size_type pos, size_type n);
229 lyxstring & assign(value_type const * p, size_type n);
232 lyxstring & assign(value_type const * p);
235 lyxstring & assign(size_type n, value_type c);
238 lyxstring & assign(iterator first, iterator last);
242 /**@name Element Access. Since lyxstring does not use exceptions,
243 an abort is called on out-of-range access to at(). */
246 const_reference operator[](size_type) const;
249 reference operator[](size_type);
252 const_reference at(size_type) const;
255 reference at(size_type);
262 // add characters after (*this)[length()-1]:
265 lyxstring & operator+=(lyxstring const &);
268 lyxstring & operator+=(value_type const *);
271 lyxstring & operator+=(value_type);
274 void push_back(value_type);
277 lyxstring & append(lyxstring const &);
280 lyxstring & append(lyxstring const &, size_type pos, size_type n);
283 lyxstring & append(value_type const *, size_type n);
286 lyxstring & append(value_type const *);
289 lyxstring & append(size_type n, value_type);
292 lyxstring & append(iterator first, iterator last);
294 // insert characters before (*this)[pos]:
297 lyxstring & insert(size_type pos, lyxstring const &);
300 lyxstring & insert(size_type pos, lyxstring const &,
301 size_type pos2, size_type n);
304 lyxstring & insert(size_type pos, value_type const * p,
308 lyxstring & insert(size_type pos, value_type const * p);
311 lyxstring & insert(size_type pos, size_type n, value_type c);
313 // insert characters before p
316 iterator insert(iterator p, value_type c);
319 void insert(iterator p, size_type n , value_type c);
322 void insert(iterator p, iterator first, iterator last);
330 size_type find(lyxstring const &, size_type i = 0) const;
333 size_type find(value_type const * p,
334 size_type i, size_type n) const;
337 size_type find(value_type const * p, size_type i = 0) const;
340 size_type find(value_type c, size_type i = 0) const;
343 size_type rfind(lyxstring const &, size_type i = npos) const;
346 size_type rfind(value_type const * p, size_type i, size_type n) const;
349 size_type rfind(value_type const * p, size_type i = npos) const;
352 size_type rfind(value_type c, size_type i = npos) const;
355 size_type find_first_of(lyxstring const &, size_type i = 0) const;
358 size_type find_first_of(value_type const * p, size_type i,
362 size_type find_first_of(value_type const * p, size_type i = 0) const;
365 size_type find_first_of(value_type c, size_type i = 0) const;
368 size_type find_last_of(lyxstring const &, size_type i = npos) const;
371 size_type find_last_of(value_type const * p, size_type i,
375 size_type find_last_of(value_type const * p, size_type i = npos) const;
378 size_type find_last_of(value_type c, size_type i = npos) const;
381 size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
384 size_type find_first_not_of(value_type const * p, size_type i,
388 size_type find_first_not_of(value_type const * p,
389 size_type i = 0) const;
392 size_type find_first_not_of(value_type c, size_type i = 0) const;
395 size_type find_last_not_of(lyxstring const &,
396 size_type i = npos) const;
399 size_type find_last_not_of(value_type const * p, size_type i,
403 size_type find_last_not_of(value_type const * p,
404 size_type i = npos) const;
407 size_type find_last_not_of(value_type c, size_type i = npos) const;
415 // replace [(*this)[i], (*this)[i+n]] with other characters:
418 lyxstring & replace(size_type i,size_type n, lyxstring const & str);
421 lyxstring & replace(size_type i,size_type n, lyxstring const & s,
422 size_type i2, size_type n2);
425 lyxstring & replace(size_type i,size_type n, value_type const * p,
429 lyxstring & replace(size_type i,size_type n, value_type const * p);
432 lyxstring & replace(size_type i, size_type n,
433 size_type n2, value_type c);
436 lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
439 lyxstring & replace(iterator i, iterator i2,
440 value_type const * p, size_type n);
443 lyxstring & replace(iterator i, iterator i2, value_type const * p);
446 lyxstring & replace(iterator i, iterator i2,
447 size_type n , value_type c);
450 lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
452 /// Erase n chars from position i.
453 lyxstring & erase(size_type i = 0, size_type n = npos);
456 lyxstring & clear() {
457 return erase(0, npos);
461 iterator erase(iterator i);
464 iterator erase(iterator first, iterator last);
469 /**@name Conversion to C-style Strings */
473 value_type const * c_str() const;
475 /** Note that this is STL compilant, so you can not assume
476 that the returned array has a trailing '\0'. */
477 value_type const * data() const;
479 /** This one returns a verbatim copy. Not the trailing '\0'
480 The caller must provide a buffer with engough room.
482 size_type copy(value_type * buf, size_type len,
483 size_type pos = 0) const;
488 /**@name Comparisons. Combined > and == */
492 int compare(lyxstring const & str) const;
495 int compare(value_type const * p) const;
498 int compare(size_type pos, size_type n, lyxstring const & str) const;
501 int compare(size_type pos, size_type n, lyxstring const & str,
502 size_type pos2, size_type n2) const;
505 int compare(size_type pos, size_type n, value_type const * p,
506 size_type n2 = npos) const;
512 /**@name Substrings */
516 lyxstring substr(size_type i = 0, size_type n = npos) const;
521 // These three operators can be used to discover erronous use of
522 // ints and strings. However a conforming C++ compiler will flag
523 // a lot of char operations as ambigous when they are compiled
524 // in. Use them for debugging only (or perhaps not even then.)
527 //lyxstring & operator+(int);
529 //lyxstring & operator=(int);
531 //lyxstring & operator+=(int);
533 /// Compare this with s. works with embedded '\0' chars also.
534 int internal_compare(size_type pos, size_type n,
535 value_type const * s,
536 size_type slen, size_type n2) const;
538 /// Forward declaration of the string representation
540 // DEC cxx requires this.
543 /// A string is a pointer to it's representation
546 /** Note: The empty_rep is a local static in each function that
547 benefits from one. There is no "global" empty srep but lyxstring
548 doesn't need one (no code actually relies upon a single
550 This overcomes *all* "static initialization" problems,
551 at maximum speed, with a small overhead of a few local static
556 /// lyxstringInvariant is used to test the lyxstring Invariant
557 friend class lyxstringInvariant;
561 // The usual comparison operators ==, !=, >, <, >=, <= are
562 // provided for lyxstrings
564 bool operator==(lyxstring const &, lyxstring const &);
565 bool operator==(lyxstring::value_type const *, lyxstring const &);
566 bool operator==(lyxstring const &, lyxstring::value_type const *);
569 bool operator!=(lyxstring const &, lyxstring const &);
570 bool operator!=(lyxstring::value_type const *, lyxstring const &);
571 bool operator!=(lyxstring const &, lyxstring::value_type const *);
574 bool operator>(lyxstring const &, lyxstring const &);
575 bool operator>(lyxstring::value_type const *, lyxstring const &);
576 bool operator>(lyxstring const &, lyxstring::value_type const *);
579 bool operator<(lyxstring const &, lyxstring const &);
580 bool operator<(lyxstring::value_type const *, lyxstring const &);
581 bool operator<(lyxstring const &, lyxstring::value_type const *);
584 bool operator>=(lyxstring const &, lyxstring const &);
585 bool operator>=(lyxstring::value_type const *, lyxstring const &);
586 bool operator>=(lyxstring const &, lyxstring::value_type const *);
589 bool operator<=(lyxstring const &, lyxstring const &);
590 bool operator<=(lyxstring::value_type const *, lyxstring const &);
591 bool operator<=(lyxstring const &, lyxstring::value_type const *);
596 lyxstring operator+(lyxstring const & a, lyxstring const & b);
597 lyxstring operator+(char const * a, lyxstring const & b);
598 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
599 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
600 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
602 istream & operator>>(istream &, lyxstring &);
603 ostream & operator<<(ostream &, lyxstring const &);
604 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');