4d80d608ebf9dba132b2f3702cc3ac7872b58c5c
[AXE.git] / src / String.h
1 /**************************************************************************
2 **  (c) Copyright 1997, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : String.h
7 **      SYSTEM NAME    : Andromeda X-Windows Encapsulation
8 **      VERSION NUMBER : $Revision: 1.2 $
9 **
10 **  DESCRIPTION      :  Character String class definition
11 **
12 **  EXPORTED OBJECTS : class String
13 **  LOCAL    OBJECTS : class substring
14 **  MODULES  USED    :
15 ***************************************************************************
16 **  ADMINISTRATIVE INFORMATION *
17 ********************************
18 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 **      CREATION DATE   : Nov 17, 1995
20 **      LAST UPDATE     : Feb 23, 2001
21 **      MODIFICATIONS   : 
22 **************************************************************************/
23
24 /*****************************
25    $Log: String.h,v $
26    Revision 1.2  2002-09-28 06:45:51  arjen
27    New feature: subtring selection by regular expression.
28    Bugfix: use the std: namespace for STL classes istream and ostream
29
30    Revision 1.1  2002/07/25 08:01:26  arjen
31    First checkin, AXE release 0.2
32
33 *****************************/
34
35 // static const char RCSID[] = "$Id: String.h,v 1.2 2002-09-28 06:45:51 arjen Exp $";
36
37 #ifndef STRING_H
38 #define STRING_H
39
40 #include <stdlib.h>
41 #include <iostream>
42 #include <string.h>
43
44 #include <regex.h>
45
46 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 **  NAME           : String - Character String class.
48 **  MEMBERS        : p -> s : Pointer to the actual String data.
49 **                   p -> n : Number of references to this String.
50 **  OPERATORS      : =      : Assign a String, char *, char to a String.
51 **                   +, +=  : concatenate Strings
52 **                   ~      : Length of a String
53 **                   []     : Individual character access.
54 **                   !      : Empty String test.
55 **                   ()     : Substring selection.
56 **                   ostream << : String to output stream.
57 **                   istream << : String from input stream.
58 **                   ==, !=, <,
59 **                   >, <=, >= : String comparison.
60 **  METHODS        :
61 **
62 **  DESCRIPTION    : The String class counts the references to a String to
63 **                   minimize copying and uses standard C++ character strings
64 **                   as constants.
65 **
66 **  RELATIONS      : substring
67 **  SEE ALSO       :
68 **  LAST MODIFIED  : Aug 27, 1999
69 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
70 */
71
72
73 class String
74 {
75    friend class substring;
76    friend class regex;
77
78    struct srep
79    {
80       char  *s;    // pointer to data;
81       int    n;    // reference count
82    } *p;
83
84 public:
85
86    String(const char *);      // String x = "abc"
87    String(char);              // String x = 'a'
88    String();                  // String x;
89    String(const String &);    // String x = String ...
90    String(const substring &); // String x = String(s, l)
91
92    String& operator=(const char);
93    String& operator=(const char *);
94    String& operator=(const String &);
95    ~String();
96
97    /*  Numerical conversion */
98
99    String(long);             //  String x(12);  x = "12"
100    String(unsigned long);    //  String x(12);  x = "12"
101    String(int);              //  String x(12);  x = "12"
102    operator long()
103    {
104       return strtol(p->s, 0, 0);
105    }
106
107    operator unsigned long()
108    {
109       return strtoul(p->s, 0, 0);
110    }
111
112    long dec(void)
113    {
114       return strtol(p->s, 0, 10);
115    }
116
117    long oct(void)
118    {
119       return strtol(p->s, 0, 8);
120    }
121
122    long hex(void) 
123    {
124       return strtol(p->s, 0, 16);
125    }
126
127    String(double);
128    operator double()
129    {
130       return strtod(p->s, 0);
131    }
132
133    /*     */
134
135    char& operator[](int i);    //  Individual character access
136
137    int operator~() const      //  Length of the String
138    {
139       return strlen(p->s);
140    }
141
142    operator char*()
143    {
144       if (p->s && p->s[0])
145          return p->s;
146       else
147          return 0;
148    }
149    operator const char*() const
150    {
151       if (p->s && p->s[0])
152          return p->s;
153       else
154          return 0;
155    }
156
157    operator bool()   //  Test for empty String
158    {
159       return p->s != 0 && p->s[0] != '\0';
160    }
161
162    /*
163     *   String concatenation.
164     *   char and char* are handled by constructors.
165     */
166
167    String& operator+=(const String&);
168    String& operator+=(const char *);
169    friend String operator+(const String&, const String&);
170    friend String operator+(const String&, const char *);
171    friend String operator+(const char *,  const String&);
172
173    /*
174     *  Shifting characters out
175     *            "abcdefgh" <<= 3  = "defgh"
176     *            "abcdefgh" >>= 3  = "abcde"
177     */
178
179    friend String operator<<(const String &x, int n);
180    String & operator<<=(int n);
181
182    friend String operator>>(const String &x, int n);
183    String & operator>>=(int n);
184
185    /*
186     *   Substring selection
187     *
188     *   A substring can be selected by a start index and a length or
189     *   by matching a regular expression.
190     *
191     *   Selecting a substring by regular expression, combined with
192     *   the lvalue semantics of the substring class is a particularly
193     *   powerful concept. Possible uses are for example:
194     *
195     *   (assuming String S, M; regex R;)
196     *   M = S(R);             ->  Returns matching part of S into M.
197     *   S(R) = "replacement"; -> replace matching part of S.
198     *   S(R) = "";            -> Removes matching part from S.
199     *   S(R) == S;            -> true if and only if all of S matches R exactly.
200     */
201
202    substring operator()(int start, int len);
203    substring operator()(const regex &r);
204
205    /*
206     *   Input and output
207     */
208
209    friend std::ostream& operator<<(std::ostream &, const String &);
210    friend std::istream& operator>>(std::istream &, String &);
211
212    /*
213     *   String comparison tests
214     */
215
216    friend int operator==(const String& x, const String& y)
217    {
218       return strcmp(x.p->s, y.p->s) == 0;
219    }
220
221    friend int operator!=(const String& x, const String& y)
222    {
223       return strcmp(x.p->s, y.p->s) != 0;
224    }
225
226    friend int operator<=(const String& x, const String& y)
227    {
228       return strcmp(x.p->s, y.p->s) <= 0;
229    }
230
231    friend int operator>=(const String& x, const String& y)
232    {
233       return strcmp(x.p->s, y.p->s) >= 0;
234    }
235
236    friend int operator<(const String& x, const String& y)
237    {
238       return strcmp(x.p->s, y.p->s) < 0;
239    }
240
241    friend int operator>(const String& x, const String& y)
242    {
243       return strcmp(x.p->s, y.p->s) > 0;
244    }
245
246    friend int operator==(const String& x, const char * y)
247    {
248       return strcmp(x.p->s, y) == 0;
249    }
250
251    friend int operator!=(const String& x, const char * y)
252    {
253       return strcmp(x.p->s, y) != 0;
254    }
255
256    friend int operator<=(const String& x, const char * y)
257    {
258       return strcmp(x.p->s, y) <= 0;
259    }
260
261    friend int operator>=(const String& x, const char * y)
262    {
263       return strcmp(x.p->s, y) >= 0;
264    }
265
266    friend int operator<(const String& x, const char * y)
267    {
268       return strcmp(x.p->s, y) < 0;
269    }
270
271    friend int operator>(const String& x, const char * y)
272    {
273       return strcmp(x.p->s, y) > 0;
274    }
275
276    /*
277     *  Modifiers
278     */
279
280    String upper(void);
281    String lower(void);
282
283    /*
284     *  Character searching and Pattern matching
285     */
286
287    int index(char c);
288    int rindex(char c);
289
290    int in(String & x);
291
292    //  Regular expression pattern matching
293  
294    friend bool operator == (const String &s, const regex &r);
295    friend bool operator == (const regex &r, const String &s);
296 };
297    /*
298     *   Other operators to think about...
299     *
300     *
301     *   Numeric conversion with strtod and strtol and vice-versa,
302     *   so we can do:
303     *                 String nr = 123  //  nr = "123"
304     *                 float x = 2.32; String f = x;  // f = "2.32"
305     *                             f = "3.145";
306     *                         int i = f;           // i = 3
307     *
308     *   String matching:
309     *       int index(String&, start=0)  // Find position of substring
310     *
311     *
312     *  Literature:  Bjarne Stroustrup, Section 6.9
313     *               DDJ October 1991, pg 24
314     */
315
316
317 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
318 **  NAME           : substring - Determine part of a String object.
319 **  MEMBERS        : str   : The String object of which this is a substring
320 **                   start : index of the first substring character.
321 **                   len   : Number of characters in the substring
322 **  OPERATORS      : =     : Assignment of a String or char *
323 **  METHODS        :
324 **
325 **  DESCRIPTION    : This implements substring selection from a String object
326 **                   with l-value semantics.
327 **
328 **  RELATIONS      : String
329 **  SEE ALSO       :
330 **  LAST MODIFIED  :
331 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332 */
333
334 class substring
335 {
336    friend class String;
337
338    String     *str;   //  Where I am a substring of.
339    int  start, len;
340
341 public:
342    String& operator=(const String &); 
343    String& operator=(char *s)
344    {
345       *this = String(s);
346       return *str;
347    }
348 };
349
350 /*  Regular expression matching */
351
352 class regex
353 {
354    friend class String;
355
356    regex_t    expression;
357
358 public:
359
360    regex(const String & reg);
361    regex(const char * reg);
362    ~regex();
363
364    friend bool operator == (const String &s, const regex &r);
365    friend bool operator == (const regex &r, const String &s);
366 };
367
368 #endif  /* STRING_H */