Imported Upstream version 1.22.4
[platform/upstream/groff.git] / src / include / stringclass.h
1 // -*- C++ -*-
2 /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
3      Written by James Clark (jjc@jclark.com)
4
5 This file is part of groff.
6
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
19
20 #include <string.h>
21 #include <stdio.h>
22 #include <assert.h>
23
24 // Ensure that the first declaration of functions that are later
25 // declared as inline declares them as inline.
26
27 class string;
28
29 inline string operator+(const string &, const string &);
30 inline string operator+(const string &, const char *);
31 inline string operator+(const char *, const string &);
32 inline string operator+(const string &, char);
33 inline string operator+(char, const string &);
34 inline int operator==(const string &, const string &);
35 inline int operator!=(const string &, const string &);
36
37 class string {
38 public:
39   string();
40   string(const string &);
41   string(const char *);
42   string(const char *, int);
43   string(char);
44
45   ~string();
46   
47   string &operator=(const string &);
48   string &operator=(const char *);
49   string &operator=(char);
50
51   string &operator+=(const string &);
52   string &operator+=(const char *);
53   string &operator+=(char);
54   void append(const char *, int);
55   
56   int length() const;
57   int empty() const;
58   int operator*() const;
59
60   string substring(int i, int n) const;
61
62   char &operator[](int);
63   char operator[](int) const;
64
65   void set_length(int i);
66   const char *contents() const;
67   int search(char) const;
68   char *extract() const;
69   void remove_spaces();
70   void clear();
71   void move(string &);
72
73   friend string operator+(const string &, const string &);
74   friend string operator+(const string &, const char *);
75   friend string operator+(const char *, const string &);
76   friend string operator+(const string &, char);
77   friend string operator+(char, const string &);
78          
79   friend int operator==(const string &, const string &);
80   friend int operator!=(const string &, const string &);
81   friend int operator<=(const string &, const string &);
82   friend int operator<(const string &, const string &);
83   friend int operator>=(const string &, const string &);
84   friend int operator>(const string &, const string &);
85
86 private:
87   char *ptr;
88   int len;
89   int sz;
90
91   string(const char *, int, const char *, int); // for use by operator+
92   void grow1();
93 };
94
95
96 inline char &string::operator[](int i)
97 {
98   assert(i >= 0 && i < len);
99   return ptr[i];
100 }
101
102 inline char string::operator[](int i) const
103 {
104   assert(i >= 0 && i < len);
105   return ptr[i];
106 }
107
108 inline int string::length() const
109 {
110   return len;
111 }
112
113 inline int string::empty() const
114 {
115   return len == 0;
116 }
117
118 inline int string::operator*() const
119 {
120   return len;
121 }
122
123 inline const char *string::contents() const
124 {
125   return ptr;
126 }
127
128 inline string operator+(const string &s1, const string &s2)
129 {
130   return string(s1.ptr, s1.len, s2.ptr, s2.len);
131 }
132
133 inline string operator+(const string &s1, const char *s2)
134 {
135 #ifdef __GNUG__
136   if (s2 == 0)
137     return s1;
138   else
139     return string(s1.ptr, s1.len, s2, strlen(s2));
140 #else
141   return s2 == 0 ? s1 : string(s1.ptr, s1.len, s2, strlen(s2));
142 #endif
143 }
144
145 inline string operator+(const char *s1, const string &s2)
146 {
147 #ifdef __GNUG__
148   if (s1 == 0)
149     return s2;
150   else
151     return string(s1, strlen(s1), s2.ptr, s2.len);
152 #else
153   return s1 == 0 ? s2 : string(s1, strlen(s1), s2.ptr, s2.len);
154 #endif
155 }
156
157 inline string operator+(const string &s, char c)
158 {
159   return string(s.ptr, s.len, &c, 1);
160 }
161
162 inline string operator+(char c, const string &s)
163 {
164   return string(&c, 1, s.ptr, s.len);
165 }
166
167 inline int operator==(const string &s1, const string &s2)
168 {
169   return (s1.len == s2.len 
170           && (s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) == 0));
171 }
172
173 inline int operator!=(const string &s1, const string &s2)
174 {
175   return (s1.len != s2.len 
176           || (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0));
177 }
178
179 inline string string::substring(int i, int n) const
180 {
181   assert(i >= 0 && i + n <= len);
182   return string(ptr + i, n);
183 }
184
185 inline string &string::operator+=(char c)
186 {
187   if (len >= sz)
188     grow1();
189   ptr[len++] = c;
190   return *this;
191 }
192
193 void put_string(const string &, FILE *);
194
195 string as_string(int);