]> git.lyx.org Git - lyx.git/blob - src/support/lyxstring.h
removed a warning from screen and added CFLAGS in lyx.spec.in.
[lyx.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 #ifdef HAVE_CONFIG_H
29 #include <config.h> // needed at least for compilers that do not
30 #endif              // understand `explicit' (JMarc)
31
32 #include "LOstream.h"
33 #include "LIstream.h"
34
35 #if 0
36 #include <iterator>
37 #endif
38
39 #include <cstring> // for size_t
40
41 /** A string class for LyX
42   
43   This is a permanent String class. It is modeled closely after the C++ STL
44   string class. In comparison with STL string lyxstring lack support for
45   reverse iterators and allocators, also char_traits is not used. In most
46   other senses it is written to be  a drop in replacement for STL string
47   (or as a transition tool). So documentation for STL string should be
48   valid for lyxstring too.
49
50   Notes for usage:
51
52   When you declare an lyxstring, it is initially empty. There is no need to
53   do things like #lyxstring a= "";#, especially not in constructors.
54
55   If you want to use a default empty lyxstring as a parameter, use
56   
57         #void foo(lyxstring par = lyxstring()); // Correct#
58   
59   rather than
60
61         #void foo(lyxstring par = "");  // WRONG!#
62         #void foo(lyxstring par = 0);   // WRONG!#
63
64   (The last one is only wrong because some compilers can't handle it.)
65
66   Methods that take an index as parameter all follow this rule: Valid indexes
67   go from 0 to length()-1.
68   \begin{tabular}{rl}
69   Correct: & #foo.substring(0, length()-1);# \\
70   Wrong:   & #bar.substring(0, length());#
71   \end{tabular}
72   
73   It is important that you declare lyxstring as const if possible, because
74   some methods are much more efficient in const versions.
75   
76   If you want to check whether a string is empty, do
77
78         #if (foo.empty()) something right#
79
80   rather than something along the lines of
81
82         #if (!foo) completely wrong#
83
84 When you want to copy an lyxstring, just do
85   
86         #lyxstring a, b = "String";#
87         #a = b; // That's it!#
88
89   not something like
90   
91         #lyxstring a, b = "String";#
92         #a = b.copy(); // This leaks. // and does not work either. #
93   
94   The class automatically handles deep copying when required.
95 */
96 class lyxstring {
97 public:
98         /**@name Typedefs */
99         //@{
100         
101         ///
102         typedef char value_type;
103
104         ///
105         typedef value_type * pointer;
106
107         ///
108         typedef value_type & reference;
109
110         ///
111         typedef value_type const & const_reference;
112
113         ///
114         typedef size_t size_type;
115
116         ///
117         typedef int difference_type;
118
119         ///
120         typedef value_type * iterator;
121         ///
122         typedef const value_type * const_iterator;
123 #if 0
124         ///
125         typedef reverse_iterator<iterator, value_type, reference>
126         reverse_iterator;
127         ///
128         typedef reverse_iterator<const_iterator, const value_type,
129                 const_reference> const_reverse_iterator;
130
131 #endif
132         //@}
133
134         ///
135         iterator begin();
136         ///
137         const_iterator begin() const;
138         ///
139         iterator end();
140         ///
141         const_iterator end() const;
142 #if 0
143         ///
144         reverse_iterator rbegin();
145         ///
146         const_reverse_iterator rbegin() const;
147         ///
148         reverse_iterator rend();
149         ///
150         const_reverse_iterator rend() const;
151 #endif
152         /**@name Constructors and Deconstructors. lyxstring has the same
153           constructors as STL, except the one using iterators, one other
154           difference is that lyxstring, do not allow the optional allocator
155           parameter. */
156         //@{
157         
158         /// "all characters" marker
159         static const size_type npos;
160
161         /// #lyxstring x;# 
162         lyxstring();
163         
164         /// #lyxstring x(lyxstring ...)# 
165         lyxstring(lyxstring const &, size_type pos = 0, size_type n = npos);
166         
167         /// #lyxstring x("abc", 2) -> "ab"#
168         lyxstring(value_type const *, size_type n);
169         
170         /// #lyxstring x("abc")#
171         lyxstring(value_type const *);
172         
173         /// lyxstring(5, 'n') -> "nnnnn"
174         lyxstring(size_type n, value_type c);
175
176         ///
177         lyxstring(iterator first, iterator last);
178         
179         ///
180         ~lyxstring();
181
182         //@}
183
184         
185         /**@name Size and Capacity */
186         //@{
187         
188         /// number of characters
189         size_type size() const;
190
191         /// largest possible string
192         size_type max_size() const { return npos -1; }
193
194         ///
195         size_type length() const { return size(); }
196
197         ///
198         bool empty() const { return size() == 0; }
199
200         ///
201         void resize(size_type n, value_type c);
202
203         ///
204         void resize(size_type n) { resize(n, ' '); }
205
206         /// size of the memory (in number of elements) allocated.
207         size_type capacity() const;
208
209         ///
210         void reserve(size_type res_arg = 0);
211         
212         //@}
213
214         /**@name Assignment */
215         //@{
216
217         ///
218         lyxstring & operator=(lyxstring const &);
219         
220         ///
221         lyxstring & operator=(value_type const *);
222         
223         ///
224         lyxstring & operator=(value_type);
225
226         ///
227         lyxstring & assign(lyxstring const &);
228         
229         ///
230         lyxstring & assign(lyxstring const &, size_type pos, size_type n);
231         
232         ///
233         lyxstring & assign(value_type const * p, size_type n);
234         
235         ///
236         lyxstring & assign(value_type const * p);
237         
238         ///
239         lyxstring & assign(size_type n, value_type c);
240
241         ///
242         lyxstring & assign(iterator first, iterator last);
243         
244         //@}
245
246         /**@name Element Access. Since lyxstring does not use exceptions,
247           an abort is called on out-of-range access to at(). */
248         
249         /// unchecked access
250         const_reference operator[](size_type) const;
251         
252         /// unchecked access
253         reference operator[](size_type);
254         
255         /// checked access
256         const_reference at(size_type) const;
257         
258         /// checked access
259         reference at(size_type);
260
261         //@}
262
263         /**@name Insert */
264         //@{
265         
266         // add characters after (*this)[length()-1]:
267         
268         ///
269         lyxstring & operator+=(lyxstring const &);
270         
271         ///
272         lyxstring & operator+=(value_type const *);
273         
274         ///
275         lyxstring & operator+=(value_type);
276
277         ///
278         void push_back(value_type);
279
280         ///
281         lyxstring & append(lyxstring const &);
282
283         ///
284         lyxstring & append(lyxstring const &, size_type pos, size_type n);
285
286         ///
287         lyxstring & append(value_type const *, size_type n);
288
289         ///
290         lyxstring & append(value_type const *);
291
292         ///
293         lyxstring & append(size_type n, value_type);
294
295         ///
296         lyxstring & append(iterator first, iterator last);
297         
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         ///
326         void insert(iterator p, iterator first, iterator last);
327         
328         //@}
329
330         /**@name Find */
331         //@{
332
333         ///
334         size_type find(lyxstring const &, size_type i = 0) const;
335         
336         ///
337         size_type find(value_type const * p,
338                          size_type i, size_type n) const;
339         
340         ///
341         size_type find(value_type const * p, size_type i = 0) const;
342         
343         ///
344         size_type find(value_type c, size_type i = 0) const;
345
346         ///
347         size_type rfind(lyxstring const &, size_type i = npos) const;
348         
349         ///
350         size_type rfind(value_type const * p, size_type i, size_type n) const;
351         
352         ///
353         size_type rfind(value_type const * p, size_type i = npos) const;
354         
355         ///
356         size_type rfind(value_type c, size_type i = npos) const;
357
358         ///
359         size_type find_first_of(lyxstring const &, size_type i = 0) const;
360         
361         ///
362         size_type find_first_of(value_type const * p, size_type i,
363                                 size_type n) const;
364         
365         ///
366         size_type find_first_of(value_type const * p, size_type i = 0) const;
367         
368         ///
369         size_type find_first_of(value_type c, size_type i = 0) const;
370
371         ///
372         size_type find_last_of(lyxstring const &, size_type i = npos) const;
373         
374         ///
375         size_type find_last_of(value_type const * p, size_type i,
376                                size_type n) const;
377         
378         ///
379         size_type find_last_of(value_type const * p, size_type i = npos) const;
380         
381         ///
382         size_type find_last_of(value_type c, size_type i = npos) const;
383
384         ///
385         size_type find_first_not_of(lyxstring const &, size_type i = 0) const;
386         
387         ///
388         size_type find_first_not_of(value_type const * p, size_type i,
389                                     size_type n) const;
390         
391         ///
392         size_type find_first_not_of(value_type const * p,
393                                     size_type i = 0) const;
394         
395         ///
396         size_type find_first_not_of(value_type c, size_type i = 0) const;
397
398         ///
399         size_type find_last_not_of(lyxstring const &,
400                                    size_type i = npos) const;
401         
402         ///
403         size_type find_last_not_of(value_type const * p, size_type i,
404                                    size_type n) const;
405         
406         ///
407         size_type find_last_not_of(value_type const * p,
408                                    size_type i = npos) const;
409         
410         ///
411         size_type find_last_not_of(value_type c, size_type i = npos) const;
412
413         //*}
414
415         
416         /**@name Replace */
417         //@{
418
419         // replace [(*this)[i], (*this)[i+n]] with other characters:
420
421         ///
422         lyxstring & replace(size_type i,size_type n, lyxstring const & str);
423
424         ///
425         lyxstring & replace(size_type i,size_type n, lyxstring const & s,
426                           size_type i2, size_type n2);
427
428         ///
429         lyxstring & replace(size_type i,size_type n, value_type const * p,
430                           size_type n2);
431
432         ///
433         lyxstring & replace(size_type i,size_type n, value_type const * p);
434
435         ///
436         lyxstring & replace(size_type i, size_type n,
437                             size_type n2, value_type c);
438
439         ///
440         lyxstring & replace(iterator i, iterator i2, const lyxstring & str);
441
442         ///
443         lyxstring & replace(iterator i, iterator i2,
444                           value_type const * p, size_type n);
445
446         ///
447         lyxstring & replace(iterator i, iterator i2, value_type const * p);
448
449         ///
450         lyxstring & replace(iterator i, iterator i2,
451                             size_type n , value_type c);
452         
453         ///
454         lyxstring & replace(iterator i, iterator i2, iterator j, iterator j2);
455
456         /// Erase n chars from position i.
457         lyxstring & erase(size_type i = 0, size_type n = npos);
458
459         ///
460         lyxstring & clear() {
461                 return erase(0, npos);
462         }
463
464         ///
465         iterator erase(iterator i);
466
467         ///
468         iterator erase(iterator first, iterator last);
469
470         //@}
471
472         
473         /**@name Conversion to C-style Strings */
474         //@{
475         
476         /// 
477         value_type const * c_str() const;
478
479         /** Note that this is STL compilant, so you can not assume
480           that the returned array has a trailing '\0'. */
481         value_type const * data() const;
482
483         /** This one returns a verbatim copy. Not the trailing '\0'
484           The caller must provide a buffer with engough room.
485           */
486         size_type copy(value_type * buf, size_type len,
487                        size_type pos = 0) const;
488
489         //@}
490
491         
492         /**@name Comparisons. Combined > and == */
493         //@{
494         
495         ///
496         int compare(lyxstring const & str) const; 
497
498         ///
499         int compare(value_type const * p) const;
500
501         ///
502         int compare(size_type pos, size_type n, lyxstring const & str) const;
503
504         ///
505         int compare(size_type pos, size_type n, lyxstring const & str,
506                     size_type pos2, size_type n2) const;
507
508         ///
509         int compare(size_type pos, size_type n, value_type const * p,
510                     size_type n2 = npos) const;
511         
512         //@}
513
514         
515         
516         /**@name Substrings */
517         //@{
518
519         ///
520         lyxstring substr(size_type i = 0, size_type n = npos) const;
521         
522         //@}
523
524 private:
525         // These three operators can be used to discover erronous use of
526         // ints and strings. However a conforming C++ compiler will flag
527         // a lot of char operations as ambigous when they are compiled
528         // in. Use them for debugging only (or perhaps not even then.)
529         // Lgb.
530         //
531         //lyxstring & operator+(int);
532         //
533         //lyxstring & operator=(int);
534         //
535         //lyxstring & operator+=(int);
536         
537         /// Forward declaration of the string representation
538         struct Srep;
539         // DEC cxx requires this.
540         friend struct Srep;
541
542         /// A string is a pointer to it's representation
543         Srep * rep;
544
545         /** Note: The empty_rep is a local static in each function that
546             benefits from one. There is no "global" empty srep but lyxstring
547             doesn't need one (no code actually relies upon a single
548             empty srep).
549             This overcomes *all* "static initialization" problems,
550             at maximum speed, with a small overhead of a few local static
551             empty_reps.
552         */
553
554 #ifdef DEVEL_VERSION
555         /// lyxstringInvariant is used to test the lyxstring Invariant
556         friend class lyxstringInvariant;
557 #endif
558 };
559
560 // The usual comparison operators ==, !=, >, <, >=, <= are
561 // provided for lyxstrings
562
563 bool operator==(lyxstring const &, lyxstring const &);
564 bool operator==(lyxstring::value_type const *, lyxstring const &);
565 bool operator==(lyxstring const &, lyxstring::value_type const *);
566
567
568 bool operator!=(lyxstring const &, lyxstring const &);
569 bool operator!=(lyxstring::value_type const *, lyxstring const &);
570 bool operator!=(lyxstring const &, lyxstring::value_type const *);
571
572
573 bool operator>(lyxstring const &, lyxstring const &);
574 bool operator>(lyxstring::value_type const *, lyxstring const &);
575 bool operator>(lyxstring const &, lyxstring::value_type const *);
576
577
578 bool operator<(lyxstring const &, lyxstring const &);
579 bool operator<(lyxstring::value_type const *, lyxstring const &);
580 bool operator<(lyxstring const &, lyxstring::value_type const *);
581
582
583 bool operator>=(lyxstring const &, lyxstring const &);
584 bool operator>=(lyxstring::value_type const *, lyxstring const &);
585 bool operator>=(lyxstring const &, lyxstring::value_type const *);
586
587
588 bool operator<=(lyxstring const &, lyxstring const &);
589 bool operator<=(lyxstring::value_type const *, lyxstring const &);
590 bool operator<=(lyxstring const &, lyxstring::value_type const *);
591
592
593 // Concatenation
594
595 lyxstring operator+(lyxstring const & a, lyxstring const & b);
596 lyxstring operator+(char const * a, lyxstring const & b);
597 lyxstring operator+(lyxstring::value_type a, lyxstring const & b);
598 lyxstring operator+(lyxstring const & a, lyxstring::value_type const * b);
599 lyxstring operator+(lyxstring const & a, lyxstring::value_type b);
600
601 istream & operator>>(istream &, lyxstring &);
602 ostream & operator<<(ostream &, lyxstring const &);
603 istream & getline(istream &, lyxstring &, lyxstring::value_type delim = '\n');
604
605 #endif