1 /* |
|
2 Copyright 2012-2014 Santeri Piippo |
|
3 All rights reserved. |
|
4 |
|
5 Redistribution and use in source and binary forms, with or without |
|
6 modification, are permitted provided that the following conditions |
|
7 are met: |
|
8 |
|
9 1. Redistributions of source code must retain the above copyright |
|
10 notice, this list of conditions and the following disclaimer. |
|
11 2. Redistributions in binary form must reproduce the above copyright |
|
12 notice, this list of conditions and the following disclaimer in the |
|
13 documentation and/or other materials provided with the distribution. |
|
14 3. The name of the author may not be used to endorse or promote products |
|
15 derived from this software without specific prior written permission. |
|
16 |
|
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 |
|
29 #ifndef BOTC_STRING_H |
|
30 #define BOTC_STRING_H |
|
31 |
|
32 #include <deque> |
|
33 #include <string> |
|
34 #include <stdarg.h> |
|
35 #include "types.h" |
|
36 #include "containers.h" |
|
37 |
|
38 class string; |
|
39 class string_list; |
|
40 |
|
41 // ============================================================================= |
|
42 // |
|
43 class string |
|
44 { |
|
45 public: |
|
46 typedef typename ::std::string::iterator iterator; |
|
47 typedef typename ::std::string::const_iterator const_iterator; |
|
48 using length_type = int; |
|
49 |
|
50 string() {} |
|
51 |
|
52 explicit string (char a) |
|
53 { |
|
54 m_string = &a; |
|
55 } |
|
56 |
|
57 string (const char* data) |
|
58 { |
|
59 m_string = data; |
|
60 } |
|
61 |
|
62 string (std::string data) |
|
63 { |
|
64 m_string = data; |
|
65 } |
|
66 |
|
67 void dump() const; |
|
68 int compare (const string& other) const; |
|
69 bool ends_with (const string& other); |
|
70 int count (const char needle) const; |
|
71 int first (const char* c, length_type a = 0) const; |
|
72 int last (const char* c, length_type a = -1) const; |
|
73 string to_lowercase() const; |
|
74 bool is_numeric() const; |
|
75 bool mask (const string& pattern) const; |
|
76 length_type posof (int n) const; |
|
77 void prepend (string a); |
|
78 void replace (const char* a, const char* b); |
|
79 string_list split (string del) const; |
|
80 string_list split (char del) const; |
|
81 void sprintf (const char* fmtstr, ...); |
|
82 bool starts_with (const string& other); |
|
83 string strip (list< char > unwanted); |
|
84 string substring (long a, long b = -1) const; |
|
85 double to_double (bool* ok = nullptr) const; |
|
86 float to_float (bool* ok = nullptr) const; |
|
87 long to_long (bool* ok = nullptr, int base = 10) const; |
|
88 void trim (length_type n); |
|
89 string to_uppercase() const; |
|
90 |
|
91 string operator+ (const string& data) const; |
|
92 string operator+ (const char* data) const; |
|
93 string operator+ (int num) const; |
|
94 string& operator+= (const string data); |
|
95 string& operator+= (const char* data); |
|
96 string& operator+= (int num); |
|
97 |
|
98 static string from_number (int a); |
|
99 static string from_number (long a); |
|
100 |
|
101 inline bool is_empty() const |
|
102 { |
|
103 return m_string[0] == '\0'; |
|
104 } |
|
105 |
|
106 inline void append (const char* data) |
|
107 { |
|
108 m_string.append (data); |
|
109 } |
|
110 |
|
111 inline void append (const char data) |
|
112 { |
|
113 m_string.push_back (data); |
|
114 } |
|
115 |
|
116 inline void append (const string& data) |
|
117 { |
|
118 m_string.append (data.chars()); |
|
119 } |
|
120 |
|
121 inline iterator begin() |
|
122 { |
|
123 return m_string.begin(); |
|
124 } |
|
125 |
|
126 inline const_iterator begin() const |
|
127 { |
|
128 return m_string.cbegin(); |
|
129 } |
|
130 |
|
131 inline int capacity() const |
|
132 { |
|
133 return m_string.capacity(); |
|
134 } |
|
135 |
|
136 inline const char* chars() const |
|
137 { |
|
138 return m_string.c_str(); |
|
139 } |
|
140 |
|
141 inline const char* c_str() const |
|
142 { |
|
143 return m_string.c_str(); |
|
144 } |
|
145 |
|
146 inline iterator end() |
|
147 { |
|
148 return m_string.end(); |
|
149 } |
|
150 |
|
151 inline const_iterator end() const |
|
152 { |
|
153 return m_string.end(); |
|
154 } |
|
155 |
|
156 inline void clear() |
|
157 { |
|
158 m_string.clear(); |
|
159 } |
|
160 |
|
161 inline bool empty() const |
|
162 { |
|
163 return m_string.empty(); |
|
164 } |
|
165 |
|
166 inline void erase (length_type pos) |
|
167 { |
|
168 m_string.erase (m_string.begin() + pos); |
|
169 } |
|
170 |
|
171 inline void insert (length_type pos, char c) |
|
172 { |
|
173 m_string.insert (m_string.begin() + pos, c); |
|
174 } |
|
175 |
|
176 inline length_type length() const |
|
177 { |
|
178 return m_string.length(); |
|
179 } |
|
180 |
|
181 inline int max_size() const |
|
182 { |
|
183 return m_string.max_size(); |
|
184 } |
|
185 |
|
186 inline string mid (int a, int len) const |
|
187 { |
|
188 return m_string.substr (a, len); |
|
189 } |
|
190 |
|
191 inline void remove (int pos, int len) |
|
192 { |
|
193 m_string.replace (pos, len, ""); |
|
194 } |
|
195 |
|
196 inline void remove_from_start (int len) |
|
197 { |
|
198 remove (0, len); |
|
199 } |
|
200 |
|
201 inline void remove_from_end (int len) |
|
202 { |
|
203 remove (length() - len, len); |
|
204 } |
|
205 |
|
206 inline void resize (int n) |
|
207 { |
|
208 m_string.resize (n); |
|
209 } |
|
210 |
|
211 inline void replace (int pos, int n, const string& a) |
|
212 { |
|
213 m_string.replace (pos, n, a.chars()); |
|
214 } |
|
215 |
|
216 inline void shrink_to_fit() |
|
217 { |
|
218 m_string.shrink_to_fit(); |
|
219 } |
|
220 |
|
221 inline const std::string& std_string() const |
|
222 { |
|
223 return m_string; |
|
224 } |
|
225 |
|
226 inline string strip (char unwanted) |
|
227 { |
|
228 return strip ( {unwanted}); |
|
229 } |
|
230 |
|
231 string& operator+= (const char data) |
|
232 { |
|
233 append (data); |
|
234 return *this; |
|
235 } |
|
236 |
|
237 string operator- (int n) const |
|
238 { |
|
239 string new_string = m_string; |
|
240 new_string -= n; |
|
241 return new_string; |
|
242 } |
|
243 |
|
244 inline string& operator-= (int n) |
|
245 { |
|
246 trim (n); |
|
247 return *this; |
|
248 } |
|
249 |
|
250 inline string operator+() const |
|
251 { |
|
252 return to_uppercase(); |
|
253 } |
|
254 |
|
255 inline string operator-() const |
|
256 { |
|
257 return to_lowercase(); |
|
258 } |
|
259 |
|
260 inline bool operator== (const string& other) const |
|
261 { |
|
262 return std_string() == other.std_string(); |
|
263 } |
|
264 |
|
265 inline bool operator== (const char* other) const |
|
266 { |
|
267 return operator== (string (other)); |
|
268 } |
|
269 |
|
270 inline bool operator!= (const string& other) const |
|
271 { |
|
272 return std_string() != other.std_string(); |
|
273 } |
|
274 |
|
275 inline bool operator!= (const char* other) const |
|
276 { |
|
277 return operator!= (string (other)); |
|
278 } |
|
279 |
|
280 inline bool operator> (const string& other) const |
|
281 { |
|
282 return std_string() > other.std_string(); |
|
283 } |
|
284 |
|
285 inline bool operator< (const string& other) const |
|
286 { |
|
287 return std_string() < other.std_string(); |
|
288 } |
|
289 |
|
290 inline operator const char*() const |
|
291 { |
|
292 return chars(); |
|
293 } |
|
294 |
|
295 inline operator const std::string&() const |
|
296 { |
|
297 return std_string(); |
|
298 } |
|
299 |
|
300 // Difference between indices @a and @b. @b can be -1, in which |
|
301 // case it will be length() - 1. |
|
302 inline int index_difference (int a, int b) |
|
303 { |
|
304 assert (b == -1 || b >= a); |
|
305 return (b != -1 ? b - a : length() - 1 - a); |
|
306 } |
|
307 |
|
308 private: |
|
309 std::string m_string; |
|
310 }; |
|
311 |
|
312 // ============================================================================= |
|
313 // |
|
314 class string_list : public list<string> |
|
315 { |
|
316 public: |
|
317 string_list() {} |
|
318 string_list (std::initializer_list<string> vals) : |
|
319 list<string> (vals) {} |
|
320 string_list (const list<string>& a) : list<string> (a.std_deque()) {} |
|
321 string_list (const list_type& a) : list<string> (a) {} |
|
322 |
|
323 string join (const string& delim); |
|
324 }; |
|
325 |
|
326 bool operator== (const char* a, const string& b); |
|
327 string operator+ (const char* a, const string& b); |
|
328 |
|
329 #endif // BOTC_STRING_H |
|