| 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 |
|