]> git.lyx.org Git - lyx.git/blob - src/support/lyxstring.h
Collapse all those LFUN_XYZ_APPLY to a single LFUN_INSET_APPLY.
[lyx.git] / src / support / lyxstring.h
1 // -*- C++ -*-
2 /**
3  * \file lyxstring.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS
10  */
11
12 // This one is heavily based on the string class in The C++
13 // Programming Language by Bjarne Stroustrup
14
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
19 // right behavior.
20
21 #ifndef LYXSTRING_H
22 #define LYXSTRING_H
23
24 #include <iosfwd>
25
26 #if 0
27 #include <iterator>
28 #endif
29
30 #include <cstring> // for size_t
31
32 /** A string class for LyX
33
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.
40
41   Notes for usage:
42
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.
45
46   If you want to use a default empty lyxstring as a parameter, use
47
48         #void foo(lyxstring par = lyxstring()); // Correct#
49
50   rather than
51
52         #void foo(lyxstring par = "");  // WRONG!#
53         #void foo(lyxstring par = 0);   // WRONG!#
54
55   (The last one is only wrong because some compilers can't handle it.)
56
57   Methods that take an index as parameter all follow this rule: Valid indexes
58   go from 0 to length()-1.
59   \begin{tabular}{rl}
60   Correct: & #foo.substring(0, length()-1);# \\
61   Wrong:   & #bar.substring(0, length());#
62   \end{tabular}
63
64   It is important that you declare lyxstring as const if possible, because
65   some methods are much more efficient in const versions.
66
67   If you want to check whether a string is empty, do
68
69         #if (foo.empty()) something right#
70
71   rather than something along the lines of
72
73         #if (!foo) completely wrong#
74
75 When you want to copy an lyxstring, just do
76
77         #lyxstring a, b = "String";#
78         #a = b; // That's it!#
79
80   not something like
81
82         #lyxstring a, b = "String";#
83         #a = b.copy(); // This leaks. // and does not work either. #
84
85   The class automatically handles deep copying when required.
86 */
87 class lyxstring {
88 public:
89         /* Typedefs */
90
91         ///
92         typedef char value_type;
93
94         ///
95         typedef value_type * pointer;
96
97         ///
98         typedef value_type & reference;
99
100         ///
101         typedef value_type const & const_reference;
102
103         ///
104         typedef size_t size_type;
105
106         ///
107         typedef int difference_type;
108
109         ///
110         typedef value_type * iterator;
111         ///
112         typedef const value_type * const_iterator;
113 #if 0
114         ///
115         typedef reverse_iterator<iterator, value_type, reference>
116         reverse_iterator;
117         ///
118         typedef reverse_iterator<const_iterator, const value_type,
119                 const_reference> const_reverse_iterator;
120
121 #endif
122
123         ///
124         iterator begin();
125         ///
126         const_iterator begin() const;
127         ///
128         iterator end();
129         ///
130         const_iterator end() const;
131 #if 0
132         ///
133         reverse_iterator rbegin();
134         ///
135         const_reverse_iterator rbegin() const;
136         ///
137         reverse_iterator rend();
138         ///
139         const_reverse_iterator rend() const;
140 #endif
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
144           parameter. */
145
146         /// "all characters" marker
147         static const size_type npos;
148
149         /// #lyxstring x;#
150         lyxstring();
151
152         /// #lyxstring x(lyxstring ...)#
153         lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
154
155         /// #lyxstring x("abc", 2) -> "ab"#
156         lyxstring(value_type const *, size_type n);
157
158         // #lyxstring x("abc")#
159         lyxstring(value_type const *);
160
161         /// lyxstring(5, 'n') -> "nnnnn"
162         lyxstring(size_type n, value_type c);
163
164 #if 1
165         ///
166         lyxstring(const_iterator first, const_iterator last);
167 #else
168         ///
169         template<class InputIterator>
170         lyxstring::lyxstring(InputIterator begin, InputIterator end) {
171                 while (begin != end) {
172                         push_back((*begin));
173                         ++begin;
174                 }
175         }
176 #endif
177         ///
178         ~lyxstring();
179
180         /// number of characters
181         size_type size() const;
182
183         /// largest possible string
184         size_type max_size() const { return npos - 1; }
185
186         ///
187         size_type length() const { return size(); }
188
189         ///
190         bool empty() const { return size() == 0; }
191
192         ///
193         void resize(size_type n, value_type c);
194
195         ///
196         void resize(size_type n) { resize(n, ' '); }
197
198         /// size of the memory (in number of elements) allocated.
199         size_type capacity() const;
200
201         ///
202         void reserve(size_type res_arg = 0);
203
204         ///
205         lyxstring & operator=(lyxstring const &);
206
207         ///
208         lyxstring & operator=(value_type const *);
209
210         ///
211         lyxstring & operator=(value_type);
212
213         ///
214         lyxstring & assign(lyxstring const &);
215
216         ///
217         lyxstring & assign(lyxstring const &, size_type pos, size_type n);
218
219         ///
220         lyxstring & assign(value_type const * p, size_type n);
221
222         ///
223         lyxstring & assign(value_type const * p);
224
225         ///
226         lyxstring & assign(size_type n, value_type c);
227
228 #if 1
229         ///
230         lyxstring & assign(const_iterator first, const_iterator last);
231 #else
232         ///
233         template<class InputIterator>
234         lyxstring & assign(InputIterator begin, InputIterator end) {
235                 clear;
236                 while (begin != end) {
237                         push_back((*begin));
238                         ++begin;
239                 }
240         }
241 #endif
242
243         /// unchecked access
244         const_reference operator[](size_type) const;
245
246         /// unchecked access
247         reference operator[](size_type);
248
249         /// checked access
250         const_reference at(size_type) const;
251
252         /// checked access
253         reference at(size_type);
254
255         // add characters after (*this)[length()-1]:
256
257         ///
258         lyxstring & operator+=(lyxstring const &);
259
260         ///
261         lyxstring & operator+=(value_type const *);
262
263         ///
264         lyxstring & operator+=(value_type);
265
266         ///
267         void push_back(value_type);
268
269         ///
270         lyxstring & append(lyxstring const &);
271
272         ///
273         lyxstring & append(lyxstring const &, size_type pos, size_type n);
274
275         ///
276         lyxstring & append(value_type const *, size_type n);
277
278         ///
279         lyxstring & append(value_type const *);
280
281         ///
282         lyxstring & append(size_type n, value_type);
283
284 #if 1
285         ///
286         lyxstring & append(iterator first, iterator last);
287 #else
288         ///
289         template<class InputIterator>
290         lyxstring & append(InputIterator begin, InputIterator end) {
291                 while (begin != end) {
292                         push_back((*begin));
293                         ++begin;
294                 }
295                 return *this;
296         }
297 #endif
298         // insert characters before (*this)[pos]:
299
300         ///
301         lyxstring & insert(size_type pos, lyxstring const &);
302
303         ///
304         lyxstring & insert(size_type pos, lyxstring const &,
305                         size_type pos2, size_type n);
306
307         ///
308         lyxstring & insert(size_type pos, value_type const * p,
309                          size_type n);
310
311         ///
312         lyxstring & insert(size_type pos, value_type const * p);
313
314         ///
315         lyxstring & insert(size_type pos, size_type n, value_type c);
316
317         // insert characters before p
318
319         ///
320         iterator insert(iterator p, value_type c);
321
322         ///
323         void insert(iterator p, size_type n , value_type c);
324
325 #if 1
326         ///
327         void insert(iterator p, iterator first, iterator last);
328 #else
329         ///
330         template<class InputIterator>
331         void insert(iterator p, InputIterator begin, InputIterator end) {
332                 iterator it;
333                 while (begin != end) {
334                         it = insert(p, (*begin));
335                         ++begin;
336                 }
337         }
338 #endif
339
340         ///
341         size_type find(lyxstring const &, size_type i = 0) const;
342
343         ///
344         size_type find(value_type const * p,
345                          size_type i, size_type n) const;
346
347         ///
348         size_type find(value_type const * p, size_type i = 0) const;
349
350         ///
351         size_type find(value_type c, size_type i = 0) const;
352
353         ///
354         size_type rfind(lyxstring const &, size_type i = npos) const;
355
356         ///
357         size_type rfind(value_type const * p, size_type i, size_type n) const;
358
359         ///
360         size_type rfind(value_type const * p, size_type i = npos) const;
361
362         ///
363         size_type rfind(value_type c, size_type i = npos) const;
364
365         ///
366         size_type find_first_of(lyxstring const &, size_type i = 0) const;
367
368         ///
369         size_type find_first_of(value_type const * p, size_type i,
370                                 size_type n) const;
371
372         ///
373         size_type find_first_of(value_type const * p, size_type i = 0) const;
374
375         ///
376         size_type find_first_of(value_type c, size_type i = 0) const;
377
378         ///
379         size_type find_last_of(lyxstring const &, size_type i = npos) const;
380
381         ///
382         size_type find_last_of(value_type const * p, size_type i,
383                                size_type n) const;
384
385         ///
386         size_type find_last_of(value_type const * p, size_type i = npos) const;
387
388         ///
389         size_type find_last_of(value_type c, size_type i = npos) const;
390
391         ///
392         size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
393
394         ///
395         size_type find_first_not_of(value_type const * p, size_type i,
396                                     size_type n) const;
397
398         ///
399         size_type find_first_not_of(value_type const * p,
400                                     size_type i = 0) const;
401
402         ///
403         size_type find_first_not_of(value_type c, size_type i = 0) const;
404
405         ///
406         size_type find_last_not_of(lyxstring const &,
407                                    size_type i = npos) const;
408
409         ///
410         size_type find_last_not_of(value_type const * p, size_type i,
411                                    size_type n) const;
412
413         ///
414         size_type find_last_not_of(value_type const * p,
415                                    size_type i = npos) const;
416
417         ///
418         size_type find_last_not_of(value_type c, size_type i = npos) const;
419
420         // replace [(*this)[i], (*this)[i+n]] with other characters:
421
422         ///
423         lyxstring & replace(size_type i, size_type n, lyxstring const & str);
424
425         ///
426         lyxstring & replace(size_type i, size_type n, lyxstring const & s,
427                           size_type i2, size_type n2);
428
429         ///
430         lyxstring & replace(size_type i, size_type n, value_type const * p,
431                           size_type n2);
432
433         ///
434         lyxstring & replace(size_type i, size_type n, value_type const * p);
435
436         ///
437         lyxstring & replace(size_type i, size_type n,
438                             size_type n2, value_type c);
439
440         /// FY! FY! FY! go away !
441         lyxstring & replace(size_type i, size_type n,
442                             value_type c);
443
444         ///
445         lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
446
447         ///
448         lyxstring & replace(iterator i, iterator i2,
449                           value_type const * p, size_type n);
450
451         ///
452         lyxstring & replace(iterator i, iterator i2, value_type const * p);
453
454         ///
455         lyxstring & replace(iterator i, iterator i2,
456                             size_type n , value_type c);
457
458         ///
459         lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
460
461         ///
462         void swap(lyxstring & str);
463
464         /// Erase n chars from position i.
465         lyxstring & erase(size_type i = 0, size_type n = npos);
466
467         ///
468         lyxstring & clear() {
469                 return erase(0, npos);
470         }
471
472         ///
473         iterator erase(iterator i);
474
475         ///
476         iterator erase(iterator first, iterator last);
477
478         ///
479         value_type const * c_str() const;
480
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;
484
485         /* This one returns a verbatim copy. Not the trailing '\0'
486           The caller must provide a buffer with engough room.
487           */
488         size_type copy(value_type * buf, size_type len,
489                        size_type pos = 0) const;
490
491
492         ///
493         int compare(lyxstring const & str) const;
494
495         ///
496         int compare(value_type const * p) const;
497
498         ///
499         int compare(size_type pos, size_type n, lyxstring const & str) const;
500
501         ///
502         int compare(size_type pos, size_type n, lyxstring const & str,
503                     size_type pos2, size_type n2) const;
504
505         ///
506         int compare(size_type pos, size_type n, value_type const * p,
507                     size_type n2 = npos) const;
508
509
510         ///
511         lyxstring substr(size_type i = 0, size_type n = npos) const;
512
513 private:
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.)
518         // Lgb.
519         //
520         //lyxstring & operator+(int);
521         //
522         //lyxstring & operator=(int);
523         //
524         //lyxstring & operator+=(int);
525
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;
530
531         /// Forward declaration of the string representation
532         struct Srep;
533         // DEC cxx requires this.
534         friend struct Srep;
535
536         /// A string is a pointer to it's representation
537         Srep * rep;
538
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
542             empty srep).
543             This overcomes *all* "static initialization" problems,
544             at maximum speed, with a small overhead of a few local static
545             empty_reps.
546         */
547
548 #ifdef ENABLE_ASSERTIONS
549         /// lyxstringInvariant is used to test the lyxstring Invariant
550         friend class lyxstringInvariant;
551 #endif
552 };
553
554 // The usual comparison operators ==, !=, >, <, >=, <= are
555 // provided for lyxstrings
556
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 *);
560
561
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 *);
565
566
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 *);
570
571
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 *);
575
576
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 *);
580
581
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 *);
585
586
587 // Concatenation
588
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);
594
595 void swap(lyxstring & s1, lyxstring & s2);
596
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');
600
601 #endif