4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS
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
30 #include <cstring> // for size_t
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 lyxstring lack support for
36 reverse iterators and allocators, also char_traits is not used. In most
37 other senses it is written to be a drop in replacement for STL string
38 (or as a transition tool). So documentation for STL string should be
39 valid for lyxstring too.
43 When you declare an lyxstring, it is initially empty. There is no need to
44 do things like #lyxstring a= "";#, especially not in constructors.
46 If you want to use a default empty lyxstring as a parameter, use
48 #void foo(lyxstring par = lyxstring()); // Correct#
52 #void foo(lyxstring par = ""); // WRONG!#
53 #void foo(lyxstring par = 0); // WRONG!#
55 (The last one is only wrong because some compilers can't handle it.)
57 Methods that take an index as parameter all follow this rule: Valid indexes
58 go from 0 to length()-1.
60 Correct: & #foo.substring(0, length()-1);# \\
61 Wrong: & #bar.substring(0, length());#
64 It is important that you declare lyxstring as const if possible, because
65 some methods are much more efficient in const versions.
67 If you want to check whether a string is empty, do
69 #if (foo.empty()) something right#
71 rather than something along the lines of
73 #if (!foo) completely wrong#
75 When you want to copy an lyxstring, just do
77 #lyxstring a, b = "String";#
78 #a = b; // That's it!#
82 #lyxstring a, b = "String";#
83 #a = b.copy(); // This leaks. // and does not work either. #
85 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 value_type const & 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;
126 const_iterator begin() const;
130 const_iterator end() const;
133 reverse_iterator rbegin();
135 const_reverse_iterator rbegin() const;
137 reverse_iterator rend();
139 const_reverse_iterator rend() const;
141 /* Constructors and Deconstructors. lyxstring has the same
142 constructors as STL, except the one using iterators, one other
143 difference is that lyxstring, do not allow the optional allocator
146 /// "all characters" marker
147 static const size_type npos;
152 /// #lyxstring x(lyxstring ...)#
153 lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
155 /// #lyxstring x("abc", 2) -> "ab"#
156 lyxstring(value_type const *, size_type n);
158 // #lyxstring x("abc")#
159 lyxstring(value_type const *);
161 /// lyxstring(5, 'n') -> "nnnnn"
162 lyxstring(size_type n, value_type c);
166 lyxstring(const_iterator first, const_iterator last);
169 template<class InputIterator>
170 lyxstring::lyxstring(InputIterator begin, InputIterator end) {
171 while (begin != end) {
180 /// number of characters
181 size_type size() const;
183 /// largest possible string
184 size_type max_size() const { return npos - 1; }
187 size_type length() const { return size(); }
190 bool empty() const { return size() == 0; }
193 void resize(size_type n, value_type c);
196 void resize(size_type n) { resize(n, ' '); }
198 /// size of the memory (in number of elements) allocated.
199 size_type capacity() const;
202 void reserve(size_type res_arg = 0);
205 lyxstring & operator=(lyxstring const &);
208 lyxstring & operator=(value_type const *);
211 lyxstring & operator=(value_type);
214 lyxstring & assign(lyxstring const &);
217 lyxstring & assign(lyxstring const &, size_type pos, size_type n);
220 lyxstring & assign(value_type const * p, size_type n);
223 lyxstring & assign(value_type const * p);
226 lyxstring & assign(size_type n, value_type c);
230 lyxstring & assign(const_iterator first, const_iterator last);
233 template<class InputIterator>
234 lyxstring & assign(InputIterator begin, InputIterator end) {
236 while (begin != end) {
244 const_reference operator[](size_type) const;
247 reference operator[](size_type);
250 const_reference at(size_type) const;
253 reference at(size_type);
255 // add characters after (*this)[length()-1]:
258 lyxstring & operator+=(lyxstring const &);
261 lyxstring & operator+=(value_type const *);
264 lyxstring & operator+=(value_type);
267 void push_back(value_type);
270 lyxstring & append(lyxstring const &);
273 lyxstring & append(lyxstring const &, size_type pos, size_type n);
276 lyxstring & append(value_type const *, size_type n);
279 lyxstring & append(value_type const *);
282 lyxstring & append(size_type n, value_type);
286 lyxstring & append(iterator first, iterator last);
289 template<class InputIterator>
290 lyxstring & append(InputIterator begin, InputIterator end) {
291 while (begin != end) {
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);
327 void insert(iterator p, iterator first, iterator last);
330 template<class InputIterator>
331 void insert(iterator p, InputIterator begin, InputIterator end) {
333 while (begin != end) {
334 it = insert(p, (*begin));
341 size_type find(lyxstring const &, size_type i = 0) const;
344 size_type find(value_type const * p,
345 size_type i, size_type n) const;
348 size_type find(value_type const * p, size_type i = 0) const;
351 size_type find(value_type c, size_type i = 0) const;
354 size_type rfind(lyxstring const &, size_type i = npos) const;
357 size_type rfind(value_type const * p, size_type i, size_type n) const;
360 size_type rfind(value_type const * p, size_type i = npos) const;
363 size_type rfind(value_type c, size_type i = npos) const;
366 size_type find_first_of(lyxstring const &, size_type i = 0) const;
369 size_type find_first_of(value_type const * p, size_type i,
373 size_type find_first_of(value_type const * p, size_type i = 0) const;
376 size_type find_first_of(value_type c, size_type i = 0) const;
379 size_type find_last_of(lyxstring const &, size_type i = npos) const;
382 size_type find_last_of(value_type const * p, size_type i,
386 size_type find_last_of(value_type const * p, size_type i = npos) const;
389 size_type find_last_of(value_type c, size_type i = npos) const;
392 size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
395 size_type find_first_not_of(value_type const * p, size_type i,
399 size_type find_first_not_of(value_type const * p,
400 size_type i = 0) const;
403 size_type find_first_not_of(value_type c, size_type i = 0) const;
406 size_type find_last_not_of(lyxstring const &,
407 size_type i = npos) const;
410 size_type find_last_not_of(value_type const * p, size_type i,
414 size_type find_last_not_of(value_type const * p,
415 size_type i = npos) const;
418 size_type find_last_not_of(value_type c, size_type i = npos) const;
420 // replace [(*this)[i], (*this)[i+n]] with other characters:
423 lyxstring & replace(size_type i, size_type n, lyxstring const & str);
426 lyxstring & replace(size_type i, size_type n, lyxstring const & s,
427 size_type i2, size_type n2);
430 lyxstring & replace(size_type i, size_type n, value_type const * p,
434 lyxstring & replace(size_type i, size_type n, value_type const * p);
437 lyxstring & replace(size_type i, size_type n,
438 size_type n2, value_type c);
440 /// FY! FY! FY! go away !
441 lyxstring & replace(size_type i, size_type n,
445 lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
448 lyxstring & replace(iterator i, iterator i2,
449 value_type const * p, size_type n);
452 lyxstring & replace(iterator i, iterator i2, value_type const * p);
455 lyxstring & replace(iterator i, iterator i2,
456 size_type n , value_type c);
459 lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
462 void swap(lyxstring & str);
464 /// Erase n chars from position i.
465 lyxstring & erase(size_type i = 0, size_type n = npos);
468 lyxstring & clear() {
469 return erase(0, npos);
473 iterator erase(iterator i);
476 iterator erase(iterator first, iterator last);
479 value_type const * c_str() const;
481 /* Note that this is STL compilant, so you can not assume
482 that the returned array has a trailing '\0'. */
483 value_type const * data() const;
485 /* This one returns a verbatim copy. Not the trailing '\0'
486 The caller must provide a buffer with engough room.
488 size_type copy(value_type * buf, size_type len,
489 size_type pos = 0) const;
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;
511 lyxstring substr(size_type i = 0, size_type n = npos) const;
514 // These three operators can be used to discover erronous use of
515 // ints and strings. However a conforming C++ compiler will flag
516 // a lot of char operations as ambigous when they are compiled
517 // in. Use them for debugging only (or perhaps not even then.)
520 //lyxstring & operator+(int);
522 //lyxstring & operator=(int);
524 //lyxstring & operator+=(int);
526 /// Compare this with s. works with embedded '\0' chars also.
527 int internal_compare(size_type pos, size_type n,
528 value_type const * s,
529 size_type slen, size_type n2) const;
531 /// Forward declaration of the string representation
533 // DEC cxx requires this.
536 /// A string is a pointer to it's representation
539 /* Note: The empty_rep is a local static in each function that
540 benefits from one. There is no "global" empty srep but lyxstring
541 doesn't need one (no code actually relies upon a single
543 This overcomes *all* "static initialization" problems,
544 at maximum speed, with a small overhead of a few local static
548 #ifdef ENABLE_ASSERTIONS
549 /// lyxstringInvariant is used to test the lyxstring Invariant
550 friend class lyxstringInvariant;
554 // The usual comparison operators ==, !=, >, <, >=, <= are
555 // provided for lyxstrings
557 bool operator==(lyxstring const &, lyxstring const &);
558 bool operator==(lyxstring::value_type const *, lyxstring const &);
559 bool operator==(lyxstring const &, lyxstring::value_type const *);
562 bool operator!=(lyxstring const &, lyxstring const &);
563 bool operator!=(lyxstring::value_type const *, lyxstring const &);
564 bool operator!=(lyxstring const &, lyxstring::value_type const *);
567 bool operator>(lyxstring const &, lyxstring const &);
568 bool operator>(lyxstring::value_type const *, lyxstring const &);
569 bool operator>(lyxstring const &, lyxstring::value_type const *);
572 bool operator<(lyxstring const &, lyxstring const &);
573 bool operator<(lyxstring::value_type const *, lyxstring const &);
574 bool operator<(lyxstring const &, lyxstring::value_type const *);
577 bool operator>=(lyxstring const &, lyxstring const &);
578 bool operator>=(lyxstring::value_type const *, lyxstring const &);
579 bool operator>=(lyxstring const &, lyxstring::value_type const *);
582 bool operator<=(lyxstring const &, lyxstring const &);
583 bool operator<=(lyxstring::value_type const *, lyxstring const &);
584 bool operator<=(lyxstring const &, lyxstring::value_type const *);
589 lyxstring operator+(lyxstring const & a, lyxstring const & b);
590 lyxstring operator+(char const * a, lyxstring const & b);
591 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
592 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
593 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
595 void swap(lyxstring & s1, lyxstring & s2);
597 std::istream & operator>>(std::istream &, lyxstring &);
598 std::ostream & operator<<(std::ostream &, lyxstring const &);
599 std::istream & getline(std::istream &, lyxstring &, lyxstring::value_type delim = '\n');