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