Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Fstring.cc
Go to the documentation of this file.
1 // Fstring: Fixed-Length Fortran-Compatible String and Substring
2 //
3 // Project: Objexx Fortran Compatibility Library (ObjexxFCL)
4 //
5 // Version: 3.0.0
6 //
7 // Language: C++
8 //
9 // Copyright (c) 2000-2009 Objexx Engineering, Inc. All Rights Reserved.
10 // Use of this source code or any derivative of it is restricted by license.
11 // Licensing is available from Objexx Engineering, Inc.: http://objexx.com Objexx@objexx.com
12 
13 
14 // ObjexxFCL Headers
15 #include <ObjexxFCL/Fstring.hh>
17 
18 // C++ Headers
19 #include <algorithm>
20 //#include <iostream>
21 
22 
23 namespace ObjexxFCL {
24 
25 
26 // Constants
27 char const SPACE( ' ' );
28 char const TAB( '\t' );
29 char const NULLC( '\000' );
30 std::string const WHITESPACE( " \t\0", 3 );
31 
32 
33 // Fstring
34 
35 
36  /// @brief Copy Constructor
37  Fstring::Fstring( Fstring const & s ) :
38  len_( s.len_ ),
39  str_( len_ > 0 ? new char[ len_ ] : 0 ),
40  c_str_( 0 ),
41  sub_( false )
42  {
43  std::memcpy( str_, s.str_, len_ );
44  }
45 
46 
47  /// @brief string Constructor
48  Fstring::Fstring( std::string const & s ) :
49  len_( s.length() ),
50  str_( len_ > 0 ? new char[ len_ ] : 0 ),
51  c_str_( 0 ),
52  sub_( false )
53  {
54  s.copy( str_, len_ );
55  }
56 
57 
58  /// @brief cstring Constructor
60  len_( std::strlen( s ) ),
61  str_( len_ > 0 ? new char[ len_ ] : 0 ),
62  c_str_( 0 ),
63  sub_( false )
64  {
65  std::memcpy( str_, s, len_ );
66  }
67 
68 
69  /// @brief Length Constructor
70  Fstring::Fstring( short int const len_a ) :
71  len_( static_cast< size_type >( std::max( static_cast< int >( len_a ), 0 ) ) ),
72  str_( len_ > 0 ? new char[ len_ ] : 0 ),
73  c_str_( 0 ),
74  sub_( false )
75  {
76  std::memset( str_, SPACE, len_ );
77  }
78 
79 
80  /// @brief Length Constructor
81  Fstring::Fstring( int const len_a ) :
82  len_( static_cast< size_type >( std::max( len_a, 0 ) ) ),
83  str_( len_ > 0 ? new char[ len_ ] : 0 ),
84  c_str_( 0 ),
85  sub_( false )
86  {
87  std::memset( str_, SPACE, len_ );
88  }
89 
90 
91  /// @brief Length Constructor
92  Fstring::Fstring( long int const len_a ) :
93  len_( static_cast< size_type >( std::max( len_a, 0l ) ) ),
94  str_( len_ > 0 ? new char[ len_ ] : 0 ),
95  c_str_( 0 ),
96  sub_( false )
97  {
98  std::memset( str_, SPACE, len_ );
99  }
100 
101 
102  /// @brief Length Constructor
103  Fstring::Fstring( unsigned short int const len_a ) :
104  len_( static_cast< size_type >( len_a ) ),
105  str_( len_ > 0 ? new char[ len_ ] : 0 ),
106  c_str_( 0 ),
107  sub_( false )
108  {
109  std::memset( str_, SPACE, len_ );
110  }
111 
112 
113  /// @brief Length Constructor
114  Fstring::Fstring( unsigned int const len_a ) :
115  len_( static_cast< size_type >( len_a ) ),
116  str_( len_ > 0 ? new char[ len_ ] : 0 ),
117  c_str_( 0 ),
118  sub_( false )
119  {
120  std::memset( str_, SPACE, len_ );
121  }
122 
123 
124  /// @brief Length Constructor
125  Fstring::Fstring( unsigned long int const len_a ) :
126  len_( static_cast< size_type >( len_a ) ),
127  str_( len_ > 0 ? new char[ len_ ] : 0 ),
128  c_str_( 0 ),
129  sub_( false )
130  {
131  std::memset( str_, SPACE, len_ );
132  }
133 
134  Fstring::Fstring( unsigned long long const len_a ) :
135  len_( static_cast< size_type >( len_a ) ),
136  str_( len_ > 0 ? new char[ len_ ] : 0 ),
137  c_str_( 0 ),
138  sub_( false )
139  {
140  std::memset( str_, SPACE, len_ );
141  }
142 
143  /// @brief Length + Fstring Constructor
144  Fstring::Fstring( size_type const len_a, Fstring const & s ) :
145  len_( len_a ),
146  str_( len_ > 0 ? new char[ len_ ] : 0 ),
147  c_str_( 0 ),
148  sub_( false )
149  {
150  if ( len_ > s.len_ ) {
151  if ( s.len_ > 0 ) std::memcpy( str_, s.str_, s.len_ );
152  std::memset( str_ + s.len_, SPACE, len_ - s.len_ ); // Space pad
153  } else if ( len_ > 0 ) {
154  std::memcpy( str_, s.str_, len_ );
155  }
156  }
157 
158 
159  /// @brief Length + string Constructor
160  Fstring::Fstring( size_type const len_a, std::string const & s ) :
161  len_( len_a ),
162  str_( len_ > 0 ? new char[ len_ ] : 0 ),
163  c_str_( 0 ),
164  sub_( false )
165  {
166  size_type const s_len( s.length() );
167  if ( len_ > s_len ) {
168  if ( s_len > 0 ) s.copy( str_, s_len );
169  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
170  } else if ( len_ > 0 ) {
171  s.copy( str_, len_ );
172  }
173  }
174 
175 
176  /// @brief Length + cstring Constructor
177  Fstring::Fstring( size_type const len_a, c_cstring const s ) :
178  len_( len_a ),
179  str_( len_ > 0 ? new char[ len_ ] : 0 ),
180  c_str_( 0 ),
181  sub_( false )
182  {
183  size_type const s_len( std::strlen( s ) );
184  if ( len_ > s_len ) {
185  if ( s_len > 0 ) std::memcpy( str_, s, s_len );
186  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
187  } else if ( len_ > 0 ) {
188  std::memcpy( str_, s, len_ );
189  }
190  }
191 
192 
193  /// @brief Length + char Constructor
194  /// @note Fills with specified char => Use Fstring( len_a, "c" ) for space-padded single character
195  Fstring::Fstring( size_type const len_a, char const c ) :
196  len_( len_a ),
197  str_( len_ > 0 ? new char[ len_ ] : 0 ),
198  c_str_( 0 ),
199  sub_( false )
200  {
201  std::memset( str_, c, len_ );
202  }
203 
204 
205  /// @brief Length + Initializer Constructor
206  Fstring::Fstring( size_type const len_a, initializer_function init ) :
207  len_( len_a ),
208  str_( len_ > 0 ? new char[ len_ ] : 0 ),
209  c_str_( 0 ),
210  sub_( false )
211  {
212  std::memset( str_, SPACE, len_ );
213  init( *this );
214  }
215 
216 
217  /// @brief Substring Range Constructor
218  Fstring::Fstring( Fstring const & s, size_type const i, size_type const j ) :
219  len_( i <= std::min( j, s.len_ ) ? std::min( j, s.len_ ) - i + 1u : static_cast< size_type >( 0 ) ),
220  str_( i <= s.len_ ? s.str_ + i - 1u : s.str_ ),
221  c_str_( 0 ),
222  sub_( true )
223  {
224  assert( i > 0 );
225  }
226 
227 
228  /// @brief Substring Tail Constructor
229  Fstring::Fstring( Fstring const & s, size_type const i ) :
230  len_( i <= s.len_ ? s.len_ - i + 1u : static_cast< size_type >( 0 ) ),
231  str_( i <= s.len_ ? s.str_ + i - 1u : s.str_ ),
232  c_str_( 0 ),
233  sub_( true )
234  {
235  assert( i > 0 );
236  }
237 
238 
239  /// @brief Copy Assignment
240  Fstring &
242  {
243  if ( this != &s ) {
244  if ( len_ > s.len_ ) {
245  if ( s.len_ > 0 ) std::memmove( str_, s.str_, s.len_ );
246  std::memset( str_ + s.len_, SPACE, len_ - s.len_ ); // Space pad
247  } else if ( len_ > 0 ) {
248  std::memmove( str_, s.str_, len_ );
249  } else if ( ( ! str_ ) && ( ! sub_ ) ) { // Uninitialized
250  len_ = s.len_;
251  str_ = ( len_ > 0 ? new char[ len_ ] : 0 );
252  std::memcpy( str_, s.str_, len_ );
253  }
254  }
255  return *this;
256  }
257 
258 
259  /// @brief = string
260  Fstring &
261  Fstring::operator =( std::string const & s )
262  {
263  size_type const s_len( s.length() );
264  if ( len_ > s_len ) {
265  if ( s_len > 0 ) s.copy( str_, s_len );
266  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
267  } else if ( len_ > 0 ) {
268  s.copy( str_, len_ );
269  } else if ( ( ! str_ ) && ( ! sub_ ) ) { // Uninitialized
270  len_ = s_len;
271  str_ = ( len_ > 0 ? new char[ len_ ] : 0 );
272  s.copy( str_, len_ );
273  }
274  return *this;
275  }
276 
277 
278  /// @brief = cstring
279  Fstring &
281  {
282  size_type const s_len( std::strlen( s ) );
283  if ( len_ > s_len ) {
284  if ( s_len > 0 ) std::memmove( str_, s, s_len );
285  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
286  } else if ( len_ > 0 ) {
287  std::memmove( str_, s, len_ );
288  } else if ( ( ! str_ ) && ( ! sub_ ) ) { // Uninitialized
289  len_ = s_len;
290  str_ = ( len_ > 0 ? new char[ len_ ] : 0 );
291  std::memcpy( str_, s, len_ );
292  }
293  return *this;
294  }
295 
296 
297  /// @brief = char
298  Fstring &
299  Fstring::operator =( char const c )
300  {
301  if ( len_ > 0 ) {
302  str_[ 0 ] = c;
303  if ( len_ > 1 ) std::memset( str_ + 1, SPACE, len_ - 1 ); // Space pad
304  } else if ( ( ! str_ ) && ( ! sub_ ) ) { // Uninitialized
305  len_ = 1;
306  str_ = new char[ 1 ];
307  str_[ 0 ] = c;
308  }
309  return *this;
310  }
311 
312 
313  /// @brief Has an Fstring?
314  bool
315  Fstring::has( Fstring const & s ) const
316  {
317  for ( size_type i = 1; i <= len_; ++i ) {
318  if ( (*this)( i ) == s ) return true;
319  }
320  return false; // No matches
321  }
322 
323 
324  /// @brief Has a string?
325  bool
326  Fstring::has( std::string const & s ) const
327  {
328  for ( size_type i = 1; i <= len_; ++i ) {
329  if ( (*this)( i ) == s ) return true;
330  }
331  return false; // No matches
332  }
333 
334 
335  /// @brief Has a cstring?
336  bool
337  Fstring::has( c_cstring const s ) const
338  {
339  for ( size_type i = 1; i <= len_; ++i ) {
340  if ( (*this)( i ) == s ) return true;
341  }
342  return false; // No matches
343  }
344 
345 
346  /// @brief Has a Character?
347  bool
348  Fstring::has( char const c ) const
349  {
350  for ( size_type i = 0; i < len_; ++i ) {
351  if ( str_[ i ] == c ) return true;
352  }
353  return false; // No matches
354  }
355 
356 
357  /// @brief Has Any Character of an Fstring?
358  bool
359  Fstring::has_any_of( Fstring const & s ) const
360  {
361  for ( size_type i = 0; i < len_; ++i ) {
362  for ( size_type j = 0, e = s.len_; j < e; ++j ) {
363  if ( str_[ i ] == s.str_[ j ] ) return true;
364  }
365  }
366  return false; // No matches
367  }
368 
369 
370  /// @brief Has Any Character of a string?
371  bool
372  Fstring::has_any_of( std::string const & s ) const
373  {
374  std::string::size_type const s_len( s.length() );
375  for ( size_type i = 0; i < len_; ++i ) {
376  for ( size_type j = 0; j < s_len; ++j ) {
377  if ( str_[ i ] == s[ j ] ) return true;
378  }
379  }
380  return false; // No matches
381  }
382 
383 
384  /// @brief Has Any Character of a cstring?
385  bool
387  {
388  size_type const s_len( std::strlen( s ) );
389  for ( size_type i = 0; i < len_; ++i ) {
390  for ( size_type j = 0; j < s_len; ++j ) {
391  if ( str_[ i ] == s[ j ] ) return true;
392  }
393  }
394  return false; // No matches
395  }
396 
397 
398  /// @brief Has a Character?
399  bool
400  Fstring::has_any_of( char const c ) const
401  {
402  for ( size_type i = 0; i < len_; ++i ) {
403  if ( str_[ i ] == c ) return true;
404  }
405  return false; // No matches
406  }
407 
408 
409  /// @brief Has a Prefix Case-Optionally?
410  bool
411  Fstring::has_prefix( Fstring const & s, bool const exact_case ) const
412  {
413  if ( s.len_ == 0 ) {
414  return false;
415  } else if ( len_ < s.len_ ) {
416  return false;
417  } else if ( exact_case ) {
418  return ( (*this)( 1, s.len_ ) == s );
419  } else {
420  return ( lowercased()( 1, s.len_ ) == s.lowercased() );
421  }
422  }
423 
424 
425  /// @brief Has a Prefix Case-Optionally?
426  bool
427  Fstring::has_prefix( c_cstring const s, bool const exact_case ) const
428  {
429  size_type const s_len( std::strlen( s ) );
430  if ( s_len == 0 ) {
431  return false;
432  } else if ( len_ < s_len ) {
433  return false;
434  } else if ( exact_case ) {
435  return ( (*this)( 1, s_len ) == s );
436  } else {
437  return ( lowercased()( 1, s_len ) == Fstring( s ).lowercase() );
438  }
439  }
440 
441 
442  /// @brief Length Space-Trimmed
445  {
446  for ( size_type i = len_; i > 0; --i ) {
447  if ( str_[ i - 1 ] != SPACE ) return i;
448  }
449  return 0;
450  }
451 
452 
453  /// @brief Length Whitespace-Trimmed
456  {
457  for ( size_type i = len_; i > 0; --i ) {
458  char const c( str_[ i - 1 ] );
459  if ( ( c != SPACE ) && ( c != TAB ) && ( c != NULLC ) ) return i;
460  }
461  return 0;
462  }
463 
464 
465  /// @brief Find First Occurrence of a Whitespace Character
468  {
469  for ( size_type i = 1; i <= len_; ++i ) {
470  char const c( str_[ i - 1 ] );
471  if ( ( c == SPACE ) || ( c == TAB ) || ( c == NULLC ) ) return i;
472  }
473  return 0; // All are non-whitespace
474  }
475 
476 
477  /// @brief Find First Occurrence of a Non-Whitespace Character
480  {
481  for ( size_type i = 1; i <= len_; ++i ) {
482  char const c( str_[ i - 1 ] );
483  if ( ( c != SPACE ) && ( c != TAB ) && ( c != NULLC ) ) return i;
484  }
485  return 0; // All are whitespace
486  }
487 
488 
489  /// @brief Find Last Occurrence of a Whitespace Character
492  {
493  for ( size_type i = len_; i > 0; --i ) {
494  char const c( str_[ i - 1 ] );
495  if ( ( c == SPACE ) || ( c == TAB ) || ( c == NULLC ) ) return i;
496  }
497  return 0; // All are non-whitespace
498  }
499 
500 
501  /// @brief Find Last Occurrence of a Non-Whitespace Character
504  {
505  for ( size_type i = len_; i > 0; --i ) {
506  char const c( str_[ i - 1 ] );
507  if ( ( c != SPACE ) && ( c != TAB ) && ( c != NULLC ) ) return i;
508  }
509  return 0; // All are whitespace
510  }
511 
512 
513  /// @brief Get Range of Whitespace-Trimmed Portion and Return its Length
516  {
517  b = std::max( find_non_whitespace(), static_cast< size_type >( 1 ) );
518  e = len_trim_whitespace();
519  return e - b + 1;
520  }
521 
522 
523  /// @brief Find First Occurrence of an Fstring
525  Fstring::find( Fstring const & s ) const
526  {
527  size_type const s_len( s.length() );
528  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
529  for ( size_type i = 1, e = len_ - s_len + 1; i <= e; ++i ) {
530  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
531  }
532  }
533  return 0; // No matches
534  }
535 
536 
537  /// @brief Find First Occurrence of a string
539  Fstring::find( std::string const & s ) const
540  {
541  std::string::size_type const s_len( s.length() );
542  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
543  for ( size_type i = 1, e = len_ - s_len + 1; i <= e; ++i ) {
544  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
545  }
546  }
547  return 0; // No matches
548  }
549 
550 
551  /// @brief Find First Occurrence of a cstring
553  Fstring::find( c_cstring const s ) const
554  {
555  size_type const s_len( std::strlen( s ) );
556  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
557  for ( size_type i = 1, e = len_ - s_len + 1; i <= e; ++i ) {
558  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
559  }
560  }
561  return 0; // No matches
562  }
563 
564 
565  /// @brief Find First Occurrence of a Character
567  Fstring::find( char const c ) const
568  {
569  for ( size_type i = 1; i <= len_; ++i ) {
570  if ( str_[ i - 1 ] == c ) return i;
571  }
572  return 0; // No matches
573  }
574 
575 
576  /// @brief Find Last Occurrence of an Fstring
578  Fstring::find_last( Fstring const & s ) const
579  {
580  size_type const s_len( s.length() );
581  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
582  for ( size_type i = len_ - s_len + 1; i > 0; --i ) {
583  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
584  }
585  }
586  return 0; // No matches
587  }
588 
589 
590  /// @brief Find Last Occurrence of a string
592  Fstring::find_last( std::string const & s ) const
593  {
594  std::string::size_type const s_len( s.length() );
595  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
596  for ( size_type i = len_ - s_len + 1; i > 0; --i ) {
597  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
598  }
599  }
600  return 0; // No matches
601  }
602 
603 
604  /// @brief Find Last Occurrence of a cstring
607  {
608  size_type const s_len( std::strlen( s ) );
609  if ( ( s_len > 0 ) && ( s_len <= len_ ) ) {
610  for ( size_type i = len_ - s_len + 1; i > 0; --i ) {
611  if ( (*this)( i, i + s_len - 1 ) == s ) return i;
612  }
613  }
614  return 0; // No matches
615  }
616 
617 
618  /// @brief Find Last Occurrence of a Character
620  Fstring::find_last( char const c ) const
621  {
622  for ( size_type i = len_; i > 0; --i ) {
623  if ( str_[ i - 1 ] == c ) return i;
624  }
625  return 0; // No matches
626  }
627 
628 
629  /// @brief Find First Occurrence of Any Character of an Fstring
632  {
633  for ( size_type i = 1; i <= len_; ++i ) {
634  for ( size_type j = 0, e = s.len_; j < e; ++j ) {
635  if ( str_[ i - 1 ] == s.str_[ j ] ) return i;
636  }
637  }
638  return 0; // No matches
639  }
640 
641 
642  /// @brief Find First Occurrence of Any Character of a string
644  Fstring::find_first_of( std::string const & s ) const
645  {
646  std::string::size_type const s_len( s.length() );
647  for ( size_type i = 1; i <= len_; ++i ) {
648  for ( size_type j = 0; j < s_len; ++j ) {
649  if ( str_[ i - 1 ] == s[ j ] ) return i;
650  }
651  }
652  return 0; // No matches
653  }
654 
655 
656  /// @brief Find First Occurrence of Any Character of a cstring
659  {
660  size_type const s_len( std::strlen( s ) );
661  for ( size_type i = 1; i <= len_; ++i ) {
662  for ( size_type j = 0; j < s_len; ++j ) {
663  if ( str_[ i - 1 ] == s[ j ] ) return i;
664  }
665  }
666  return 0; // No matches
667  }
668 
669 
670  /// @brief Find First Occurrence of a Character
672  Fstring::find_first_of( char const c ) const
673  {
674  for ( size_type i = 1; i <= len_; ++i ) {
675  if ( str_[ i - 1 ] == c ) return i;
676  }
677  return 0; // No matches
678  }
679 
680 
681  /// @brief Find First Occurrence of Any Character not of an Fstring
684  {
685  for ( size_type i = 1; i <= len_; ++i ) {
686  bool found( false );
687  for ( size_type j = 0, e = s.len_; j < e; ++j ) {
688  if ( str_[ i - 1 ] == s.str_[ j ] ) {
689  found = true;
690  break;
691  }
692  }
693  if ( ! found ) return i;
694  }
695  return 0; // No matches
696  }
697 
698 
699  /// @brief Find First Occurrence of Any Character not of a string
701  Fstring::find_first_not_of( std::string const & s ) const
702  {
703  std::string::size_type const s_len( s.length() );
704  for ( size_type i = 1; i <= len_; ++i ) {
705  bool found( false );
706  for ( size_type j = 0; j < s_len; ++j ) {
707  if ( str_[ i - 1 ] == s[ j ] ) {
708  found = true;
709  break;
710  }
711  }
712  if ( ! found ) return i;
713  }
714  return 0; // No matches
715  }
716 
717 
718  /// @brief Find First Occurrence of Any Character not of a cstring
721  {
722  size_type const s_len( std::strlen( s ) );
723  for ( size_type i = 1; i <= len_; ++i ) {
724  bool found( false );
725  for ( size_type j = 0; j < s_len; ++j ) {
726  if ( str_[ i - 1 ] == s[ j ] ) {
727  found = true;
728  break;
729  }
730  }
731  if ( ! found ) return i;
732  }
733  return 0; // No matches
734  }
735 
736 
737  /// @brief Find First Occurrence not of a Character
739  Fstring::find_first_not_of( char const c ) const
740  {
741  for ( size_type i = 1; i <= len_; ++i ) {
742  if ( str_[ i - 1 ] != c ) return i;
743  }
744  return 0; // No matches
745  }
746 
747 
748  /// @brief Find Last Occurrence of Any Character of an Fstring
750  Fstring::find_last_of( Fstring const & s ) const
751  {
752  for ( size_type i = len_; i > 0; --i ) {
753  for ( size_type j = 0, e = s.len_; j < e; ++j ) {
754  if ( str_[ i - 1 ] == s.str_[ j ] ) return i;
755  }
756  }
757  return 0; // No matches
758  }
759 
760 
761  /// @brief Find Last Occurrence of Any Character of a string
763  Fstring::find_last_of( std::string const & s ) const
764  {
765  std::string::size_type const s_len( s.length() );
766  for ( size_type i = len_; i > 0; --i ) {
767  for ( size_type j = 0; j < s_len; ++j ) {
768  if ( str_[ i - 1 ] == s[ j ] ) return i;
769  }
770  }
771  return 0; // No matches
772  }
773 
774 
775  /// @brief Find Last Occurrence of Any Character of a cstring
778  {
779  size_type const s_len( std::strlen( s ) );
780  for ( size_type i = len_; i > 0; --i ) {
781  for ( size_type j = 0; j < s_len; ++j ) {
782  if ( str_[ i - 1 ] == s[ j ] ) return i;
783  }
784  }
785  return 0; // No matches
786  }
787 
788 
789  /// @brief Find Last Occurrence of a Character
791  Fstring::find_last_of( char const c ) const
792  {
793  for ( size_type i = len_; i > 0; --i ) {
794  if ( str_[ i - 1 ] == c ) return i;
795  }
796  return 0; // No matches
797  }
798 
799 
800  /// @brief Find Last Occurrence of Any Character not of an Fstring
803  {
804  for ( size_type i = len_; i > 0; --i ) {
805  bool found( false );
806  for ( size_type j = 0, e = s.len_; j < e; ++j ) {
807  if ( str_[ i - 1 ] == s.str_[ j ] ) {
808  found = true;
809  break;
810  }
811  }
812  if ( ! found ) return i;
813  }
814  return 0; // No matches
815  }
816 
817 
818  /// @brief Find Last Occurrence of Any Character not of a string
820  Fstring::find_last_not_of( std::string const & s ) const
821  {
822  std::string::size_type const s_len( s.length() );
823  for ( size_type i = len_; i > 0; --i ) {
824  bool found( false );
825  for ( size_type j = 0; j < s_len; ++j ) {
826  if ( str_[ i - 1 ] == s[ j ] ) {
827  found = true;
828  break;
829  }
830  }
831  if ( ! found ) return i;
832  }
833  return 0; // No matches
834  }
835 
836 
837  /// @brief Find Last Occurrence of Any Character not of a cstring
840  {
841  size_type const s_len( std::strlen( s ) );
842  for ( size_type i = len_; i > 0; --i ) {
843  bool found( false );
844  for ( size_type j = 0; j < s_len; ++j ) {
845  if ( str_[ i - 1 ] == s[ j ] ) {
846  found = true;
847  break;
848  }
849  }
850  if ( ! found ) return i;
851  }
852  return 0; // No matches
853  }
854 
855 
856  /// @brief Find Last Occurrence not of a Character
858  Fstring::find_last_not_of( char const c ) const
859  {
860  for ( size_type i = len_; i > 0; --i ) {
861  if ( str_[ i - 1 ] != c ) return i;
862  }
863  return 0; // No matches
864  }
865 
866 
867  /// @brief Lowercase
868  Fstring &
870  {
871  for ( size_type i = 0; i < len_; ++i ) {
872  str_[ i ] = std::tolower( str_[ i ] );
873  }
874  return *this;
875  }
876 
877 
878  /// @brief Uppercase
879  Fstring &
881  {
882  for ( size_type i = 0; i < len_; ++i ) {
883  str_[ i ] = std::toupper( str_[ i ] );
884  }
885  return *this;
886  }
887 
888 
889  /// @brief Left Justify
890  Fstring &
892  {
893  for ( size_type i = 0; i < len_; ++i ) {
894  if ( str_[ i ] != SPACE ) {
895  if ( i > 0 ) {
896  std::memmove( str_, str_ + i, len_ - i );
897  std::memset( str_ + len_ - i, SPACE, i );
898  }
899  return *this;
900  }
901  }
902  return *this;
903  }
904 
905 
906  /// @brief Right Justify
907  Fstring &
909  {
910  for ( size_type i = len_; i > 0; --i ) {
911  if ( str_[ i - 1 ] != SPACE ) {
912  if ( i < len_ ) {
913  std::memmove( str_ + len_ - i, str_, i );
914  std::memset( str_, SPACE, len_ - i );
915  }
916  return *this;
917  }
918  }
919  return *this;
920  }
921 
922 
923  /// @brief Center
924  Fstring &
926  {
927  left_justify();
928  size_type const len_t( len_trim() );
929  size_type const pad( ( len_ - len_t ) / 2 );
930  if ( pad > 0 ) {
931  std::memmove( str_ + pad, str_, len_t );
932  std::memset( str_, SPACE, pad );
933  }
934  return *this;
935  }
936 
937 
938  /// @brief Compress Out Whitespace
939  Fstring &
941  {
942  size_type j( 0 );
943  for ( size_type i = 0; i < len_; ++i ) {
944  char const c( str_[ i ] );
945  if ( ( c != SPACE ) && ( c != TAB ) && ( c != NULLC ) ) str_[ j++ ] = c;
946  }
947  if ( j < len_ ) std::memset( str_ + j, SPACE, len_ - j );
948  return *this;
949  }
950 
951 
952  /// @brief Trim Trailing Whitespace Replacing it with Space
953  Fstring &
955  {
956  if ( len_ > 0 ) {
957  size_type const ie( len_trim_whitespace() );
958  if ( ie < len_ ) {
959  std::memset( str_ + ie, SPACE, len_ - ie ); // Space pad
960  }
961  }
962  return *this;
963  }
964 
965 
966  /// @brief Strip Specified Characters from the Tails
967  Fstring &
968  Fstring::strip( std::string const & chars )
969  {
970  if ( len_ > 0 ) {
971  size_type const ib( find_first_not_of( chars ) );
972  if ( ib == 0 ) {
973  clear();
974  } else {
975  size_type const ie( find_last_not_of( chars ) );
976  assert( ie >= ib );
977  size_type const len_sub( ie - ib + 1 );
978  if ( len_sub < len_ ) {
979  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
980  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
981  }
982  }
983  }
984  return *this;
985  }
986 
987 
988  /// @brief Strip Specified Characters from the Left Tail
989  Fstring &
990  Fstring::lstrip( std::string const & chars )
991  {
992  if ( len_ > 0 ) {
993  size_type const ib( find_first_not_of( chars ) );
994  if ( ib == 0 ) {
995  clear();
996  } else {
997  size_type const len_sub( len_ - ib + 1 );
998  if ( len_sub < len_ ) {
999  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
1000  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
1001  }
1002  }
1003  }
1004  return *this;
1005  }
1006 
1007 
1008  /// @brief Strip Specified Characters from the Right Tail
1009  Fstring &
1010  Fstring::rstrip( std::string const & chars )
1011  {
1012  if ( len_ > 0 ) {
1013  size_type const ie( find_last_not_of( chars ) );
1014  if ( ie == 0 ) {
1015  clear();
1016  } else if ( ie < len_ ) {
1017  std::memset( str_ + ie, SPACE, len_ - ie ); // Space pad
1018  }
1019  }
1020  return *this;
1021  }
1022 
1023 
1024  /// @brief Strip Space from the Tails
1025  Fstring &
1027  {
1028  if ( len_ > 0 ) {
1029  size_type const ib( find_first_not_of( SPACE ) );
1030  if ( ib == 0 ) {
1031  clear();
1032  } else {
1033  size_type const ie( find_last_not_of( SPACE ) );
1034  assert( ie >= ib );
1035  size_type const len_sub( ie - ib + 1 );
1036  if ( len_sub < len_ ) {
1037  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
1038  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
1039  }
1040  }
1041  }
1042  return *this;
1043  }
1044 
1045 
1046  /// @brief Strip Space from the Left Tail
1047  Fstring &
1049  {
1050  if ( len_ > 0 ) {
1051  size_type const ib( find_first_not_of( SPACE ) );
1052  if ( ib == 0 ) {
1053  clear();
1054  } else {
1055  size_type const len_sub( len_ - ib + 1 );
1056  if ( len_sub < len_ ) {
1057  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
1058  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
1059  }
1060  }
1061  }
1062  return *this;
1063  }
1064 
1065 
1066  /// @brief Strip Space from the Right Tail
1067  Fstring &
1069  {
1070  if ( len_ > 0 ) {
1071  size_type const ie( find_last_not_of( SPACE ) );
1072  if ( ie == 0 ) {
1073  clear();
1074  } else if ( ie < len_ ) {
1075  std::memset( str_ + ie, SPACE, len_ - ie ); // Space pad
1076  }
1077  }
1078  return *this;
1079  }
1080 
1081 
1082  /// @brief Strip Whitespace from the Tails
1083  Fstring &
1085  {
1086  if ( len_ > 0 ) {
1087  size_type const ib( find_first_not_of( WHITESPACE ) );
1088  if ( ib == 0 ) {
1089  clear();
1090  } else {
1091  size_type const ie( find_last_not_of( WHITESPACE ) );
1092  assert( ie >= ib );
1093  size_type const len_sub( ie - ib + 1 );
1094  if ( len_sub < len_ ) {
1095  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
1096  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
1097  }
1098  }
1099  }
1100  return *this;
1101  }
1102 
1103 
1104  /// @brief Strip Whitespace from the Left Tail
1105  Fstring &
1107  {
1108  if ( len_ > 0 ) {
1109  size_type const ib( find_first_not_of( WHITESPACE ) );
1110  if ( ib == 0 ) {
1111  clear();
1112  } else {
1113  size_type const len_sub( len_ - ib + 1 );
1114  if ( len_sub < len_ ) {
1115  if ( ib > 1 ) std::memmove( str_, str_ + ib - 1, len_sub );
1116  std::memset( str_ + len_sub, SPACE, len_ - len_sub ); // Space pad
1117  }
1118  }
1119  }
1120  return *this;
1121  }
1122 
1123 
1124  /// @brief Strip Whitespace from the Right Tail
1125  Fstring &
1127  {
1128  if ( len_ > 0 ) {
1129  size_type const ie( find_last_not_of( WHITESPACE ) );
1130  if ( ie == 0 ) {
1131  clear();
1132  } else if ( ie < len_ ) {
1133  std::memset( str_ + ie, SPACE, len_ - ie ); // Space pad
1134  }
1135  }
1136  return *this;
1137  }
1138 
1139 
1140  /// @brief Overlay an Fstring
1141  Fstring &
1143  {
1144  (*this)( pos, std::min( ( pos + s.len_ ) - 1, len_ ) ) = s;
1145  return *this;
1146  }
1147 
1148 
1149  /// @brief Overlay a string
1150  Fstring &
1151  Fstring::overlay( std::string const & s, size_type const pos )
1152  {
1153  (*this)( pos, std::min<size_type>( ( pos + s.length() ) - 1, len_ ) ) = s;
1154  return *this;
1155  }
1156 
1157 
1158  /// @brief Overlay a cstring
1159  Fstring &
1161  {
1162  (*this)( pos, std::min<size_type>( ( pos + std::strlen( s ) ) - 1, len_ ) ) = s;
1163  return *this;
1164  }
1165 
1166 
1167  /// @brief Null-Terminated cstring Copy of the Fstring that is Owned by the Fstring
1168  c_cstring
1170  {
1171  delete[] c_str_; c_str_ = new char[ len_ + 1 ];
1172  if ( len_ > 0 ) std::memmove( c_str_, str_, len_ ); // Copy the string data
1173  c_str_[ len_ ] = '\0'; // Null-terminate
1174  return c_str_;
1175  }
1176 
1177 
1178  /// @brief Whitespace-Trimmed Null-Terminated cstring Copy of the Fstring that is Owned by the Fstring
1179  /// @note This shares data/pointer with c_str()
1180  c_cstring
1182  {
1183  size_type const len_trim_whitespace_( len_trim_whitespace() );
1184  delete[] c_str_; c_str_ = new char[ len_trim_whitespace_ + 1 ];
1185  if ( len_trim_whitespace_ > 0 ) std::memmove( c_str_, str_, len_trim_whitespace_ ); // Copy the string data
1186  c_str_[ len_trim_whitespace_ ] = '\0'; // Null-terminate
1187  return c_str_;
1188  }
1189 
1190 
1191  /// @brief Copy to a Pre-Allocated String
1193  Fstring::copy( cstring str, size_type const len_a, size_type const off ) const
1194  {
1195  assert( off <= len_ );
1196  size_type const len_copied( std::min( len_ - std::min( off, len_ ), len_a ) );
1197  if ( len_copied > 0 ) std::memmove( str, str_ + off, len_copied );
1198  return len_copied;
1199  }
1200 
1201 
1202  /// @brief Fstring == Fstring
1203  bool
1204  operator ==( Fstring const & s, Fstring const & t )
1205  {
1206  Fstring::size_type const min_len( std::min( s.len_, t.len_ ) );
1207  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1208  if ( s.str_[ i ] != t.str_[ i ] ) return false;
1209  }
1210  if ( s.len_ < t.len_ ) {
1211  for ( Fstring::size_type i = s.len_, e = t.len_; i < e; ++i ) {
1212  if ( t.str_[ i ] != SPACE ) return false;
1213  }
1214  } else if ( s.len_ > t.len_ ) {
1215  for ( Fstring::size_type i = t.len_, e = s.len_; i < e; ++i ) {
1216  if ( s.str_[ i ] != SPACE ) return false;
1217  }
1218  }
1219  return true;
1220  }
1221 
1222 
1223  /// @brief Fstring == string
1224  bool
1225  operator ==( Fstring const & s, std::string const & t )
1226  {
1227  Fstring::size_type const t_len( t.length() );
1228  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1229  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1230  if ( s.str_[ i ] != t[ i ] ) return false;
1231  }
1232  if ( s.len_ < t_len ) {
1233  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1234  if ( t[ i ] != SPACE ) return false;
1235  }
1236  } else if ( s.len_ > t_len ) {
1237  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1238  if ( s.str_[ i ] != SPACE ) return false;
1239  }
1240  }
1241  return true;
1242  }
1243 
1244 
1245  /// @brief Fstring == cstring
1246  bool
1247  operator ==( Fstring const & s, c_cstring const t )
1248  {
1249  Fstring::size_type const t_len( std::strlen( t ) );
1250  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1251  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1252  if ( s.str_[ i ] != t[ i ] ) return false;
1253  }
1254  if ( s.len_ < t_len ) {
1255  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1256  if ( t[ i ] != SPACE ) return false;
1257  }
1258  } else if ( s.len_ > t_len ) {
1259  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1260  if ( s.str_[ i ] != SPACE ) return false;
1261  }
1262  }
1263  return true;
1264  }
1265 
1266 
1267  /// @brief Fstring == char
1268  bool
1269  operator ==( Fstring const & s, char const c )
1270  {
1271  if ( s.empty() ) { // Zero-length Fstring
1272  return false;
1273  } else if ( s.str_[ 0 ] == c ) { // First character matches
1274  return ( s( 2 ).is_blank() ); // Rest is blank
1275  } else { // First character doesn't match
1276  return false;
1277  }
1278  }
1279 
1280 
1281  /// @brief Fstring <= Fstring
1282  bool
1283  operator <=( Fstring const & s, Fstring const & t )
1284  {
1285  Fstring::size_type const min_len( std::min( s.len_, t.len_ ) );
1286  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1287  unsigned char const s_i( s.str_[ i ] );
1288  unsigned char const t_i( t.str_[ i ] );
1289  if ( s_i < t_i ) {
1290  return true;
1291  } else if ( s_i > t_i ) {
1292  return false;
1293  }
1294  }
1295  if ( s.len_ < t.len_ ) {
1296  for ( Fstring::size_type i = s.len_, e = t.len_; i < e; ++i ) {
1297  unsigned char const t_i( t.str_[ i ] );
1298  if ( SPACE < t_i ) {
1299  return true;
1300  } else if ( SPACE > t_i ) {
1301  return false;
1302  }
1303  }
1304  } else if ( s.len_ > t.len_ ) {
1305  for ( Fstring::size_type i = t.len_, e = s.len_; i < e; ++i ) {
1306  unsigned char const s_i( s.str_[ i ] );
1307  if ( s_i < SPACE ) {
1308  return true;
1309  } else if ( s_i > SPACE ) {
1310  return false;
1311  }
1312  }
1313  }
1314  return true; // Equal
1315  }
1316 
1317 
1318  /// @brief Fstring < Fstring
1319  bool
1320  operator <( Fstring const & s, Fstring const & t )
1321  {
1322  Fstring::size_type const min_len( std::min( s.len_, t.len_ ) );
1323  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1324  unsigned char const s_i( s.str_[ i ] );
1325  unsigned char const t_i( t.str_[ i ] );
1326  if ( s_i < t_i ) {
1327  return true;
1328  } else if ( s_i > t_i ) {
1329  return false;
1330  }
1331  }
1332  if ( s.len_ < t.len_ ) {
1333  for ( Fstring::size_type i = s.len_, e = t.len_; i < e; ++i ) {
1334  unsigned char const t_i( t.str_[ i ] );
1335  if ( SPACE < t_i ) {
1336  return true;
1337  } else if ( SPACE > t_i ) {
1338  return false;
1339  }
1340  }
1341  } else if ( s.len_ > t.len_ ) {
1342  for ( Fstring::size_type i = t.len_, e = s.len_; i < e; ++i ) {
1343  unsigned char const s_i( s.str_[ i ] );
1344  if ( s_i < SPACE ) {
1345  return true;
1346  } else if ( s_i > SPACE ) {
1347  return false;
1348  }
1349  }
1350  }
1351  return false; // Equal
1352  }
1353 
1354 
1355  /// @brief Fstring <= string
1356  bool
1357  operator <=( Fstring const & s, std::string const & t )
1358  {
1359  Fstring::size_type const t_len( t.length() );
1360  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1361  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1362  unsigned char const s_i( s.str_[ i ] );
1363  unsigned char const t_i( t[ i ] );
1364  if ( s_i < t_i ) {
1365  return true;
1366  } else if ( s_i > t_i ) {
1367  return false;
1368  }
1369  }
1370  if ( s.len_ < t_len ) {
1371  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1372  unsigned char const t_i( t[ i ] );
1373  if ( SPACE < t_i ) {
1374  return true;
1375  } else if ( SPACE > t_i ) {
1376  return false;
1377  }
1378  }
1379  } else if ( s.len_ > t_len ) {
1380  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1381  unsigned char const s_i( s.str_[ i ] );
1382  if ( s_i < SPACE ) {
1383  return true;
1384  } else if ( s_i > SPACE ) {
1385  return false;
1386  }
1387  }
1388  }
1389  return true; // Equal
1390  }
1391 
1392 
1393  /// @brief Fstring < string
1394  bool
1395  operator <( Fstring const & s, std::string const & t )
1396  {
1397  Fstring::size_type const t_len( t.length() );
1398  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1399  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1400  unsigned char const s_i( s.str_[ i ] );
1401  unsigned char const t_i( t[ i ] );
1402  if ( s_i < t_i ) {
1403  return true;
1404  } else if ( s_i > t_i ) {
1405  return false;
1406  }
1407  }
1408  if ( s.len_ < t_len ) {
1409  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1410  unsigned char const t_i( t[ i ] );
1411  if ( SPACE < t_i ) {
1412  return true;
1413  } else if ( SPACE > t_i ) {
1414  return false;
1415  }
1416  }
1417  } else if ( s.len_ > t_len ) {
1418  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1419  unsigned char const s_i( s.str_[ i ] );
1420  if ( s_i < SPACE ) {
1421  return true;
1422  } else if ( s_i > SPACE ) {
1423  return false;
1424  }
1425  }
1426  }
1427  return false; // Equal
1428  }
1429 
1430 
1431  /// @brief Fstring <= cstring
1432  bool
1433  operator <=( Fstring const & s, c_cstring const t )
1434  {
1435  Fstring::size_type const t_len( std::strlen( t ) );
1436  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1437  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1438  unsigned char const s_i( s.str_[ i ] );
1439  unsigned char const t_i( t[ i ] );
1440  if ( s_i < t_i ) {
1441  return true;
1442  } else if ( s_i > t_i ) {
1443  return false;
1444  }
1445  }
1446  if ( s.len_ < t_len ) {
1447  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1448  unsigned char const t_i( t[ i ] );
1449  if ( SPACE < t_i ) {
1450  return true;
1451  } else if ( SPACE > t_i ) {
1452  return false;
1453  }
1454  }
1455  } else if ( s.len_ > t_len ) {
1456  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1457  unsigned char const s_i( s.str_[ i ] );
1458  if ( s_i < SPACE ) {
1459  return true;
1460  } else if ( s_i > SPACE ) {
1461  return false;
1462  }
1463  }
1464  }
1465  return true; // Equal
1466  }
1467 
1468 
1469  /// @brief Fstring < cstring
1470  bool
1471  operator <( Fstring const & s, c_cstring const t )
1472  {
1473  Fstring::size_type const t_len( std::strlen( t ) );
1474  Fstring::size_type const min_len( std::min( s.len_, t_len ) );
1475  for ( Fstring::size_type i = 0; i < min_len; ++i ) {
1476  unsigned char const s_i( s.str_[ i ] );
1477  unsigned char const t_i( t[ i ] );
1478  if ( s_i < t_i ) {
1479  return true;
1480  } else if ( s_i > t_i ) {
1481  return false;
1482  }
1483  }
1484  if ( s.len_ < t_len ) {
1485  for ( Fstring::size_type i = s.len_; i < t_len; ++i ) {
1486  unsigned char const t_i( t[ i ] );
1487  if ( SPACE < t_i ) {
1488  return true;
1489  } else if ( SPACE > t_i ) {
1490  return false;
1491  }
1492  }
1493  } else if ( s.len_ > t_len ) {
1494  for ( Fstring::size_type i = t_len, e = s.len_; i < e; ++i ) {
1495  unsigned char const s_i( s.str_[ i ] );
1496  if ( s_i < SPACE ) {
1497  return true;
1498  } else if ( s_i > SPACE ) {
1499  return false;
1500  }
1501  }
1502  }
1503  return false; // Equal
1504  }
1505 
1506 
1507  /// @brief Constant Substring: s( i, j )
1508  Fsubstring const
1509  Fstring::operator ()( size_type const i, size_type const j ) const
1510  {
1511  return Fsubstring( *this, i, j );
1512  }
1513 
1514 
1515  /// @brief Substring: s( i, j )
1516  Fsubstring
1518  {
1519  return Fsubstring( *this, i, j );
1520  }
1521 
1522 
1523  /// @brief Constant Tail Substring: s( i )
1524  Fstring const
1526  {
1527  return Fsubstring( *this, i );
1528  }
1529 
1530 
1531  /// @brief Tail Substring: s( i )
1532  Fsubstring
1534  {
1535  return Fsubstring( *this, i );
1536  }
1537 
1538 
1539  /// @brief Space-Free Head Constant Substring
1540  Fsubstring const
1542  {
1543  size_type const ie( find( SPACE ) );
1544  if ( ie == 0 ) {
1545  return Fsubstring( *this, 1, len_ );
1546  } else {
1547  return Fsubstring( *this, 1, ie - 1 );
1548  }
1549  }
1550 
1551 
1552  /// @brief Space-Free Head Substring
1553  Fsubstring
1555  {
1556  size_type const ie( find( SPACE ) );
1557  if ( ie == 0 ) {
1558  return Fsubstring( *this, 1, len_ );
1559  } else {
1560  return Fsubstring( *this, 1, ie - 1 );
1561  }
1562  }
1563 
1564 
1565  /// @brief Space Tail Constant Substring
1566  Fsubstring const
1568  {
1569  return Fsubstring( *this, len_trim() + 1 );
1570  }
1571 
1572 
1573  /// @brief Space Tail Substring
1574  Fsubstring
1576  {
1577  return Fsubstring( *this, len_trim() + 1 );
1578  }
1579 
1580 
1581  /// @brief Stream Input
1582  std::istream &
1583  operator >>( std::istream & stream, Fstring & s )
1584  {
1585  std::string ss;
1586  stream >> std::setw( s.len_ ) >> ss;
1587  s = ss;
1588  return stream;
1589  }
1590 
1591 
1592  /// @brief Get from Stream
1593  std::istream &
1594  get( std::istream & stream, Fstring & s )
1595  {
1596  if ( s.len_ > 0 ) {
1597  char * const buff( new char[ s.len_ + 1 ] );
1598  stream.get( buff, s.len_ + 1 ); // get adds null-terminator
1599  std::size_t const lb( std::strlen( buff ) );
1600  std::memcpy( s.str_, buff, lb );
1601  std::memset( s.str_ + lb, SPACE, s.len_ - lb );
1602  delete[] buff;
1603  }
1604  return stream;
1605  }
1606 
1607 
1608  /// @brief Get Line from Stream
1609  std::istream &
1610  getline( std::istream & stream, Fstring & s )
1611  {
1612  std::string ss;
1613  stream.width( s.len_ );
1614  std::getline( stream, ss );
1615  s = ss;
1616  return stream;
1617  }
1618 
1619 
1620  /// @brief Read from Stream
1621  std::istream &
1622  read( std::istream & stream, Fstring & s )
1623  {
1624  stream.read( s.str_, s.len_ );
1625  return stream;
1626  }
1627 
1628 
1629  /// @brief Read Available Characters from Stream
1630  std::istream &
1631  readsome( std::istream & stream, Fstring & s )
1632  {
1633  stream.readsome( s.str_, s.len_ );
1634  return stream;
1635  }
1636 
1637 
1638  /// @brief Stream Output
1639  std::ostream &
1640  operator <<( std::ostream & stream, Fstring const & s )
1641  {
1642  stream.write( s.str_, s.len_ );
1643  return stream;
1644  }
1645 
1646 
1647 // Fstring
1648 
1649 
1650 // Fsubstring
1651 
1652 
1653  /// @brief Copy Assignment
1654  Fsubstring &
1656  {
1657  if ( this != &s ) {
1658  if ( len_ > s.len_ ) {
1659  if ( s.len_ > 0 ) std::memmove( str_, s.str_, s.len_ );
1660  std::memset( str_ + s.len_, SPACE, len_ - s.len_ ); // Space pad
1661  } else if ( len_ > 0 ) {
1662  std::memmove( str_, s.str_, len_ );
1663  }
1664  }
1665  return *this;
1666  }
1667 
1668 
1669  /// @brief = Fstring
1670  Fsubstring &
1672  {
1673  if ( this != &s ) {
1674  if ( len_ > s.len_ ) {
1675  if ( s.len_ > 0 ) std::memmove( str_, s.str_, s.len_ );
1676  std::memset( str_ + s.len_, SPACE, len_ - s.len_ ); // Space pad
1677  } else if ( len_ > 0 ) {
1678  std::memmove( str_, s.str_, len_ );
1679  }
1680  }
1681  return *this;
1682  }
1683 
1684 
1685  /// @brief = string
1686  Fsubstring &
1687  Fsubstring::operator =( std::string const & s )
1688  {
1689  size_type const s_len( s.length() );
1690  if ( len_ > s_len ) {
1691  if ( s_len > 0 ) s.copy( str_, s_len );
1692  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
1693  } else if ( len_ > 0 ) {
1694  s.copy( str_, len_ );
1695  }
1696  return *this;
1697  }
1698 
1699 
1700  /// @brief = cstring
1701  Fsubstring &
1703  {
1704  size_type const s_len( std::strlen( s ) );
1705  if ( len_ > s_len ) {
1706  if ( s_len > 0 ) std::memmove( str_, s, s_len );
1707  std::memset( str_ + s_len, SPACE, len_ - s_len ); // Space pad
1708  } else if ( len_ > 0 ) {
1709  std::memmove( str_, s, len_ );
1710  }
1711  return *this;
1712  }
1713 
1714 
1715  /// @brief = char
1716  Fsubstring &
1717  Fsubstring::operator =( char const c )
1718  {
1719  if ( len_ > 0 ) {
1720  str_[ 0 ] = c;
1721  if ( len_ > 1 ) std::memset( str_ + 1, SPACE, len_ - 1 ); // Space pad
1722  }
1723  return *this;
1724  }
1725 
1726 
1727 // Fsubstring
1728 
1729 
1730 } // namespace ObjexxFCL
std::istream & operator>>(std::istream &stream, byte &b)
Stream Input.
Definition: byte.hh:409
static T min(T x, T y)
Definition: Svm.cc:16
size_type len_
Length.
Definition: Fstring.hh:1694
Fstring & right_justify()
Right Justify.
Definition: Fstring.cc:908
Fstring & center()
Center.
Definition: Fstring.cc:925
size_type find_last_whitespace() const
Find Last Occurrence of a Whitespace Character.
Definition: Fstring.cc:491
Fstring lowercased() const
Lowercased Copy.
Definition: Fstring.hh:958
size_type copy(cstring str, size_type const len_a, size_type const off=0) const
Copy to a Pre-Allocated String.
Definition: Fstring.cc:1193
DimensionExpressionMin min(Dimension const &dim1, Dimension const &dim2)
min( Dimension, Dimension )
char const TAB( '\t')
std::istream & read(std::istream &stream, Fstring &s)
Read from Stream.
Definition: Fstring.cc:1622
Fstring & rstrip()
Strip Space from an Fstring's Right Tail.
Definition: Fstring.cc:1068
std::istream & getline(std::istream &stream, Fstring &s)
Get Line from Stream.
Definition: Fstring.cc:1610
Fstring & rstrip_whitespace()
Strip Whitespace from an Fstring's Right Tail.
Definition: Fstring.cc:1126
char * cstring
Definition: Cstring.hh:35
size_type find_whitespace() const
Find First Occurrence of a Whitespace Character.
Definition: Fstring.cc:467
char * c_str_
cstring
Definition: Fstring.hh:1700
bool operator<=(byte const &i, byte const &j)
byte <= byte
Definition: byte.hh:376
Fstring & overlay(Fstring const &s, size_type const pos=1)
Overlay an Fstring.
Definition: Fstring.cc:1142
c_cstring c_str() const
Null-Terminated cstring Copy of the Fstring that is Owned by the Fstring.
Definition: Fstring.cc:1169
size_type find_last(Fstring const &s) const
Find Last Occurrence of an Fstring.
Definition: Fstring.cc:578
Fstring & strip_whitespace()
Strip Whitespace from an Fstring's Tails.
Definition: Fstring.cc:1084
size_type find_last_not_of(Fstring const &s) const
Find Last Occurrence of Any Character not of an Fstring.
Definition: Fstring.cc:802
Fsubstring & operator=(Fsubstring const &s)
Copy Assignment.
Definition: Fstring.cc:1655
bool has_any_of(Fstring const &s) const
Has Any Character of an Fstring?
Definition: Fstring.cc:359
std::size_t size_type
Definition: Fstring.hh:66
size_type len_trim() const
Length Space-Trimmed.
Definition: Fstring.cc:444
Fstring & compress()
Compress Out Whitespace.
Definition: Fstring.cc:940
Fsubstring: Fixed-Length Fortran-Compatible Substring.
Definition: Fstring.hh:2039
size_type find_first_of(Fstring const &s) const
Find First Occurrence of Any Character of an Fstring.
Definition: Fstring.cc:631
char const * c_cstring
c_cstring t_str() const
Whitespace-Trimmed Null-Terminated cstring Copy of the Fstring that is Owned by the Fstring...
Definition: Fstring.cc:1181
size_type find(Fstring const &s) const
Find First Occurrence of an Fstring.
Definition: Fstring.cc:525
size_type find_first_not_of(Fstring const &s) const
Find First Occurrence of Any Character not of an Fstring.
Definition: Fstring.cc:683
std::istream & readsome(std::istream &stream, Fstring &s)
Read Available Characters from Stream.
Definition: Fstring.cc:1631
std::string & pad(std::string &s, std::string::size_type const len)
Pad a string to a Specified Length.
bool const sub_
Substring flag.
Definition: Fstring.hh:1703
bool has_prefix(Fstring const &s, bool const exact_case=true) const
Has a Prefix Case-Optionally?
Definition: Fstring.cc:411
Fstring & lstrip()
Strip Space from an Fstring's Left Tail.
Definition: Fstring.cc:1048
size_type find_last_non_whitespace() const
Find Last Occurrence of a Non-Whitespace Character.
Definition: Fstring.cc:503
Fstring & operator=(Fstring const &s)
Copy Assignment.
Definition: Fstring.cc:241
Fsubstring tail()
Space Tail Substring.
Definition: Fstring.cc:1575
Fstring & clear()
Clear.
Definition: Fstring.hh:894
friend class Fsubstring
Definition: Fstring.hh:60
bool has(Fstring const &s) const
Has an Fstring?
Definition: Fstring.cc:315
size_type find_non_whitespace() const
Find First Occurrence of a Non-Whitespace Character.
Definition: Fstring.cc:479
bool empty() const
Empty?
Definition: Fstring.hh:280
Fstring & trim_whitespace()
Trim Trailing Whitespace Replacing it with Space.
Definition: Fstring.cc:954
Fstring & lstrip_whitespace()
Strip Whitespace from an Fstring's Left Tail.
Definition: Fstring.cc:1106
size_type find_last_of(Fstring const &s) const
Find Last Occurrence of Any Character of an Fstring.
Definition: Fstring.cc:750
size_type length() const
Length.
Definition: Fstring.hh:514
char const NULLC( '\000')
DimensionExpressionMax max(Dimension const &dim1, Dimension const &dim2)
max( Dimension, Dimension )
Fstring & left_justify()
Left Justify.
Definition: Fstring.cc:891
Fsubstring const operator()(size_type const i, size_type const j) const
Constant Substring: s( i, j )
Definition: Fstring.cc:1509
Fstring: Fixed-Length Fortran-Compatible String.
Definition: Fstring.hh:53
bool operator<(byte const &i, byte const &j)
byte < byte
Definition: byte.hh:366
void init()
set global 'init_was_called' to true
Definition: init.cc:26
Fstring()
Default Constructor.
Definition: Fstring.hh:79
std::ostream & operator<<(std::ostream &stream, CArray< T > const &a)
stream << CArray
Definition: CArray.io.hh:33
static T max(T x, T y)
Definition: Svm.cc:19
Fstring & uppercase()
Uppercase.
Definition: Fstring.cc:880
char const SPACE( ' ')
bool operator==(byte const &i, byte const &j)
byte == byte
Definition: byte.hh:346
Fstring & lowercase()
Lowercase.
Definition: Fstring.cc:869
Fsubstring const head() const
Space-Free Head Constant Substring.
Definition: Fstring.cc:1541
Fstring & strip()
Strip Space from an Fstring's Tails.
Definition: Fstring.cc:1026
char * str_
String.
Definition: Fstring.hh:1697
size_type trimmed_whitespace_range(size_type &b, size_type &e) const
Get Range of Whitespace-Trimmed Portion and Return its Length.
Definition: Fstring.cc:515
std::string const WHITESPACE(" \t\0", 3)
size_type len_trim_whitespace() const
Length Whitespace-Trimmed.
Definition: Fstring.cc:455