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
34 /** A string class for LyX
36 This is a permanent String class. It is modeled closely after the C++ STL
37 string class. In comparison with STL string lyxstring lack support for
38 reverse iterators and allocators, also char_traits is not used. In most
39 other senses it is written to be a drop in replacement for STL string
40 (or as a transition tool). So documentation for STL string should be
41 valid for lyxstring too.
45 When you declare an lyxstring, it is initially empty. There is no need to
46 do things like #lyxstring a= "";#, especially not in constructors.
48 If you want to use a default empty lyxstring as a parameter, use
50 #void foo(lyxstring par = lyxstring()); // Correct#
54 #void foo(lyxstring par = ""); // WRONG!#
55 #void foo(lyxstring par = 0); // WRONG!#
57 (The last one is only wrong because some compilers can't handle it.)
59 Methods that take an index as parameter all follow this rule: Valid indexes
60 go from 0 to length()-1.
62 Correct: & #foo.substring(0, length()-1);# \\
63 Wrong: & #bar.substring(0, length());#
66 It is important that you declare lyxstring as const if possible, because
67 some methods are much more efficient in const versions.
69 If you want to check whether a string is empty, do
71 #if (foo.empty()) something right#
73 rather than something along the lines of
75 #if (!foo) completely wrong#
77 When you want to copy an lyxstring, just do
79 #lyxstring a, b = "String";#
80 #a = b; // That's it!#
84 #lyxstring a, b = "String";#
85 #a = b.copy(); // This leaks. // and does not work either. #
87 The class automatically handles deep copying when required.
94 typedef char value_type;
97 typedef value_type * pointer;
100 typedef value_type & reference;
103 typedef value_type const & const_reference;
106 typedef size_t size_type;
109 typedef int difference_type;
112 typedef value_type * iterator;
114 typedef const value_type * const_iterator;
117 typedef reverse_iterator<iterator, value_type, reference>
120 typedef reverse_iterator<const_iterator, const value_type,
121 const_reference> const_reverse_iterator;
128 const_iterator begin() const;
132 const_iterator end() const;
135 reverse_iterator rbegin();
137 const_reverse_iterator rbegin() const;
139 reverse_iterator rend();
141 const_reverse_iterator rend() const;
143 /* Constructors and Deconstructors. lyxstring has the same
144 constructors as STL, except the one using iterators, one other
145 difference is that lyxstring, do not allow the optional allocator
148 /// "all characters" marker
149 static const size_type npos;
154 /// #string x(string ...)#
155 string(string const &, size_type pos = 0, size_type n = npos);
157 /// #string x("abc", 2) -> "ab"#
158 string(value_type const *, size_type n);
161 string(value_type const *);
163 /// string(5, 'n') -> "nnnnn"
164 string(size_type n, value_type c);
168 string(const_iterator first, const_iterator last);
171 template<class InputIterator>
172 string(InputIterator begin, InputIterator end) {
173 while (begin != end) {
182 /// number of characters
183 size_type size() const;
185 /// largest possible string
186 size_type max_size() const { return npos - 1; }
189 size_type length() const { return size(); }
192 bool empty() const { return size() == 0; }
195 void resize(size_type n, value_type c);
198 void resize(size_type n) { resize(n, ' '); }
200 /// size of the memory (in number of elements) allocated.
201 size_type capacity() const;
204 void reserve(size_type res_arg = 0);
207 string & operator=(string const &);
210 string & operator=(value_type const *);
213 string & operator=(value_type);
216 string & assign(string const &);
219 string & assign(string const &, size_type pos, size_type n);
222 string & assign(value_type const * p, size_type n);
225 string & assign(value_type const * p);
228 string & assign(size_type n, value_type c);
232 string & assign(const_iterator first, const_iterator last);
235 template<class InputIterator>
236 string & assign(InputIterator begin, InputIterator end) {
238 while (begin != end) {
246 const_reference operator[](size_type) const;
249 reference operator[](size_type);
252 const_reference at(size_type) const;
255 reference at(size_type);
257 // add characters after (*this)[length()-1]:
260 string & operator+=(string const &);
263 string & operator+=(value_type const *);
266 string & operator+=(value_type);
269 void push_back(value_type);
272 string & append(string const &);
275 string & append(string const &, size_type pos, size_type n);
278 string & append(value_type const *, size_type n);
281 string & append(value_type const *);
284 string & append(size_type n, value_type);
288 string & append(iterator first, iterator last);
291 template<class InputIterator>
292 string & append(InputIterator begin, InputIterator end) {
293 while (begin != end) {
300 // insert characters before (*this)[pos]:
303 string & insert(size_type pos, string const &);
306 string & insert(size_type pos, string const &,
307 size_type pos2, size_type n);
310 string & insert(size_type pos, value_type const * p,
314 string & insert(size_type pos, value_type const * p);
317 string & insert(size_type pos, size_type n, value_type c);
319 // insert characters before p
322 iterator insert(iterator p, value_type c);
325 void insert(iterator p, size_type n , value_type c);
329 void insert(iterator p, iterator first, iterator last);
332 template<class InputIterator>
333 void insert(iterator p, InputIterator begin, InputIterator end) {
335 while (begin != end) {
336 it = insert(p, (*begin));
343 size_type find(string const &, size_type i = 0) const;
346 size_type find(value_type const * p,
347 size_type i, size_type n) const;
350 size_type find(value_type const * p, size_type i = 0) const;
353 size_type find(value_type c, size_type i = 0) const;
356 size_type rfind(string const &, size_type i = npos) const;
359 size_type rfind(value_type const * p, size_type i, size_type n) const;
362 size_type rfind(value_type const * p, size_type i = npos) const;
365 size_type rfind(value_type c, size_type i = npos) const;
368 size_type find_first_of(string const &, size_type i = 0) const;
371 size_type find_first_of(value_type const * p, size_type i,
375 size_type find_first_of(value_type const * p, size_type i = 0) const;
378 size_type find_first_of(value_type c, size_type i = 0) const;
381 size_type find_last_of(string const &, size_type i = npos) const;
384 size_type find_last_of(value_type const * p, size_type i,
388 size_type find_last_of(value_type const * p, size_type i = npos) const;
391 size_type find_last_of(value_type c, size_type i = npos) const;
394 size_type find_first_not_of(string const &, size_type i = 0) const;
397 size_type find_first_not_of(value_type const * p, size_type i,
401 size_type find_first_not_of(value_type const * p,
402 size_type i = 0) const;
405 size_type find_first_not_of(value_type c, size_type i = 0) const;
408 size_type find_last_not_of(string const &,
409 size_type i = npos) const;
412 size_type find_last_not_of(value_type const * p, size_type i,
416 size_type find_last_not_of(value_type const * p,
417 size_type i = npos) const;
420 size_type find_last_not_of(value_type c, size_type i = npos) const;
422 // replace [(*this)[i], (*this)[i+n]] with other characters:
425 string & replace(size_type i, size_type n, string const & str);
428 string & replace(size_type i, size_type n, string const & s,
429 size_type i2, size_type n2);
432 string & replace(size_type i, size_type n, value_type const * p,
436 string & replace(size_type i, size_type n, value_type const * p);
439 string & replace(size_type i, size_type n,
440 size_type n2, value_type c);
442 /// FY! FY! FY! go away !
443 string & replace(size_type i, size_type n,
447 string & replace(iterator i, iterator i2, const string & str);
450 string & replace(iterator i, iterator i2,
451 value_type const * p, size_type n);
454 string & replace(iterator i, iterator i2, value_type const * p);
457 string & replace(iterator i, iterator i2,
458 size_type n , value_type c);
461 string & replace(iterator i, iterator i2, iterator j, iterator j2);
464 void swap(string & str);
466 /// Erase n chars from position i.
467 string & erase(size_type i = 0, size_type n = npos);
471 return erase(0, npos);
475 iterator erase(iterator i);
478 iterator erase(iterator first, iterator last);
481 value_type const * c_str() const;
483 /* Note that this is STL compilant, so you can not assume
484 that the returned array has a trailing '\0'. */
485 value_type const * data() const;
487 /* This one returns a verbatim copy. Not the trailing '\0'
488 The caller must provide a buffer with engough room.
490 size_type copy(value_type * buf, size_type len,
491 size_type pos = 0) const;
495 int compare(string const & str) const;
498 int compare(value_type const * p) const;
501 int compare(size_type pos, size_type n, string const & str) const;
504 int compare(size_type pos, size_type n, string const & str,
505 size_type pos2, size_type n2) const;
508 int compare(size_type pos, size_type n, value_type const * p,
509 size_type n2 = npos) const;
513 string substr(size_type i = 0, size_type n = npos) const;
516 // These three operators can be used to discover erronous use of
517 // ints and strings. However a conforming C++ compiler will flag
518 // a lot of char operations as ambigous when they are compiled
519 // in. Use them for debugging only (or perhaps not even then.)
522 //string & operator+(int);
524 //string & operator=(int);
526 //string & operator+=(int);
528 /// Compare this with s. works with embedded '\0' chars also.
529 int internal_compare(size_type pos, size_type n,
530 value_type const * s,
531 size_type slen, size_type n2) const;
533 /// Forward declaration of the string representation
535 // DEC cxx requires this.
538 /// A string is a pointer to it's representation
541 /* Note: The empty_rep is a local static in each function that
542 benefits from one. There is no "global" empty srep but string
543 doesn't need one (no code actually relies upon a single
545 This overcomes *all* "static initialization" problems,
546 at maximum speed, with a small overhead of a few local static
550 #ifdef ENABLE_ASSERTIONS
551 /// lyxstringInvariant is used to test the lyxstring Invariant
552 friend class stringInvariant;
556 // The usual comparison operators ==, !=, >, <, >=, <= are
557 // provided for lyxstrings
559 bool operator==(string const &, string const &);
560 bool operator==(string::value_type const *, string const &);
561 bool operator==(string const &, string::value_type const *);
564 bool operator!=(string const &, string const &);
565 bool operator!=(string::value_type const *, string const &);
566 bool operator!=(string const &, string::value_type const *);
569 bool operator>(string const &, string const &);
570 bool operator>(string::value_type const *, string const &);
571 bool operator>(string const &, string::value_type const *);
574 bool operator<(string const &, string const &);
575 bool operator<(string::value_type const *, string const &);
576 bool operator<(string const &, string::value_type const *);
579 bool operator>=(string const &, string const &);
580 bool operator>=(string::value_type const *, string const &);
581 bool operator>=(string const &, string::value_type const *);
584 bool operator<=(string const &, string const &);
585 bool operator<=(string::value_type const *, string const &);
586 bool operator<=(string const &, string::value_type const *);
591 string operator+(string const & a, string const & b);
592 string operator+(char const * a, string const & b);
593 string operator+(string::value_type a, string const & b);
594 string operator+(string const & a, string::value_type const * b);
595 string operator+(string const & a, string::value_type b);
597 void swap(string & s1, string & s2);
599 std::istream & operator>>(std::istream &, string &);
600 std::ostream & operator<<(std::ostream &, string const &);
601 std::istream & getline(std::istream &, string &, string::value_type delim = '\n');