1. Abstract
std::string 與 std::wstring 是 C++ 提供的字串型別,雖然說已經相當不錯用,但與CString[1]、 C#、VB.Net等語言所提供的 String 型別相比較,還是沒那麼實用。
2. Introduction
在原本的 std::basic_string 上在添加更多的功能,如 format、trim、split等等。
1 #ifndef HAVE_STD_STRINGEX_H_INCLUDED
2 #define HAVE_STD_STRINGEX_H_INCLUDED
3 ///================================================================================///
4 ///================================================================================///
5 ///<類別名稱>
6 /// - base_stringex_t (Ver.4)
7 /// -
8 ///<使用說明>
9 /// - 1. 加強 C++ 標準庫中所提供的 std::basic_string 的功能上不足。
10 /// - 2. std::stringex 對應於 std::string。
11 /// - 3. std::wstringex 對應於 std::wstring。
12 /// - 4. 可以直接應用於 std::cout, std::cin, std::wcout, std::wcin。
13 /// -
14 ///<名稱空間範圍>
15 /// - std
16 /// -
17 ///<資料成員列表>
18 /// -
19 ///<成員函式列表>
20 /// - format()
21 /// - format_append()
22 /// - trim_left()
23 /// - trim_right()
24 /// - trim()
25 /// - trim_left() [Static版本]
26 /// - trim_right() [Static版本]
27 /// - trim() [Static版本]
28 /// - to_long()
29 /// - to_double()
30 /// - to_lower()
31 /// - to_upper()
32 /// - to_lower() [Static版本]
33 /// - to_upper() [Static版本]
34 /// - split() [傳回對應的 std::vector<std::stringex> or std::vector<std::wstringex>]
35 /// -
36 ///<繼承類別列表>
37 /// - Please lookup source code.
38 /// -
39 ///<特殊備註>
40 /// - Author : Awen.Su
41 /// - WebSite : http://awen.cnblogs.com/
42 /// - Copyright: BSD License
43 /// - Please do not remove the copyright information. Thank you !!!
44 /// -
45 ///================================================================================///
46 ///================================================================================///
47
48 ///C/C++ STANDARD INCLUDES
49 #include <string>
50 #include <sstream>
51 #include <vector>
52 #include <typeinfo>
53 #include <cstring>
54 #include <cstdarg>
55 #include <cwchar>
56 #include <cctype>
57 #include <cwctype>
58 #include <algorithm>
59 #include <iterator>
60
61 ///================================================================================///
62 ///================================================================================///
63 namespace std {
64 ///================================================================================///
65 ///================================================================================///
66
67 template <typename _Derived, typename _Elem>
68 class base_stringex_format;
69
70 template <typename _Derived>
71 class base_stringex_format<_Derived, char>
72 {
73 protected:
74 static const int MAX_BUFFER = 8192;
75
76 public:
77 _Derived& format(const char *fmt, )
78 {
79 _Derived *THIS = static_cast<_Derived*>(this);
80
81 char buffer[MAX_BUFFER] = {0};
82 int result = 0;
83
84 va_list args;
85 va_start(args, fmt);
86
87 result = vsnprintf(buffer, MAX_BUFFER - 1, fmt, args);
88
89 va_end(args);
90
91 THIS->assign(buffer, result);
92
93 return(*THIS);
94 }
95 };
96
97 template <typename _Derived>
98 class base_stringex_format<_Derived, wchar_t>
99 {
100 protected:
101 static const int MAX_BUFFER = 8192;
102
103 public:
104 _Derived& format(const wchar_t *fmt, )
105 {
106 /// 格式中的 %s 須改用 %S
107
108 _Derived *THIS = static_cast<_Derived*>(this);
109
110 wchar_t buffer[MAX_BUFFER] = {0};
111 int result= 0;
112
113 va_list args;
114 va_start(args, fmt);
115
116 result = vswprintf(buffer, MAX_BUFFER - 1, fmt, args);
117
118 va_end(args);
119
120 THIS->assign(buffer, result);
121
122 return(*THIS);
123 }
124 };
125
126 ///================================================================================///
127 ///================================================================================///
128
129 template <typename _Derived, typename _Elem>
130 class base_stringex_format_append;
131
132 template <typename _Derived>
133 class base_stringex_format_append<_Derived, char>
134 {
135 protected:
136 static const int MAX_BUFFER = 8192;
137
138 public:
139 _Derived& format_append(const char *fmt, )
140 {
141 _Derived *THIS = static_cast<_Derived*>(this);
142
143 char buffer[MAX_BUFFER] = {0};
144 int result = 0;
145
146 va_list args;
147 va_start(args, fmt);
148
149 result = vsnprintf(buffer, MAX_BUFFER - 1, fmt, args);
150
151 va_end(args);
152
153 THIS->append(buffer, result);
154
155 return(*THIS);
156 }
157 };
158
159 template <typename _Derived>
160 class base_stringex_format_append<_Derived, wchar_t>
161 {
162 protected:
163 static const int MAX_BUFFER = 8192;
164
165 public:
166 _Derived& format_append(const wchar_t *fmt, )
167 {
168 /// 格式中的 %s 須改用 %S
169
170 _Derived *THIS = static_cast<_Derived*>(this);
171
172 wchar_t buffer[MAX_BUFFER] = {0};
173 int result= 0;
174
175 va_list args;
176 va_start(args, fmt);
177
178 result = vswprintf(buffer, MAX_BUFFER - 1, fmt, args);
179
180 va_end(args);
181
182 THIS->append(buffer, result);
183
184 return(*THIS);
185 }
186 };
187
188 ///================================================================================///
189 ///================================================================================///
190
191 template <typename _Derived, typename _Elem>
192 class base_stringex_trim_left;
193
194 template <typename _Derived>
195 class base_stringex_trim_left<_Derived, char>
196 {
197 public:
198 _Derived& trim_left()
199 {
200 _Derived *THIS = static_cast<_Derived*>(this);
201
202 typename _Derived::size_type position = THIS->find_first_not_of(" \t\r\n");
203
204 if(position != std::basic_string<char>::npos)
205 THIS->erase(0, position);
206 else
207 THIS->erase();
208
209 return *THIS;
210 }
211
212 static _Derived trim_left(const _Derived _Source)
213 {
214 return static_cast<_Derived>(_Source).trim_left();
215 }
216 };
217
218 template <typename _Derived>
219 class base_stringex_trim_left<_Derived, wchar_t>
220 {
221 public:
222 _Derived& trim_left()
223 {
224 _Derived *THIS = static_cast<_Derived*>(this);
225
226 typename _Derived::size_type position = THIS->find_first_not_of(L" \t\r\n");
227
228 if(position != std::basic_string<wchar_t>::npos)
229 THIS->erase(0, position);
230 else
231 THIS->erase();
232
233 return(*THIS);
234 }
235
236 static _Derived trim_left(const _Derived _Source)
237 {
238 return static_cast<_Derived>(_Source).trim_left();
239 }
240 };
241
242 ///================================================================================///
243 ///================================================================================///
244
245 template <typename _Derived, typename _Elem>
246 class base_stringex_trim_right;
247
248 template <typename _Derived>
249 class base_stringex_trim_right<_Derived, char>
250 {
251 public:
252 _Derived& trim_right()
253 {
254 _Derived *THIS = static_cast<_Derived*>(this);
255
256 typename _Derived::size_type position = THIS->find_last_not_of(" \t\r\n");
257
258 if(position != std::basic_string<char>::npos)
259 THIS->erase(++position);
260
261 return(*THIS);
262 }
263
264 static _Derived trim_right(const _Derived _Source)
265 {
266 return static_cast<_Derived>(_Source).trim_right();
267 }
268 };
269
270 template <typename _Derived>
271 class base_stringex_trim_right<_Derived, wchar_t>
272 {
273 public:
274 _Derived& trim_right()
275 {
276 _Derived *THIS = static_cast<_Derived*>(this);
277
278 typename _Derived::size_type position = THIS->find_last_not_of(L" \t\r\n");
279
280 if(position != std::basic_string<wchar_t>::npos)
281 THIS->erase(++position);
282
283 return(*THIS);
284 }
285
286 static _Derived trim_right(const _Derived _Source)
287 {
288 return static_cast<_Derived>(_Source).trim_right();
289 }
290 };
291
292 ///================================================================================///
293 ///================================================================================///
294
295 template <typename _Derived, typename _Elem>
296 class base_stringex_trim;
297
298 template <typename _Derived>
299 class base_stringex_trim<_Derived, char>
300 {
301 public:
302 _Derived& trim()
303 {
304 _Derived *THIS = static_cast<_Derived*>(this);
305
306 THIS->trim_left().trim_right();
307
308 return(*THIS);
309 }
310
311 static _Derived trim(const _Derived _Source)
312 {
313 return static_cast<_Derived>(_Source).trim_left().trim_right();
314 }
315 };
316
317 template <typename _Derived>
318 class base_stringex_trim<_Derived, wchar_t>
319 {
320 public:
321 _Derived& trim()
322 {
323 _Derived *THIS = static_cast<_Derived*>(this);
324
325 THIS->trim_left().trim_right();
326
327 return(*THIS);
328 }
329
330 static _Derived trim(const _Derived _Source)
331 {
332 return static_cast<_Derived>(_Source).trim_left().trim_right();
333 }
334 };
335 ///================================================================================///
336 ///================================================================================///
337
338 template <typename _Derived, typename _Elem>
339 class base_stringex_to_integer;
340
341 template <typename _Derived>
342 class base_stringex_to_integer<_Derived, char>
343 {
344 public:
345 long to_long() const
346 {
347 std::stringstream _SS;
348 long _Result;
349
350 _Derived *THIS = static_cast<_Derived*>(this);
351
352 _SS << THIS->c_str();
353 _SS >> _Result;
354 _SS.clear();
355
356 return _Result;
357 }
358
359 double to_double() const
360 {
361 _Derived *THIS = static_cast<_Derived*>(this);
362
363 std::stringstream _SS;
364 double _Result;
365
366 _SS << THIS->c_str();
367 _SS >> _Result;
368 _SS.clear();
369
370 return _Result;
371 }
372 };
373
374 template <typename _Derived>
375 class base_stringex_to_integer<_Derived, wchar_t>
376 {
377 public:
378 long to_long() const
379 {
380 _Derived *THIS = static_cast<_Derived*>(this);
381
382 std::wstringstream _SS;
383 long _Result;
384
385 _SS << THIS->c_str();
386 _SS >> _Result;
387 _SS.clear();
388
389 return _Result;
390 }
391
392 double to_double() const
393 {
394 _Derived *THIS = static_cast<_Derived*>(this);
395
396 std::wstringstream _SS;
397 double _Result;
398
399 _SS << THIS->c_str();
400 _SS >> _Result;
401 _SS.clear();
402
403 return _Result;
404 }
405 };
406
407 ///================================================================================///
408 ///================================================================================///
409
410 template <typename _Derived, typename _Elem>
411 class base_stringex_case_converter;
412
413 template <typename _Derived>
414 class base_stringex_case_converter<_Derived, char>
415 {
416 public:
417 _Derived& to_lower()
418 {
419 _Derived *THIS = static_cast<_Derived*>(this);
420
421 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::tolower);
422
423 return *THIS;
424 }
425
426 _Derived& to_upper()
427 {
428 _Derived *THIS = static_cast<_Derived*>(this);
429
430 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::toupper);
431
432 return *THIS;
433 }
434
435 static _Derived to_lower(const _Derived &_In)
436 {
437 _Derived the_transfer;
438
439 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
440 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::tolower);
441
442 return the_transfer;
443 }
444
445 static _Derived to_upper(const _Derived &_In)
446 {
447 _Derived the_transfer;
448
449 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
450 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::toupper);
451
452 return the_transfer;
453 }
454 };
455
456
457 template <typename _Derived>
458 class base_stringex_case_converter<_Derived, wchar_t>
459 {
460 public:
461 _Derived& to_lower()
462 {
463 _Derived *THIS = static_cast<_Derived*>(this);
464
465 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::towlower);
466
467 return *THIS;
468 }
469
470 _Derived& to_upper()
471 {
472 _Derived *THIS = static_cast<_Derived*>(this);
473
474 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::towupper);
475
476 return *THIS;
477 }
478
479 static _Derived to_lower(const _Derived &_In)
480 {
481 _Derived the_transfer;
482
483 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
484 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::towlower);
485
486 return the_transfer;
487 }
488
489 static _Derived to_upper(const _Derived &_In)
490 {
491 _Derived the_transfer;
492
493 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
494 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::towupper);
495
496 return the_transfer;
497 }
498 };
499
500 ///================================================================================///
501 ///================================================================================///
502 template <typename _Derived, typename _Elem>
503 class base_stringex_split
504 {
505 public:
506 typename typedef std::vector<_Derived> split_type;
507
508 split_type split(const _Derived &_Delimiter) const
509 {
510 _Derived *THIS = static_cast<_Derived*>(this);
511
512 _Derived the_handler = *THIS;
513 split_type the_result;
514 int the_cut_at;
515
516 while((the_cut_at = the_handler.find_first_of(_Delimiter)) != the_handler.npos)
517 {
518 if(the_cut_at > 0)
519 {
520 the_result.push_back(the_handler.substr(0, the_cut_at));
521 }
522
523 the_handler = the_handler.substr(the_cut_at + 1);
524 }
525
526 if(the_handler.length() > 0)
527 the_result.push_back(the_handler);
528
529 return the_result;
530 }
531 };
532
533 ///================================================================================///
534 ///================================================================================///
535 // Class Implemented Here:
536 ///================================================================================///
537 ///================================================================================///
538 template <typename _Elem>
539 class base_stringex_t : public basic_string<_Elem>,
540 public base_stringex_format<base_stringex_t<_Elem>, _Elem>,
541 public base_stringex_format_append<base_stringex_t<_Elem>, _Elem>,
542 public base_stringex_trim_left<base_stringex_t<_Elem>, _Elem>,
543 public base_stringex_trim_right<base_stringex_t<_Elem>, _Elem>,
544 public base_stringex_trim<base_stringex_t<_Elem>, _Elem>,
545 public base_stringex_to_integer<base_stringex_t<_Elem>, _Elem>,
546 public base_stringex_case_converter<base_stringex_t<_Elem>, _Elem>,
547 public base_stringex_split<base_stringex_t<_Elem>, _Elem>
548 {
549 public:
550 typename typedef base_stringex_t<_Elem> impl_type;
551
552 base_stringex_t() : std::basic_string<_Elem>() {}
553 virtual ~base_stringex_t(){}
554
555 base_stringex_t(const base_stringex_t<_Elem> &in) : std::basic_string<_Elem>() { this->assign(in.c_str()); }
556 base_stringex_t(const std::basic_string<_Elem> &in) : std::basic_string<_Elem>() { this->assign(in); }
557 base_stringex_t(const _Elem *in, size_t size) : std::basic_string<_Elem>() { this->assign(in, size); }
558 base_stringex_t(const _Elem *in) : std::basic_string<_Elem>() { this->assign(in); }
559
560 base_stringex_t& operator=(const base_stringex_t<_Elem> &in)
561 {
562 if(this == &in) return(*this);
563 this->assign(in.c_str());
564 return(*this);
565 }
566
567 base_stringex_t& operator=(const std::basic_string<_Elem> &in) { this->assign(in); return(*this); }
568 base_stringex_t& operator=(const _Elem *in) { this->assign(in); return(*this); }
569
570 operator const _Elem*() const { return((*this).c_str()); }
571 };//class base_stringex_t
572
573 typedef base_stringex_t<char> stringex;
574 typedef base_stringex_t<wchar_t> wstringex;
575
576 }//namespace std
577 #endif//HAVE_STD_STRINGEX_H_INCLUDED
578
2 #define HAVE_STD_STRINGEX_H_INCLUDED
3 ///================================================================================///
4 ///================================================================================///
5 ///<類別名稱>
6 /// - base_stringex_t (Ver.4)
7 /// -
8 ///<使用說明>
9 /// - 1. 加強 C++ 標準庫中所提供的 std::basic_string 的功能上不足。
10 /// - 2. std::stringex 對應於 std::string。
11 /// - 3. std::wstringex 對應於 std::wstring。
12 /// - 4. 可以直接應用於 std::cout, std::cin, std::wcout, std::wcin。
13 /// -
14 ///<名稱空間範圍>
15 /// - std
16 /// -
17 ///<資料成員列表>
18 /// -
19 ///<成員函式列表>
20 /// - format()
21 /// - format_append()
22 /// - trim_left()
23 /// - trim_right()
24 /// - trim()
25 /// - trim_left() [Static版本]
26 /// - trim_right() [Static版本]
27 /// - trim() [Static版本]
28 /// - to_long()
29 /// - to_double()
30 /// - to_lower()
31 /// - to_upper()
32 /// - to_lower() [Static版本]
33 /// - to_upper() [Static版本]
34 /// - split() [傳回對應的 std::vector<std::stringex> or std::vector<std::wstringex>]
35 /// -
36 ///<繼承類別列表>
37 /// - Please lookup source code.
38 /// -
39 ///<特殊備註>
40 /// - Author : Awen.Su
41 /// - WebSite : http://awen.cnblogs.com/
42 /// - Copyright: BSD License
43 /// - Please do not remove the copyright information. Thank you !!!
44 /// -
45 ///================================================================================///
46 ///================================================================================///
47
48 ///C/C++ STANDARD INCLUDES
49 #include <string>
50 #include <sstream>
51 #include <vector>
52 #include <typeinfo>
53 #include <cstring>
54 #include <cstdarg>
55 #include <cwchar>
56 #include <cctype>
57 #include <cwctype>
58 #include <algorithm>
59 #include <iterator>
60
61 ///================================================================================///
62 ///================================================================================///
63 namespace std {
64 ///================================================================================///
65 ///================================================================================///
66
67 template <typename _Derived, typename _Elem>
68 class base_stringex_format;
69
70 template <typename _Derived>
71 class base_stringex_format<_Derived, char>
72 {
73 protected:
74 static const int MAX_BUFFER = 8192;
75
76 public:
77 _Derived& format(const char *fmt, )
78 {
79 _Derived *THIS = static_cast<_Derived*>(this);
80
81 char buffer[MAX_BUFFER] = {0};
82 int result = 0;
83
84 va_list args;
85 va_start(args, fmt);
86
87 result = vsnprintf(buffer, MAX_BUFFER - 1, fmt, args);
88
89 va_end(args);
90
91 THIS->assign(buffer, result);
92
93 return(*THIS);
94 }
95 };
96
97 template <typename _Derived>
98 class base_stringex_format<_Derived, wchar_t>
99 {
100 protected:
101 static const int MAX_BUFFER = 8192;
102
103 public:
104 _Derived& format(const wchar_t *fmt, )
105 {
106 /// 格式中的 %s 須改用 %S
107
108 _Derived *THIS = static_cast<_Derived*>(this);
109
110 wchar_t buffer[MAX_BUFFER] = {0};
111 int result= 0;
112
113 va_list args;
114 va_start(args, fmt);
115
116 result = vswprintf(buffer, MAX_BUFFER - 1, fmt, args);
117
118 va_end(args);
119
120 THIS->assign(buffer, result);
121
122 return(*THIS);
123 }
124 };
125
126 ///================================================================================///
127 ///================================================================================///
128
129 template <typename _Derived, typename _Elem>
130 class base_stringex_format_append;
131
132 template <typename _Derived>
133 class base_stringex_format_append<_Derived, char>
134 {
135 protected:
136 static const int MAX_BUFFER = 8192;
137
138 public:
139 _Derived& format_append(const char *fmt, )
140 {
141 _Derived *THIS = static_cast<_Derived*>(this);
142
143 char buffer[MAX_BUFFER] = {0};
144 int result = 0;
145
146 va_list args;
147 va_start(args, fmt);
148
149 result = vsnprintf(buffer, MAX_BUFFER - 1, fmt, args);
150
151 va_end(args);
152
153 THIS->append(buffer, result);
154
155 return(*THIS);
156 }
157 };
158
159 template <typename _Derived>
160 class base_stringex_format_append<_Derived, wchar_t>
161 {
162 protected:
163 static const int MAX_BUFFER = 8192;
164
165 public:
166 _Derived& format_append(const wchar_t *fmt, )
167 {
168 /// 格式中的 %s 須改用 %S
169
170 _Derived *THIS = static_cast<_Derived*>(this);
171
172 wchar_t buffer[MAX_BUFFER] = {0};
173 int result= 0;
174
175 va_list args;
176 va_start(args, fmt);
177
178 result = vswprintf(buffer, MAX_BUFFER - 1, fmt, args);
179
180 va_end(args);
181
182 THIS->append(buffer, result);
183
184 return(*THIS);
185 }
186 };
187
188 ///================================================================================///
189 ///================================================================================///
190
191 template <typename _Derived, typename _Elem>
192 class base_stringex_trim_left;
193
194 template <typename _Derived>
195 class base_stringex_trim_left<_Derived, char>
196 {
197 public:
198 _Derived& trim_left()
199 {
200 _Derived *THIS = static_cast<_Derived*>(this);
201
202 typename _Derived::size_type position = THIS->find_first_not_of(" \t\r\n");
203
204 if(position != std::basic_string<char>::npos)
205 THIS->erase(0, position);
206 else
207 THIS->erase();
208
209 return *THIS;
210 }
211
212 static _Derived trim_left(const _Derived _Source)
213 {
214 return static_cast<_Derived>(_Source).trim_left();
215 }
216 };
217
218 template <typename _Derived>
219 class base_stringex_trim_left<_Derived, wchar_t>
220 {
221 public:
222 _Derived& trim_left()
223 {
224 _Derived *THIS = static_cast<_Derived*>(this);
225
226 typename _Derived::size_type position = THIS->find_first_not_of(L" \t\r\n");
227
228 if(position != std::basic_string<wchar_t>::npos)
229 THIS->erase(0, position);
230 else
231 THIS->erase();
232
233 return(*THIS);
234 }
235
236 static _Derived trim_left(const _Derived _Source)
237 {
238 return static_cast<_Derived>(_Source).trim_left();
239 }
240 };
241
242 ///================================================================================///
243 ///================================================================================///
244
245 template <typename _Derived, typename _Elem>
246 class base_stringex_trim_right;
247
248 template <typename _Derived>
249 class base_stringex_trim_right<_Derived, char>
250 {
251 public:
252 _Derived& trim_right()
253 {
254 _Derived *THIS = static_cast<_Derived*>(this);
255
256 typename _Derived::size_type position = THIS->find_last_not_of(" \t\r\n");
257
258 if(position != std::basic_string<char>::npos)
259 THIS->erase(++position);
260
261 return(*THIS);
262 }
263
264 static _Derived trim_right(const _Derived _Source)
265 {
266 return static_cast<_Derived>(_Source).trim_right();
267 }
268 };
269
270 template <typename _Derived>
271 class base_stringex_trim_right<_Derived, wchar_t>
272 {
273 public:
274 _Derived& trim_right()
275 {
276 _Derived *THIS = static_cast<_Derived*>(this);
277
278 typename _Derived::size_type position = THIS->find_last_not_of(L" \t\r\n");
279
280 if(position != std::basic_string<wchar_t>::npos)
281 THIS->erase(++position);
282
283 return(*THIS);
284 }
285
286 static _Derived trim_right(const _Derived _Source)
287 {
288 return static_cast<_Derived>(_Source).trim_right();
289 }
290 };
291
292 ///================================================================================///
293 ///================================================================================///
294
295 template <typename _Derived, typename _Elem>
296 class base_stringex_trim;
297
298 template <typename _Derived>
299 class base_stringex_trim<_Derived, char>
300 {
301 public:
302 _Derived& trim()
303 {
304 _Derived *THIS = static_cast<_Derived*>(this);
305
306 THIS->trim_left().trim_right();
307
308 return(*THIS);
309 }
310
311 static _Derived trim(const _Derived _Source)
312 {
313 return static_cast<_Derived>(_Source).trim_left().trim_right();
314 }
315 };
316
317 template <typename _Derived>
318 class base_stringex_trim<_Derived, wchar_t>
319 {
320 public:
321 _Derived& trim()
322 {
323 _Derived *THIS = static_cast<_Derived*>(this);
324
325 THIS->trim_left().trim_right();
326
327 return(*THIS);
328 }
329
330 static _Derived trim(const _Derived _Source)
331 {
332 return static_cast<_Derived>(_Source).trim_left().trim_right();
333 }
334 };
335 ///================================================================================///
336 ///================================================================================///
337
338 template <typename _Derived, typename _Elem>
339 class base_stringex_to_integer;
340
341 template <typename _Derived>
342 class base_stringex_to_integer<_Derived, char>
343 {
344 public:
345 long to_long() const
346 {
347 std::stringstream _SS;
348 long _Result;
349
350 _Derived *THIS = static_cast<_Derived*>(this);
351
352 _SS << THIS->c_str();
353 _SS >> _Result;
354 _SS.clear();
355
356 return _Result;
357 }
358
359 double to_double() const
360 {
361 _Derived *THIS = static_cast<_Derived*>(this);
362
363 std::stringstream _SS;
364 double _Result;
365
366 _SS << THIS->c_str();
367 _SS >> _Result;
368 _SS.clear();
369
370 return _Result;
371 }
372 };
373
374 template <typename _Derived>
375 class base_stringex_to_integer<_Derived, wchar_t>
376 {
377 public:
378 long to_long() const
379 {
380 _Derived *THIS = static_cast<_Derived*>(this);
381
382 std::wstringstream _SS;
383 long _Result;
384
385 _SS << THIS->c_str();
386 _SS >> _Result;
387 _SS.clear();
388
389 return _Result;
390 }
391
392 double to_double() const
393 {
394 _Derived *THIS = static_cast<_Derived*>(this);
395
396 std::wstringstream _SS;
397 double _Result;
398
399 _SS << THIS->c_str();
400 _SS >> _Result;
401 _SS.clear();
402
403 return _Result;
404 }
405 };
406
407 ///================================================================================///
408 ///================================================================================///
409
410 template <typename _Derived, typename _Elem>
411 class base_stringex_case_converter;
412
413 template <typename _Derived>
414 class base_stringex_case_converter<_Derived, char>
415 {
416 public:
417 _Derived& to_lower()
418 {
419 _Derived *THIS = static_cast<_Derived*>(this);
420
421 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::tolower);
422
423 return *THIS;
424 }
425
426 _Derived& to_upper()
427 {
428 _Derived *THIS = static_cast<_Derived*>(this);
429
430 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::toupper);
431
432 return *THIS;
433 }
434
435 static _Derived to_lower(const _Derived &_In)
436 {
437 _Derived the_transfer;
438
439 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
440 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::tolower);
441
442 return the_transfer;
443 }
444
445 static _Derived to_upper(const _Derived &_In)
446 {
447 _Derived the_transfer;
448
449 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
450 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::toupper);
451
452 return the_transfer;
453 }
454 };
455
456
457 template <typename _Derived>
458 class base_stringex_case_converter<_Derived, wchar_t>
459 {
460 public:
461 _Derived& to_lower()
462 {
463 _Derived *THIS = static_cast<_Derived*>(this);
464
465 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::towlower);
466
467 return *THIS;
468 }
469
470 _Derived& to_upper()
471 {
472 _Derived *THIS = static_cast<_Derived*>(this);
473
474 std::transform(THIS->begin(), THIS->end(), THIS->begin(), ::towupper);
475
476 return *THIS;
477 }
478
479 static _Derived to_lower(const _Derived &_In)
480 {
481 _Derived the_transfer;
482
483 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
484 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::towlower);
485
486 return the_transfer;
487 }
488
489 static _Derived to_upper(const _Derived &_In)
490 {
491 _Derived the_transfer;
492
493 std::copy(_In.begin(), _In.end(), std::back_inserter(the_transfer));
494 std::transform(the_transfer.begin(), the_transfer.end(), the_transfer.begin(), ::towupper);
495
496 return the_transfer;
497 }
498 };
499
500 ///================================================================================///
501 ///================================================================================///
502 template <typename _Derived, typename _Elem>
503 class base_stringex_split
504 {
505 public:
506 typename typedef std::vector<_Derived> split_type;
507
508 split_type split(const _Derived &_Delimiter) const
509 {
510 _Derived *THIS = static_cast<_Derived*>(this);
511
512 _Derived the_handler = *THIS;
513 split_type the_result;
514 int the_cut_at;
515
516 while((the_cut_at = the_handler.find_first_of(_Delimiter)) != the_handler.npos)
517 {
518 if(the_cut_at > 0)
519 {
520 the_result.push_back(the_handler.substr(0, the_cut_at));
521 }
522
523 the_handler = the_handler.substr(the_cut_at + 1);
524 }
525
526 if(the_handler.length() > 0)
527 the_result.push_back(the_handler);
528
529 return the_result;
530 }
531 };
532
533 ///================================================================================///
534 ///================================================================================///
535 // Class Implemented Here:
536 ///================================================================================///
537 ///================================================================================///
538 template <typename _Elem>
539 class base_stringex_t : public basic_string<_Elem>,
540 public base_stringex_format<base_stringex_t<_Elem>, _Elem>,
541 public base_stringex_format_append<base_stringex_t<_Elem>, _Elem>,
542 public base_stringex_trim_left<base_stringex_t<_Elem>, _Elem>,
543 public base_stringex_trim_right<base_stringex_t<_Elem>, _Elem>,
544 public base_stringex_trim<base_stringex_t<_Elem>, _Elem>,
545 public base_stringex_to_integer<base_stringex_t<_Elem>, _Elem>,
546 public base_stringex_case_converter<base_stringex_t<_Elem>, _Elem>,
547 public base_stringex_split<base_stringex_t<_Elem>, _Elem>
548 {
549 public:
550 typename typedef base_stringex_t<_Elem> impl_type;
551
552 base_stringex_t() : std::basic_string<_Elem>() {}
553 virtual ~base_stringex_t(){}
554
555 base_stringex_t(const base_stringex_t<_Elem> &in) : std::basic_string<_Elem>() { this->assign(in.c_str()); }
556 base_stringex_t(const std::basic_string<_Elem> &in) : std::basic_string<_Elem>() { this->assign(in); }
557 base_stringex_t(const _Elem *in, size_t size) : std::basic_string<_Elem>() { this->assign(in, size); }
558 base_stringex_t(const _Elem *in) : std::basic_string<_Elem>() { this->assign(in); }
559
560 base_stringex_t& operator=(const base_stringex_t<_Elem> &in)
561 {
562 if(this == &in) return(*this);
563 this->assign(in.c_str());
564 return(*this);
565 }
566
567 base_stringex_t& operator=(const std::basic_string<_Elem> &in) { this->assign(in); return(*this); }
568 base_stringex_t& operator=(const _Elem *in) { this->assign(in); return(*this); }
569
570 operator const _Elem*() const { return((*this).c_str()); }
571 };//class base_stringex_t
572
573 typedef base_stringex_t<char> stringex;
574 typedef base_stringex_t<wchar_t> wstringex;
575
576 }//namespace std
577 #endif//HAVE_STD_STRINGEX_H_INCLUDED
578
3. Conclusion
目前此 std::base_stringex_t 已經實作的 function 均為 Awen 在實際專案上經常使用的功能。希望未來能實作更多其他的功能。
4. Reference
[1] CString Management,The Code Project,http://www.codeproject.com/KB/string/cstringmgmt.aspx