]> git.lyx.org Git - features.git/blob - src/support/lyxstring.h
some other things
[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         ///
453         void swap(lyxstring & str);
454         
455         /// Erase n chars from position i.
456         lyxstring & erase(size_type i = 0, size_type n = npos);
457
458         ///
459         lyxstring & clear() {
460                 return erase(0, npos);
461         }
462
463         ///
464         iterator erase(iterator i);
465
466         ///
467         iterator erase(iterator first, iterator last);
468
469         //@}
470
471         
472         /**@name Conversion to C-style Strings */
473         //@{
474         
475         /// 
476         value_type const * c_str() const;
477
478         /** Note that this is STL compilant, so you can not assume
479           that the returned array has a trailing '\0'. */
480         value_type const * data() const;
481
482         /** This one returns a verbatim copy. Not the trailing '\0'
483           The caller must provide a buffer with engough room.
484           */
485         size_type copy(value_type * buf, size_type len,
486                        size_type pos = 0) const;
487
488         //@}
489
490         
491         /**@name Comparisons. Combined > and == */
492         //@{
493         
494         ///
495         int compare(lyxstring const & str) const; 
496
497         ///
498         int compare(value_type const * p) const;
499
500         ///
501         int compare(size_type pos, size_type n, lyxstring const & str) const;
502
503         ///
504         int compare(size_type pos, size_type n, lyxstring const & str,
505                     size_type pos2, size_type n2) const;
506
507         ///
508         int compare(size_type pos, size_type n, value_type const * p,
509                     size_type n2 = npos) const;
510         
511         //@}
512
513         
514         
515         /**@name Substrings */
516         //@{
517
518         ///
519         lyxstring substr(size_type i = 0, size_type n = npos) const;
520         
521         //@}
522
523 private:
524         // These three operators can be used to discover erronous use of
525         // ints and strings. However a conforming C++ compiler will flag
526         // a lot of char operations as ambigous when they are compiled
527         // in. Use them for debugging only (or perhaps not even then.)
528         // Lgb.
529         //
530         //lyxstring & operator+(int);
531         //
532         //lyxstring & operator=(int);
533         //
534         //lyxstring & operator+=(int);
535
536         /// Compare this with s. works with embedded '\0' chars also.
537         int internal_compare(size_type pos, size_type n,
538                              value_type const * s,
539                              size_type slen, size_type n2) const;
540                 
541         /// Forward declaration of the string representation
542         struct Srep;
543         // DEC cxx requires this.
544         friend struct Srep;
545
546         /// A string is a pointer to it's representation
547         Srep * rep;
548
549         /** Note: The empty_rep is a local static in each function that
550             benefits from one. There is no "global" empty srep but lyxstring
551             doesn't need one (no code actually relies upon a single
552             empty srep).
553             This overcomes *all* "static initialization" problems,
554             at maximum speed, with a small overhead of a few local static
555             empty_reps.
556         */
557
558 #ifdef DEVEL_VERSION
559         /// lyxstringInvariant is used to test the lyxstring Invariant
560         friend class lyxstringInvariant;
561 #endif
562 };
563
564 // The usual comparison operators ==, !=, >, <, >=, <= are
565 // provided for lyxstrings
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 bool operator>=(lyxstring const &, lyxstring const &);
588 bool operator>=(lyxstring::value_type const *, lyxstring const &);
589 bool operator>=(lyxstring const &, lyxstring::value_type const *);
590
591
592 bool operator<=(lyxstring const &, lyxstring const &);
593 bool operator<=(lyxstring::value_type const *, lyxstring const &);
594 bool operator<=(lyxstring const &, lyxstring::value_type const *);
595
596
597 // Concatenation
598
599 lyxstring operator+(lyxstring const & a, lyxstring const & b);
600 lyxstring operator+(char const * a, lyxstring const & b);
601 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
602 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
603 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
604
605 void swap(lyxstring & s1, lyxstring & s2);
606
607 istream & operator>>(istream &, lyxstring &);
608 ostream & operator<<(ostream &, lyxstring const &);
609 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');
610
611 #endif