- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gstr.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gstr.cpp
19 //
20
21 #include "gdef.h"
22 #include "gstr.h"
23 #include "gdebug.h"
24 #include <cmath>
25 #include <algorithm>
26 #include <functional>
27 #include <ctype.h>
28 #include <iomanip>
29 #include <climits>
30 #include <string>
31 #include <sstream>
32
33 std::string G::Str::escaped( const std::string & s_in , const std::string & specials , char c_escape )
34 {
35 std::string s( s_in ) ;
36 escape( s , specials , c_escape ) ;
37 return s ;
38 }
39
40 void G::Str::escape( std::string & s , const std::string & specials , char c_escape )
41 {
42 size_type pos = 0U ;
43 for(;;)
44 {
45 pos = s.find_first_of( specials , pos ) ;
46 if( pos == std::string::npos )
47 break ;
48
49 s.insert( pos , 1U , c_escape ) ;
50 pos++ ;
51 pos++ ;
52 }
53 }
54
55 bool G::Str::replace( std::string & s , const std::string & from , const std::string & to , size_type * pos_p )
56 {
57 if( from.length() == 0 )
58 return false ;
59
60 size_type pos = pos_p == NULL ? 0 : *pos_p ;
61 if( pos >= s.length() )
62 return false ;
63
64 pos = s.find( from , pos ) ;
65 if( pos == std::string::npos )
66 {
67 return false ;
68 }
69 else
70 {
71 s.replace( pos , from.length() , to ) ;
72 if( pos_p != NULL )
73 *pos_p = pos + to.length() ;
74 return true ;
75 }
76 }
77
78 unsigned int G::Str::replaceAll( std::string & s , const std::string & from , const std::string & to )
79 {
80 unsigned int count = 0U ;
81 for( size_type pos = 0U ; replace(s,from,to,&pos) ; count++ )
82 ; // no-op
83 return count ;
84 }
85
86 unsigned int G::Str::replaceAll( std::string & s , const char * from , const char * to )
87 {
88 // this char* overload is an optimisation to avoid constructing
89 // temporaries when starting with a c-string -- we only construct
90 // std-strings if there is work to do
91
92 if( s.find(from) != std::string::npos )
93 {
94 unsigned int count = 0U ;
95 for( size_type pos = 0U ; replace(s,from,to,&pos) ; count++ )
96 ; // no-op
97 return count ;
98 }
99 else
100 {
101 return 0U ;
102 }
103 }
104
105 void G::Str::removeAll( std::string & s , char c )
106 {
107 const std::string::iterator end = s.end() ;
108 s.erase( std::remove_if( s.begin() , end , std::bind1st(std::equal_to<char>(),c) ) , end ) ;
109 }
110
111 void G::Str::trimLeft( std::string & s , const std::string & ws , size_type limit )
112 {
113 size_type n = s.find_first_not_of( ws ) ;
114 if( limit != 0U && ( n == std::string::npos || n > limit ) )
115 n = limit >= s.length() ? std::string::npos : limit ;
116 if( n == std::string::npos )
117 s = std::string() ;
118 else if( n != 0U )
119 s.erase( 0U , n ) ;
120 }
121
122 void G::Str::trimRight( std::string & s , const std::string & ws , size_type limit )
123 {
124 size_type n = s.find_last_not_of( ws ) ;
125 if( limit != 0U && ( n == std::string::npos || s.length() > (limit+n+1U) ) )
126 n = limit >= s.length() ? std::string::npos : (s.length()-limit-1U) ;
127 if( n == std::string::npos )
128 s = std::string() ;
129 else if( n != 0U )
130 s.resize( n+1U ) ;
131 }
132
133 void G::Str::trim( std::string & s , const std::string & ws )
134 {
135 trimLeft(s,ws) ; trimRight(s,ws) ;
136 }
137
138 std::string G::Str::trimmed( const std::string & s_in , const std::string & ws )
139 {
140 std::string s( s_in ) ;
141 trim( s , ws ) ;
142 return s ;
143 }
144
145 namespace
146 {
147 struct IsDigit : std::unary_function<char,bool>
148 {
149 bool operator()( char c ) const { return !! isdigit( c ) ; }
150 } ;
151 }
152 bool G::Str::isNumeric( const std::string & s , bool allow_minus_sign )
153 {
154 const std::string::const_iterator end = s.end() ;
155 std::string::const_iterator p = s.begin() ;
156 if( allow_minus_sign && p != end && *p == '-' ) ++p ;
157 return std::find_if( p , end , std::not1(IsDigit()) ) == end ;
158 }
159
160 namespace
161 {
162 struct IsPrintableAscii : std::unary_function<char,bool>
163 {
164 bool operator()( char c ) const { return c >= 0x20 && c < 0x7f ; }
165 } ;
166 }
167 bool G::Str::isPrintableAscii( const std::string & s )
168 {
169 const std::string::const_iterator end = s.end() ;
170 return std::find_if( s.begin() , end , std::not1(IsPrintableAscii()) ) == end ;
171 }
172
173 bool G::Str::isUShort( const std::string & s )
174 {
175 try
176 {
177 G_IGNORE_RETURN(unsigned short) toUShort(s) ;
178 }
179 catch( Overflow & )
180 {
181 return false ;
182 }
183 catch( InvalidFormat & )
184 {
185 return false ;
186 }
187 return true ;
188 }
189
190 bool G::Str::isUInt( const std::string & s )
191 {
192 try
193 {
194 G_IGNORE_RETURN(unsigned int) toUInt(s) ;
195 }
196 catch( Overflow & )
197 {
198 return false ;
199 }
200 catch( InvalidFormat & )
201 {
202 return false ;
203 }
204 return true ;
205 }
206
207 bool G::Str::isULong( const std::string & s )
208 {
209 try
210 {
211 G_IGNORE_RETURN(unsigned long) toULong(s) ;
212 }
213 catch( Overflow & )
214 {
215 return false ;
216 }
217 catch( InvalidFormat & )
218 {
219 return false ;
220 }
221 return true ;
222 }
223
224 std::string G::Str::fromBool( bool b )
225 {
226 return b ? "true" : "false" ;
227 }
228
229 std::string G::Str::fromDouble( double d )
230 {
231 std::ostringstream ss ;
232 ss << std::setprecision(16) << d ; // was "setprecision(DBL_DIG+1)
233 return ss.str() ;
234 }
235
236 std::string G::Str::fromInt( int i )
237 {
238 std::ostringstream ss ;
239 ss << i ;
240 return ss.str() ;
241 }
242
243 std::string G::Str::fromLong( long l )
244 {
245 std::ostringstream ss ;
246 ss << l ;
247 return ss.str() ;
248 }
249
250 std::string G::Str::fromShort( short s )
251 {
252 std::ostringstream ss ;
253 ss << s ;
254 return ss.str() ;
255 }
256
257 std::string G::Str::fromUInt( unsigned int ui )
258 {
259 std::ostringstream ss ;
260 ss << ui ;
261 return ss.str() ;
262 }
263
264 std::string G::Str::fromULong( unsigned long ul )
265 {
266 std::ostringstream ss ;
267 ss << ul ;
268 return ss.str() ;
269 }
270
271 std::string G::Str::fromUShort( unsigned short us )
272 {
273 std::ostringstream ss ;
274 ss << us ;
275 return ss.str() ;
276 }
277
278 bool G::Str::toBool( const std::string & s )
279 {
280 std::string str = lower( s ) ;
281 if( str == "true" )
282 {
283 return true ;
284 }
285 else if( str == "false" )
286 {
287 return false ;
288 }
289 else
290 {
291 throw InvalidFormat( s ) ;
292 return false ; // never gets here -- the return pacifies some compilers
293 }
294 }
295
296 double G::Str::toDouble( const std::string &s )
297 {
298 char * end = NULL ;
299 double result = ::strtod( s.c_str(), &end ) ;
300
301 if( end == 0 || end[0] != '\0' )
302 throw InvalidFormat( s ) ;
303
304 if( result == HUGE_VAL || result == -(HUGE_VAL) )
305 throw Overflow( s ) ;
306
307 return result ;
308 }
309
310 int G::Str::toInt( const std::string &s )
311 {
312 long long_val = toLong( s ) ;
313 int int_val = static_cast<int>( long_val ) ;
314
315 if( int_val != long_val )
316 throw Overflow( s ) ;
317
318 return int_val ;
319 }
320
321 long G::Str::toLong( const std::string &s )
322 {
323 char * end = NULL ;
324 long result = ::strtol( s.c_str(), &end, 0 ) ;
325
326 if( end == 0 || end[0] != '\0' )
327 throw InvalidFormat( s ) ;
328
329 if( result == LONG_MAX || result == LONG_MIN )
330 throw Overflow( s ) ;
331
332 return result ;
333 }
334
335 short G::Str::toShort( const std::string &s )
336 {
337 long long_val = toLong( s ) ;
338 short short_val = static_cast<short>( long_val ) ;
339
340 if( short_val != long_val )
341 throw Overflow( s ) ;
342
343 return short_val ;
344 }
345
346 unsigned int G::Str::toUInt( const std::string &s , bool limited )
347 {
348 unsigned long ulong_val = toULong( s ) ;
349 unsigned int uint_val = static_cast<unsigned int>( ulong_val ) ;
350
351 if( uint_val != ulong_val )
352 {
353 if( limited )
354 uint_val = UINT_MAX ;
355 else
356 throw Overflow( s ) ;
357 }
358
359 return uint_val ;
360 }
361
362 unsigned long G::Str::toULong( const std::string &s , bool limited )
363 {
364 char * end = NULL ;
365 unsigned long result = ::strtoul( s.c_str() , &end , 10 ) ;
366
367 if( end == 0 || end[0] != '\0' )
368 throw InvalidFormat( s ) ;
369
370 if( result == ULONG_MAX )
371 {
372 if( limited )
373 result = ULONG_MAX ;
374 else
375 throw Overflow( s ) ;
376 }
377
378 return result ;
379 }
380
381 unsigned short G::Str::toUShort( const std::string &s , bool limited )
382 {
383 unsigned long ulong_val = toULong( s ) ;
384 unsigned short ushort_val = static_cast<unsigned short>( ulong_val ) ;
385
386 if( ushort_val != ulong_val )
387 {
388 if( limited )
389 ushort_val = USHRT_MAX ;
390 else
391 throw Overflow( s ) ;
392 }
393
394 return ushort_val ;
395 }
396
397 namespace
398 {
399 struct ToLower : std::unary_function<char,char>
400 {
401 char operator()( char c ) { return static_cast<char>( tolower(c) ) ; }
402 } ;
403 }
404 void G::Str::toLower( std::string & s )
405 {
406 std::transform( s.begin() , s.end() , s.begin() , ToLower() ) ;
407 }
408 std::string G::Str::lower( const std::string & in )
409 {
410 std::string out = in ;
411 toLower( out ) ;
412 return out ;
413 }
414
415 namespace
416 {
417 struct ToUpper : std::unary_function<char,char>
418 {
419 char operator()( char c ) { return static_cast<char>( toupper(c) ) ; }
420 } ;
421 }
422 void G::Str::toUpper( std::string & s )
423 {
424 std::transform( s.begin() , s.end() , s.begin() , ToUpper() ) ;
425 }
426 std::string G::Str::upper( const std::string & in )
427 {
428 std::string out = in ;
429 toUpper( out ) ;
430 return out ;
431 }
432
433 namespace
434 {
435 template <typename Tchar = char , typename Tuchar = unsigned char>
436 struct PrintableAppender : std::unary_function<Tchar,void>
437 {
438 std::string & s ;
439 Tchar escape_in ;
440 char escape_out ;
441 bool eight_bit ;
442 PrintableAppender( std::string & s_ , Tchar escape_ , bool eight_bit_ ) :
443 s(s_) ,
444 escape_in(escape_) ,
445 escape_out(static_cast<char>(escape_)) ,
446 eight_bit(eight_bit_)
447 {
448 }
449 void operator()( Tchar c )
450 {
451 const Tuchar uc = static_cast<Tuchar>(c) ;
452 if( c == escape_in )
453 {
454 s.append( 2U , escape_out ) ;
455 }
456 else if( !eight_bit && uc >= 0x20U && uc < 0x7FU && uc != 0xFFU )
457 {
458 s.append( 1U , static_cast<char>(c) ) ;
459 }
460 else if( eight_bit && ( ( uc >= 0x20U && uc < 0x7FU ) || uc >= 0xA0 ) && uc != 0xFFU )
461 {
462 s.append( 1U , static_cast<char>(c) ) ;
463 }
464 else
465 {
466 s.append( 1U , escape_out ) ;
467 if( static_cast<char>(c) == '\n' )
468 {
469 s.append( 1U , 'n' ) ;
470 }
471 else if( static_cast<char>(c) == '\r' )
472 {
473 s.append( 1U , 'r' ) ;
474 }
475 else if( static_cast<char>(c) == '\t' )
476 {
477 s.append( 1U , 't' ) ;
478 }
479 else if( c == 0 )
480 {
481 s.append( 1U , '0' ) ;
482 }
483 else
484 {
485 s.append( 1U , 'x' ) ;
486 const char * const map = "0123456789abcdef" ;
487 unsigned long n = uc ;
488 if( sizeof(Tchar) == 1 )
489 {
490 n &= 0xFFUL ;
491 s.append( 1U , map[(n/16UL)%16UL] ) ;
492 s.append( 1U , map[n%16UL] ) ;
493 }
494 else
495 {
496 n &= 0xFFFFUL ;
497 s.append( 1U , map[(n/4096UL)%16UL] ) ;
498 s.append( 1U , map[(n/256UL)%16UL] ) ;
499 s.append( 1U , map[(n/16UL)%16UL] ) ;
500 s.append( 1U , map[n%16UL] ) ;
501 }
502 }
503 }
504 }
505 } ;
506 }
507 std::string G::Str::printable( const std::string & in , char escape )
508 {
509 std::string result ;
510 result.reserve( in.length() + 1U ) ;
511 std::for_each( in.begin() , in.end() , PrintableAppender<char,unsigned char>(result,escape,true) ) ;
512 return result ;
513 }
514 std::string G::Str::toPrintableAscii( const std::string & in , char escape )
515 {
516 std::string result ;
517 result.reserve( in.length() + 1U ) ;
518 std::for_each( in.begin() , in.end() , PrintableAppender<char,unsigned char>(result,escape,false) ) ;
519 return result ;
520 }
521 std::string G::Str::toPrintableAscii( char c , char escape )
522 {
523 std::string result ;
524 PrintableAppender<char,unsigned char> append_printable( result , escape , false ) ;
525 append_printable( c ) ;
526 return result ;
527 }
528 std::string G::Str::toPrintableAscii( const std::wstring & in , wchar_t escape )
529 {
530 std::string result ;
531 result.reserve( in.length() * 3U ) ;
532 std::for_each( in.begin() , in.end() , PrintableAppender<wchar_t,unsigned long>(result,escape,false) ) ;
533 return result ;
534 }
535
536 std::string G::Str::readLineFrom( std::istream & stream , const std::string & eol )
537 {
538 std::string result ;
539 readLineFrom( stream , eol.empty() ? std::string(1U,'\n') : eol , result , true ) ;
540 return result ;
541 }
542
543 void G::Str::readLineFrom( std::istream & stream , const std::string & eol , std::string & line , bool pre_erase )
544 {
545 G_ASSERT( eol.length() != 0U ) ;
546
547 if( pre_erase )
548 line.erase() ;
549
550 // this is a special speed optimisation for a two-character terminator with a one-character initial string ;-)
551 if( eol.length() == 2U && eol[0] != eol[1] && line.length() == 1U )
552 {
553 // Save the initial character, use std::getline() for speed (terminating
554 // on the second character of the two-character terminator), check that the
555 // one-character terminator was actually part of the required two-character
556 // terminator, remove the first character of the two-character terminator,
557 // and finally re-insert the initial character.
558 //
559 const char c = line[0] ;
560 line.erase() ; // since getline() doesnt erase it if already at eof
561 std::getline( stream , line , eol[1] ) ; // fast
562 const std::string::size_type line_length = line.length() ;
563 bool complete = line_length > 0U && line[line_length-1U] == eol[0] ;
564 if( complete )
565 {
566 line.resize( line_length - 1U ) ;
567 line.insert( 0U , &c , 1U ) ;
568 }
569 else
570 {
571 line.insert( 0U , &c , 1U ) ;
572 if( stream.good() )
573 {
574 line.append( 1U , eol[1] ) ;
575 readLineFromImp( stream , eol , line ) ;
576 }
577 }
578 }
579 else
580 {
581 readLineFromImp( stream , eol , line ) ;
582 }
583 }
584
585 void G::Str::readLineFromImp( std::istream & stream , const std::string & eol , std::string & line )
586 {
587 const size_type limit = line.max_size() ;
588 const size_type eol_length = eol.length() ;
589 const char eol_final = eol.at( eol_length - 1U ) ;
590 size_type line_length = line.length() ;
591
592 bool changed = false ;
593 char c ;
594 for(;;)
595 {
596 stream.get( c ) ; // sets the fail bit at eof
597 if( stream.fail() )
598 {
599 // work more like std::getline() in <string> -- reset the failbit and set eof
600 // (remember that clear() sets all the flags explicitly to the given values)
601 stream.clear( ( stream.rdstate() & ~std::ios_base::failbit ) | std::ios_base::eofbit ) ;
602 break ;
603 }
604
605 if( line_length == limit ) // pathological case -- see also std::getline()
606 {
607 stream.setstate( std::ios_base::failbit ) ;
608 break ;
609 }
610
611 line.append( 1U , c ) ; // fast enough if 'line' has sufficient capacity
612 changed = true ;
613 ++line_length ;
614
615 if( line_length >= eol_length && c == eol_final ) // optimisation
616 {
617 const size_type offset = line_length - eol_length ;
618 if( line.find(eol,offset) == offset )
619 {
620 line.erase(offset) ;
621 break ;
622 }
623 }
624 }
625 if( !changed )
626 {
627 // set the failbit
628 // (remember that setstate() sets the flag(s) identified by the given bitmask to 1)
629 stream.setstate( std::ios_base::failbit ) ;
630 }
631 }
632
633 std::string G::Str::wrap( std::string text , const std::string & prefix_1 ,
634 const std::string & prefix_2 , size_type width )
635 {
636 std::string ws( " \t\n" ) ;
637 std::ostringstream ss ;
638 for( bool first_line = true ; text.length() ; first_line = false )
639 {
640 const size_type prefix_length =
641 first_line ? prefix_1.length() : prefix_2.length() ;
642 size_type w = (width > prefix_length) ? (width-prefix_length) : width ;
643
644 const size_type pos_nl = text.find_first_of("\n") ;
645 if( pos_nl != std::string::npos && pos_nl != 0U && pos_nl < w )
646 {
647 w = pos_nl ;
648 }
649
650 std::string line = text ;
651 if( text.length() > w ) // (should use wcwidth() for utf-8 compatibility)
652 {
653 line = text.substr( 0U , w ) ;
654 if( text.find_first_of(ws,w) != w )
655 {
656 const size_type white_space = line.find_last_of( ws ) ;
657 const size_type black_space = line.find_first_not_of( ws ) ;
658 if( white_space != std::string::npos &&
659 black_space != std::string::npos &&
660 (white_space+1U) != black_space )
661 {
662 line = line.substr( 0U , white_space ) ;
663 }
664 }
665 }
666
667 if( line.length() != 0U )
668 {
669 ss << ( first_line ? prefix_1 : prefix_2 ) << line << std::endl ;
670 }
671
672 text = text.length() == line.length() ?
673 std::string() : text.substr(line.length()) ;
674
675 const size_type black_space = text.find_first_not_of( ws ) ;
676 if( black_space != 0U && black_space != std::string::npos )
677 {
678 unsigned int newlines = 0U ;
679 for( size_type pos = 0U ; pos < black_space ; ++pos )
680 {
681 if( text.at(pos) == '\n' )
682 {
683 newlines++ ;
684 if( newlines > 1U )
685 ss << prefix_2 << std::endl ;
686 }
687 }
688
689 text = text.substr( black_space ) ;
690 }
691 }
692 return ss.str() ;
693 }
694
695 namespace
696 {
697 template <typename T>
698 void splitIntoTokens_( const std::string & in , T & out , const std::string & ws )
699 {
700 typedef G::Str::size_type size_type ;
701 for( size_type p = 0U ; p != std::string::npos ; )
702 {
703 p = in.find_first_not_of( ws , p ) ;
704 if( p != std::string::npos )
705 {
706 size_type end = in.find_first_of( ws , p ) ;
707 size_type len = end == std::string::npos ? end : (end-p) ;
708 out.push_back( in.substr(p,len) ) ;
709 p = end ;
710 }
711 }
712 }
713 }
714 void G::Str::splitIntoTokens( const std::string & in , Strings & out , const std::string & ws )
715 {
716 splitIntoTokens_( in , out , ws ) ;
717 }
718 void G::Str::splitIntoTokens( const std::string & in , StringArray & out , const std::string & ws )
719 {
720 splitIntoTokens_( in , out , ws ) ;
721 }
722
723 namespace
724 {
725 template <typename T>
726 void splitIntoFields_( const std::string & in_in , T & out , const std::string & ws ,
727 char escape , bool discard_bogus )
728 {
729 typedef G::Str::size_type size_type ;
730 std::string all( ws ) ;
731 if( escape != '\0' )
732 all.append( 1U , escape ) ;
733
734 if( in_in.length() )
735 {
736 std::string in = in_in ;
737 size_type start = 0U ;
738 size_type last_pos = in.length() - 1U ;
739 size_type pos = 0U ;
740 for(;;)
741 {
742 if( pos >= in.length() ) break ;
743 pos = in.find_first_of( all , pos ) ;
744 if( pos == std::string::npos ) break ;
745 if( in.at(pos) == escape )
746 {
747 const bool valid = pos != last_pos && in.find(all,pos+1U) == (pos+1U) ;
748 if( valid || discard_bogus )
749 in.erase( pos , 1U ) ;
750 else
751 pos++ ;
752 pos++ ;
753 }
754 else
755 {
756 out.push_back( in.substr(start,pos-start) ) ;
757 pos++ ;
758 start = pos ;
759 }
760 }
761 out.push_back( in.substr(start,pos-start) ) ;
762 }
763 }
764 }
765 void G::Str::splitIntoFields( const std::string & in , Strings & out , const std::string & ws ,
766 char escape , bool discard_bogus )
767 {
768 splitIntoFields_( in , out , ws , escape , discard_bogus ) ;
769 }
770 void G::Str::splitIntoFields( const std::string & in , StringArray & out , const std::string & ws ,
771 char escape , bool discard_bogus )
772 {
773 splitIntoFields_( in , out , ws , escape , discard_bogus ) ;
774 }
775
776 namespace
777 {
778 template <typename T>
779 struct Joiner : std::unary_function<const T&,void>
780 {
781 T & result ;
782 const T & sep ;
783 bool & first ;
784 Joiner( T & result_ , const T & sep_ , bool & first_ ) :
785 result(result_) ,
786 sep(sep_) ,
787 first(first_)
788 {
789 first = true ;
790 }
791 void operator()( const T & s )
792 {
793 if( !first ) result.append( sep ) ;
794 result.append( s ) ;
795 first = false ;
796 }
797 } ;
798 }
799 std::string G::Str::join( const Strings & strings , const std::string & sep )
800 {
801 std::string result ;
802 bool first = true ;
803 std::for_each( strings.begin() , strings.end() , Joiner<std::string>(result,sep,first) ) ;
804 return result ;
805 }
806 std::string G::Str::join( const StringArray & strings , const std::string & sep )
807 {
808 std::string result ;
809 bool first = true ;
810 std::for_each( strings.begin() , strings.end() , Joiner<std::string>(result,sep,first) ) ;
811 return result ;
812 }
813
814 namespace
815 {
816 template <typename T>
817 struct Firster : std::unary_function<const T&,const typename T::first_type&>
818 {
819 const typename T::first_type & operator()( const T & pair ) { return pair.first ; }
820 } ;
821 }
822 G::Strings G::Str::keys( const StringMap & map )
823 {
824 Strings result ;
825 std::transform( map.begin() , map.end() , std::back_inserter(result) , Firster<StringMap::value_type>() ) ;
826 return result ;
827 }
828
829 std::string G::Str::ws()
830 {
831 return std::string(" \t\n\r") ;
832 }
833
834 std::string G::Str::head( const std::string & in , std::string::size_type pos , const std::string & default_ )
835 {
836 return
837 pos == std::string::npos ?
838 default_ :
839 ( pos == 0U ? std::string() : ( (pos+1U) >= in.length() ? in : in.substr(0U,pos) ) ) ;
840 }
841
842 std::string G::Str::tail( const std::string & in , std::string::size_type pos , const std::string & default_ )
843 {
844 return
845 pos == std::string::npos ?
846 default_ :
847 ( (pos+1U) >= in.length() ? std::string() : in.substr(pos+1U) ) ;
848 }
849
850 bool G::Str::tailMatch( const std::string & in , const std::string & ending )
851 {
852 return
853 ending.empty() ||
854 ( in.length() >= ending.length() &&
855 in.substr( in.length() - ending.length() ) == ending ) ;
856 // 0 == in.compare( in.length() - ending.length() , ending.length() , ending ) // faster, but not gcc2.95
857 }
858
G::Str::fromBool
static std::string fromBool(bool b)
Converts boolean 'b' to a string.
Definition: gstr.cpp:224
G::Str::size_type
std::string::size_type size_type
Definition: gstr.h:45
G::Str::printable
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:507
G::Str::toBool
static bool toBool(const std::string &s)
Converts string 's' to a bool.
Definition: gstr.cpp:278
G::Str::toUInt
static unsigned int toUInt(const std::string &s, bool limited=false)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:346
G::Str::toInt
static int toInt(const std::string &s)
Converts string 's' to an int.
Definition: gstr.cpp:310
G::Strings
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
G::Str::wrap
static std::string wrap(std::string text, const std::string &prefix_first_line, const std::string &prefix_subsequent_lines, size_type width=70U)
Does word-wrapping.
Definition: gstr.cpp:633
G::Str::tailMatch
static bool tailMatch(const std::string &in, const std::string &ending)
Returns true if the given string has the given ending.
Definition: gstr.cpp:850
G::Str::splitIntoFields
static void splitIntoFields(const std::string &in, Strings &out, const std::string &seperators, char escape= '\0', bool discard_bogus_escapes=true)
Splits the string into fields.
Definition: gstr.cpp:765
G::Str::escape
static void escape(std::string &, const std::string &specials, char escape= '\\')
Prefixes each occurrence of one of the special characters with the escape character.
Definition: gstr.cpp:40
G::Str::fromDouble
static std::string fromDouble(double d)
Converts double 'd' to a string.
Definition: gstr.cpp:229
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:44
md5::size_type
std::string::size_type size_type
A std::size_t type.
Definition: md5.h:43
G::Str::splitIntoTokens
static void splitIntoTokens(const std::string &in, Strings &out, const std::string &ws)
Splits the string into 'ws'-delimited tokens.
Definition: gstr.cpp:714
G::Str::toShort
static short toShort(const std::string &s)
Converts string 's' to a short.
Definition: gstr.cpp:335
G::Str::isNumeric
static bool isNumeric(const std::string &s, bool allow_minus_sign=false)
Returns true if every character is a decimal digit.
Definition: gstr.cpp:152
G::Str::fromInt
static std::string fromInt(int i)
Converts int 'i' to a string.
Definition: gstr.cpp:236
G::Str::tail
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:842
G::Str::trim
static void trim(std::string &s, const std::string &ws)
Trims both ends of s, taking off any of the 'ws' characters.
Definition: gstr.cpp:133
G::Str::trimLeft
static void trimLeft(std::string &s, const std::string &ws, size_type limit=0U)
Trims the lhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:111
G::Str::fromLong
static std::string fromLong(long l)
Converts long 'l' to a string.
Definition: gstr.cpp:243
G::Str::lower
static std::string lower(const std::string &s)
Returns a copy of 's' in which all uppercase characters have been replaced by lowercase characters...
Definition: gstr.cpp:408
G::Str::toLower
static void toLower(std::string &s)
Replaces all uppercase characters in string 's' by lowercase characters.
Definition: gstr.cpp:404
G::Str::keys
static Strings keys(const StringMap &string_map)
Extracts the keys from a map of strings.
Definition: gstr.cpp:822
G_ASSERT
#define G_ASSERT(test)
Definition: gassert.h:30
G::Str::fromUInt
static std::string fromUInt(unsigned int ui)
Converts unsigned int 'ui' to a string.
Definition: gstr.cpp:257
gstr.h
G::Str::replace
static bool replace(std::string &s, const std::string &from, const std::string &to, size_type *pos_p=NULL)
Replaces 'from' with 'to', starting at offset '*pos_p'.
Definition: gstr.cpp:55
G::Str::replaceAll
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurences of sub-string 'from' with 'to'...
Definition: gstr.cpp:78
G::Str::head
static std::string head(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:834
G::Str::trimRight
static void trimRight(std::string &s, const std::string &ws, size_type limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:122
G::Str::toDouble
static double toDouble(const std::string &s)
Converts string 's' to a double.
Definition: gstr.cpp:296
G::Str::fromShort
static std::string fromShort(short s)
Converts short 's' to a string.
Definition: gstr.cpp:250
G::Str::isUShort
static bool isUShort(const std::string &s)
Returns true if the string can be converted into an unsigned short without throwing an exception...
Definition: gstr.cpp:173
G::Str::upper
static std::string upper(const std::string &s)
Returns a copy of 's' in which all lowercase characters have been replaced by uppercase characters...
Definition: gstr.cpp:426
G::Str::fromUShort
static std::string fromUShort(unsigned short us)
Converts unsigned short 'us' to a string.
Definition: gstr.cpp:271
G::Str::escaped
static std::string escaped(const std::string &, const std::string &specials, char escape= '\\')
Prefixes each occurrence of one of the special characters with the escape character.
Definition: gstr.cpp:33
G::Str::trimmed
static std::string trimmed(const std::string &s, const std::string &ws)
Returns a trim()med version of s.
Definition: gstr.cpp:138
G::Str::readLineFrom
static std::string readLineFrom(std::istream &stream, const std::string &eol=std::string())
Reads a line from the stream using the given line terminator.
Definition: gstr.cpp:536
G::Str::isPrintableAscii
static bool isPrintableAscii(const std::string &s)
Returns true if every character is a 7-bit, non-control character (ie.
Definition: gstr.cpp:167
G::StringMap
std::map< std::string, std::string > StringMap
A std::map of std::strings.
Definition: gstrings.h:49
G::Str::toLong
static long toLong(const std::string &s)
Converts string 's' to a long.
Definition: gstr.cpp:321
G::Str::toUShort
static unsigned short toUShort(const std::string &s, bool limited=false)
Converts string 's' to an unsigned short.
Definition: gstr.cpp:381
G::Str::toULong
static unsigned long toULong(const std::string &s, bool limited=false)
Converts string 's' to an unsigned long.
Definition: gstr.cpp:362
G::Str::isUInt
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
Definition: gstr.cpp:190
G::Str::removeAll
static void removeAll(std::string &, char)
Removes all occurrences of the character from the string.
Definition: gstr.cpp:105
G::Str::isULong
static bool isULong(const std::string &s)
Returns true if the string can be converted into an unsigned long without throwing an exception...
Definition: gstr.cpp:207
G::Str::fromULong
static std::string fromULong(unsigned long ul)
Converts unsigned long 'ul' to a string.
Definition: gstr.cpp:264
G::Str::join
static std::string join(const Strings &strings, const std::string &sep)
Concatenates a set of strings.
Definition: gstr.cpp:799
G::Str::ws
static std::string ws()
A convenience function returning standard whitespace characters.
Definition: gstr.cpp:829
G::Str::toPrintableAscii
static std::string toPrintableAscii(char c, char escape= '\\')
Returns a 7-bit printable representation of the given input character.
Definition: gstr.cpp:521
gdebug.h
G::Str::toUpper
static void toUpper(std::string &s)
Replaces all lowercase characters in string 's' by uppercase characters.
Definition: gstr.cpp:422