[2015] | 1 | /* ========================================================================
|
---|
| 2 | * (C) 2000 Vienna University of Technology
|
---|
| 3 | * ========================================================================
|
---|
| 4 | * PROJECT: Urban Viz
|
---|
| 5 | * ========================================================================*/
|
---|
| 6 | /** very handy template String class.
|
---|
| 7 | *
|
---|
| 8 | * for char-strings, 'String' is typedef'd for convenience
|
---|
| 9 | * Note: can be used standalone in all std-conforming C++ environments
|
---|
| 10 | *
|
---|
| 11 | * $Header: /usr/local/cvsyare/cvsyamp/include/mstring.h,v 1.1 2002/11/14 15:22:48 wimmer Exp $
|
---|
| 12 | * @author Michael Wimmer
|
---|
| 13 | * @file */
|
---|
| 14 | /* ========================================================================*/
|
---|
| 15 |
|
---|
| 16 | #ifndef NO_PRAGMA_ONCE
|
---|
| 17 | #pragma once
|
---|
| 18 | #endif
|
---|
| 19 |
|
---|
| 20 | #ifndef MSTRING_H
|
---|
| 21 | #define MSTRING_H
|
---|
| 22 |
|
---|
| 23 | // remove completely stupid MSVC warning
|
---|
| 24 | #ifdef _MSC_VER
|
---|
| 25 | #pragma warning(disable: 4786) // 'identifier' : identifier was truncated to
|
---|
| 26 | // 'number' characters in the debug information
|
---|
| 27 | #endif
|
---|
| 28 |
|
---|
| 29 | // Note: this always uses namespace std. no namespace precautions!
|
---|
| 30 | #include <string>
|
---|
| 31 | using std::basic_string;
|
---|
| 32 |
|
---|
| 33 | // ---------------------------------------------------------------------------
|
---|
| 34 | // class mbasic_string definition
|
---|
| 35 | // ---------------------------------------------------------------------------
|
---|
| 36 |
|
---|
| 37 | // internally used
|
---|
| 38 | static const char *MSTRING_WHITESPACE = " \t";
|
---|
| 39 |
|
---|
| 40 |
|
---|
| 41 | /** Very handy String class.
|
---|
| 42 | Normally, you would use \c mbasic_string<char>, here typedef'd as 'String'.
|
---|
| 43 |
|
---|
| 44 | Improves upon basic_string by adding:
|
---|
| 45 | - most importantly, a cast to const char *
|
---|
| 46 | - some useful Basic like operations,
|
---|
| 47 | such as Left, Mid, Right, Trim, Upper, ...
|
---|
| 48 | */
|
---|
| 49 | template<class E>
|
---|
| 50 | class mbasic_string : public basic_string<E> {
|
---|
| 51 | public:
|
---|
| 52 | // size_type not automatically looked up on sgis
|
---|
| 53 | typedef typename basic_string<E>::size_type size_type;
|
---|
| 54 |
|
---|
| 55 | //-- Constructors
|
---|
| 56 |
|
---|
| 57 | /// various constructors
|
---|
| 58 | mbasic_string() : basic_string<E>() {}
|
---|
| 59 |
|
---|
| 60 | ///
|
---|
| 61 | mbasic_string(const E *s) : basic_string<E>(s) {}
|
---|
| 62 |
|
---|
| 63 | ///
|
---|
| 64 | mbasic_string(size_type n, const E c) : basic_string<E>(n, c) {}
|
---|
| 65 |
|
---|
| 66 | ///
|
---|
| 67 | mbasic_string(const E c) : basic_string<E>(1, c) {}
|
---|
| 68 |
|
---|
| 69 | ///
|
---|
| 70 | mbasic_string(const mbasic_string<E>& mbs) : basic_string<E>(mbs) {}
|
---|
| 71 |
|
---|
| 72 | ///
|
---|
| 73 | mbasic_string(const basic_string<E>& bs) : basic_string<E>(bs) {}
|
---|
| 74 |
|
---|
| 75 | //-- Assignment
|
---|
| 76 |
|
---|
| 77 | /// various assignment ops
|
---|
| 78 | mbasic_string& operator=(const E c)
|
---|
| 79 | { basic_string<E>::operator=(c); return *this; }
|
---|
| 80 |
|
---|
| 81 | ///
|
---|
| 82 | mbasic_string& operator=(const E *s)
|
---|
| 83 | { basic_string<E>::operator=(s); return *this; }
|
---|
| 84 |
|
---|
| 85 | ///
|
---|
| 86 | mbasic_string& operator=(const mbasic_string<E>& rhs)
|
---|
| 87 | { basic_string<E>::operator=((const basic_string<E>&)rhs);
|
---|
| 88 | return *this; }
|
---|
| 89 |
|
---|
| 90 | /// very useful!
|
---|
| 91 | operator const char*() const { return this->c_str(); }
|
---|
| 92 |
|
---|
| 93 | //-- special access
|
---|
| 94 |
|
---|
| 95 | /// n characters from position pos (n may be out of range)
|
---|
| 96 | mbasic_string substr(size_type pos = 0, size_type n = npos) const
|
---|
| 97 | { basic_string<E> res = basic_string<E>::substr(pos,n); return res; }
|
---|
| 98 |
|
---|
| 99 | /// leftmost nr characters (no problem if nr too large)
|
---|
| 100 | mbasic_string Left(size_type nr) const { return substr(0,nr); }
|
---|
| 101 |
|
---|
| 102 | /// rightmost nr characters (no problem if nr too large)
|
---|
| 103 | mbasic_string Right(size_type nr) const;
|
---|
| 104 |
|
---|
| 105 | /** substring from position 'from' to position 'to' (no problems
|
---|
| 106 | if args out of range) */
|
---|
| 107 | mbasic_string Mid(size_type from, size_type to) const
|
---|
| 108 | { if (from >= size() || from > to) return "";
|
---|
| 109 | else return substr(from,to-from+1); }
|
---|
| 110 |
|
---|
| 111 | //-- padding
|
---|
| 112 | mbasic_string Pad(char padchar, int length) const;
|
---|
| 113 |
|
---|
| 114 | //-- trimming
|
---|
| 115 |
|
---|
| 116 | /// @name Trimming, converting upper/lower case
|
---|
| 117 | //@{
|
---|
| 118 | /// removes whitespace (space, tab) from the right
|
---|
| 119 | mbasic_string& TrimRightSelf();
|
---|
| 120 |
|
---|
| 121 | /// removes whitespace (space, tab) from the left
|
---|
| 122 | mbasic_string& TrimLeftSelf();
|
---|
| 123 |
|
---|
| 124 | /// removes whitespace from both left and right
|
---|
| 125 | mbasic_string& TrimSelf();
|
---|
| 126 |
|
---|
| 127 | /// returns a 'right-trimmed' copy of string
|
---|
| 128 | mbasic_string TrimRight() const
|
---|
| 129 | { return mbasic_string<E>(*this).TrimRightSelf(); }
|
---|
| 130 |
|
---|
| 131 | /// returns a 'left-trimmed' copy of string
|
---|
| 132 | mbasic_string TrimLeft() const
|
---|
| 133 | { return mbasic_string<E>(*this).TrimLeftSelf(); }
|
---|
| 134 |
|
---|
| 135 | /// returns a 'trimmed' copy of string
|
---|
| 136 | mbasic_string Trim() const { return mbasic_string<E>(*this).TrimSelf();}
|
---|
| 137 |
|
---|
| 138 | //-- upper/lower conversion
|
---|
| 139 |
|
---|
| 140 | /// converts string to uppercase
|
---|
| 141 | mbasic_string& UpperSelf();
|
---|
| 142 |
|
---|
| 143 | /// converts string to uppercase
|
---|
| 144 | mbasic_string& LowerSelf();
|
---|
| 145 |
|
---|
| 146 | /// returns an uppercase copy of string
|
---|
| 147 | mbasic_string Upper() const { return mbasic_string<E>(*this).UpperSelf();}
|
---|
| 148 |
|
---|
| 149 | /// returns an uppercase copy of string
|
---|
| 150 | mbasic_string Lower() const { return mbasic_string<E>(*this).LowerSelf();}
|
---|
| 151 |
|
---|
| 152 | //@}
|
---|
| 153 |
|
---|
| 154 | //-- other stuff
|
---|
| 155 |
|
---|
| 156 | /** in contrast to empty(), also returns true if string is only
|
---|
| 157 | whitespace (space, tab) */
|
---|
| 158 | bool Empty() const;
|
---|
| 159 | };
|
---|
| 160 |
|
---|
| 161 | /// for convenience (that's what you'll use)
|
---|
| 162 | typedef mbasic_string<char> String;
|
---|
| 163 |
|
---|
| 164 | // ---------------------------------------------------------------------------
|
---|
| 165 | // class mbasic_string template member implementation
|
---|
| 166 | // ---------------------------------------------------------------------------
|
---|
| 167 |
|
---|
| 168 | template<class E>
|
---|
| 169 | inline mbasic_string<E> mbasic_string<E>::Right(size_type nr) const
|
---|
| 170 | {
|
---|
| 171 | // take care that pos doesn't become negative
|
---|
| 172 | if(nr > size())
|
---|
| 173 | {
|
---|
| 174 | return *this;
|
---|
| 175 | }
|
---|
| 176 | else
|
---|
| 177 | {
|
---|
| 178 | return substr(size()-nr, nr);
|
---|
| 179 | }
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 |
|
---|
| 183 | // ----- WARNING: the following only useful for E = char or similar!
|
---|
| 184 |
|
---|
| 185 | template<class E>
|
---|
| 186 | inline bool mbasic_string<E>::Empty() const
|
---|
| 187 | {
|
---|
| 188 | return (find_first_not_of(MSTRING_WHITESPACE) == npos);
|
---|
| 189 | }
|
---|
| 190 |
|
---|
| 191 |
|
---|
| 192 | template<class E>
|
---|
| 193 | inline mbasic_string<E>& mbasic_string<E>::TrimRightSelf()
|
---|
| 194 | {
|
---|
| 195 | if (!empty())
|
---|
| 196 | {
|
---|
| 197 | size_type pos = find_last_not_of(MSTRING_WHITESPACE);
|
---|
| 198 | if(pos == npos) // everything whitespace
|
---|
| 199 | erase();
|
---|
| 200 | else if(pos != size()-1) // pos = size()-1 -> no whitespace
|
---|
| 201 | erase(pos+1);
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | return *this;
|
---|
| 205 | }
|
---|
| 206 |
|
---|
| 207 |
|
---|
| 208 | template<class E>
|
---|
| 209 | inline mbasic_string<E>& mbasic_string<E>::TrimLeftSelf()
|
---|
| 210 | {
|
---|
| 211 |
|
---|
| 212 | if (!empty())
|
---|
| 213 | {
|
---|
| 214 | size_type pos = find_first_not_of(MSTRING_WHITESPACE);
|
---|
| 215 | if(pos == npos) // everything whitespace
|
---|
| 216 | erase();
|
---|
| 217 | else if(pos != 0)
|
---|
| 218 | erase(0 , pos);
|
---|
| 219 | }
|
---|
| 220 |
|
---|
| 221 | return *this;
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | template<class E>
|
---|
| 225 | inline mbasic_string<E>& mbasic_string<E>::TrimSelf()
|
---|
| 226 | {
|
---|
| 227 |
|
---|
| 228 | this->TrimRightSelf();
|
---|
| 229 |
|
---|
| 230 | this->TrimLeftSelf();
|
---|
| 231 |
|
---|
| 232 | return *this;
|
---|
| 233 | }
|
---|
| 234 |
|
---|
| 235 |
|
---|
| 236 | template<class E>
|
---|
| 237 | inline mbasic_string<E> &mbasic_string<E>::UpperSelf() {
|
---|
| 238 |
|
---|
| 239 | if (!empty())
|
---|
| 240 | for(size_type i = 0; i < length(); i++)
|
---|
| 241 | at(i) = (E)toupper(at(i));
|
---|
| 242 |
|
---|
| 243 | return *this;
|
---|
| 244 | }
|
---|
| 245 |
|
---|
| 246 | template<class E>
|
---|
| 247 | inline mbasic_string<E> &mbasic_string<E>::LowerSelf() {
|
---|
| 248 |
|
---|
| 249 | if (!empty())
|
---|
| 250 | for(size_type i = 0; i < length(); i++)
|
---|
| 251 | at(i) = (E)tolower(at(i));
|
---|
| 252 |
|
---|
| 253 | return *this;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | template<class E>
|
---|
| 257 | inline mbasic_string<E> mbasic_string<E>::Pad(char padchar, int length) const
|
---|
| 258 | {
|
---|
| 259 | mbasic_string<E> result(*this);
|
---|
| 260 | while (result.length() < length)
|
---|
| 261 | result += padchar;
|
---|
| 262 | return result;
|
---|
| 263 | }
|
---|
| 264 |
|
---|
| 265 | // --------- operator+() definitions
|
---|
| 266 |
|
---|
| 267 | /// string concatentation (defined multiple times to allow good overloads)
|
---|
| 268 | template<class E>
|
---|
| 269 | inline mbasic_string<E> operator+(const mbasic_string<E>& lhs,
|
---|
| 270 | const mbasic_string<E>& rhs)
|
---|
| 271 | {
|
---|
| 272 |
|
---|
| 273 | return mbasic_string<E>(lhs) += rhs;
|
---|
| 274 | }
|
---|
| 275 |
|
---|
| 276 |
|
---|
| 277 | ///
|
---|
| 278 | template<class E>
|
---|
| 279 | inline mbasic_string<E> operator+(const mbasic_string<E>& lhs, const E *rhs)
|
---|
| 280 | {
|
---|
| 281 |
|
---|
| 282 | return mbasic_string<E>(lhs) += rhs;
|
---|
| 283 | }
|
---|
| 284 |
|
---|
| 285 | ///
|
---|
| 286 | template<class E>
|
---|
| 287 | inline mbasic_string<E> operator+(const mbasic_string<E>& lhs, const E rhs)
|
---|
| 288 | {
|
---|
| 289 |
|
---|
| 290 | return mbasic_string<E>(lhs) += rhs;
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | ///
|
---|
| 294 | template<class E>
|
---|
| 295 | inline mbasic_string<E> operator+(const E *lhs, const mbasic_string<E>& rhs)
|
---|
| 296 | {
|
---|
| 297 |
|
---|
| 298 | return mbasic_string<E>(lhs) += rhs;
|
---|
| 299 | }
|
---|
| 300 |
|
---|
| 301 | ///
|
---|
| 302 | template<class E>
|
---|
| 303 | inline mbasic_string<E> operator+(const E lhs, const mbasic_string<E>& rhs)
|
---|
| 304 | {
|
---|
| 305 |
|
---|
| 306 | return mbasic_string<E>(1,lhs) += rhs;
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 | #endif // _MSTRING_H
|
---|