summaryrefslogtreecommitdiff
path: root/src/stable/string.h
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2012-03-25 20:00:08 +0000
committerMike Buland <eichlan@xagasoft.com>2012-03-25 20:00:08 +0000
commit469bbcf0701e1eb8a6670c23145b0da87357e178 (patch)
treeb5b062a16e46a6c5d3410b4e574cd0cc09057211 /src/stable/string.h
parentee1b79396076edc4e30aefb285fada03bb45e80d (diff)
downloadlibbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.gz
libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.bz2
libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.xz
libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.zip
Code is all reorganized. We're about ready to release. I should write up a
little explenation of the arrangement.
Diffstat (limited to 'src/stable/string.h')
-rw-r--r--src/stable/string.h1053
1 files changed, 1053 insertions, 0 deletions
diff --git a/src/stable/string.h b/src/stable/string.h
new file mode 100644
index 0000000..a9006d1
--- /dev/null
+++ b/src/stable/string.h
@@ -0,0 +1,1053 @@
1/*
2 * Copyright (C) 2007-2011 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_STRING_H
9#define BU_STRING_H
10
11#include <stdint.h>
12#include <memory>
13
14#include "bu/util.h"
15#include "bu/sharedcore.h"
16#include "bu/exceptionbase.h"
17#include "bu/archivebase.h"
18#include "bu/list.h"
19#include "bu/fmt.h"
20#include "bu/variant.h"
21#include <string.h>
22
23namespace Bu
24{
25 class String;
26 class MemBuf;
27
28 /** @cond DEVEL */
29 class StringCore
30 {
31 friend class String;
32 friend class SharedCore<String, StringCore>;
33 private:
34 struct Chunk
35 {
36 long nLength;
37 char *pData;
38 Chunk *pNext;
39 };
40
41 StringCore();
42 StringCore( const StringCore &rSrc );
43 virtual ~StringCore();
44
45 mutable long nLength;
46 mutable Chunk *pFirst;
47 mutable Chunk *pLast;
48
49 void clear() const;
50 Chunk *newChunk() const;
51 Chunk *newChunk( long nLen ) const;
52 Chunk *copyChunk( Chunk *pSrc ) const;
53 void appendChunk( Chunk *pNewChunk );
54 void prependChunk( Chunk *pNewChunk );
55 };
56 /** @endcond */
57
58 /**
59 */
60 class String : public SharedCore<String, StringCore>
61 {
62 protected:
63 using SharedCore<String, StringCore >::core;
64 using SharedCore<String, StringCore >::_hardCopy;
65
66 private:
67 typedef StringCore::Chunk Chunk;
68
69 public: // Iterators
70 struct iterator;
71 typedef struct const_iterator
72 {
73 friend class String;
74 friend struct iterator;
75 private:
76 const_iterator( Chunk *pChunk, int iPos ) :
77 pChunk( pChunk ),
78 iPos( iPos )
79 {
80 }
81
82 Chunk *pChunk;
83 int iPos;
84
85 public:
86 const_iterator( const const_iterator &i ) :
87 pChunk( i.pChunk ),
88 iPos( i.iPos )
89 {
90 }
91
92 const_iterator( const struct iterator &i ) :
93 pChunk( i.pChunk ),
94 iPos( i.iPos )
95 {
96 }
97
98 const_iterator() :
99 pChunk( NULL ),
100 iPos( 0 )
101 {
102 }
103
104 bool operator==( const const_iterator &i ) const
105 {
106 return pChunk == i.pChunk && iPos == i.iPos;
107 }
108
109 bool operator!=( const const_iterator &i ) const
110 {
111 return !(*this == i);
112 }
113
114 const_iterator &operator=( const const_iterator &i )
115 {
116 pChunk = i.pChunk;
117 iPos = i.iPos;
118 return *this;
119 }
120
121 const_iterator &operator=( const iterator &i )
122 {
123 pChunk = i.pChunk;
124 iPos = i.iPos;
125 return *this;
126 }
127
128 const_iterator &operator++()
129 {
130 if( !pChunk ) return *this;
131 iPos++;
132 if( iPos >= pChunk->nLength )
133 {
134 iPos = 0;
135 pChunk = pChunk->pNext;
136 }
137 return *this;
138 }
139
140 const_iterator &operator++( int )
141 {
142 if( !pChunk ) return *this;
143 iPos++;
144 if( iPos >= pChunk->nLength )
145 {
146 iPos = 0;
147 pChunk = pChunk->pNext;
148 }
149 return *this;
150 }
151
152 const_iterator &operator+=( int iAmnt )
153 {
154 if( !pChunk ) return *this;
155 iPos += iAmnt;
156 while( iPos >= pChunk->nLength )
157 {
158 iPos -= pChunk->nLength;
159 pChunk = pChunk->pNext;
160 if( pChunk == NULL )
161 break;
162 }
163 return *this;
164 }
165
166 const_iterator operator+( int iAmnt ) const
167 {
168 if( !pChunk ) return *this;
169 const_iterator ret( *this );
170 ret += iAmnt;
171 return ret;
172 }
173
174 const char &operator *() const
175 {
176 if( !pChunk ) throw Bu::ExceptionBase("Not a valid const_iterator.");
177 return pChunk->pData[iPos];
178 }
179
180 bool operator==( const char &c ) const
181 {
182 if( !pChunk ) return false;
183 return pChunk->pData[iPos] == c;
184 }
185
186 bool operator!=( const char &c ) const
187 {
188 if( !pChunk ) return false;
189 return pChunk->pData[iPos] != c;
190 }
191
192 operator bool() const
193 {
194 return pChunk != NULL;
195 }
196
197 bool isValid() const
198 {
199 return pChunk != NULL;
200 }
201
202 bool compare( const const_iterator &c ) const
203 {
204 const_iterator a = *this;
205 const_iterator b = c;
206 if( a == b )
207 return true;
208 for(; a && b; a++, b++ )
209 {
210 if( *a != *b )
211 return false;
212 }
213 if( (bool)a != (bool)b )
214 return false;
215 return true;
216 }
217
218 bool compare( const const_iterator &c, int nLen ) const
219 {
220 const_iterator a = *this;
221 const_iterator b = c;
222 if( a == b )
223 return true;
224 for(int j = 0; j < nLen; a++, b++, j++ )
225 {
226 if( !a || !b || *a != *b )
227 return false;
228 }
229 return true;
230 }
231
232 bool compare( const char *c ) const
233 {
234 if( !pChunk ) return false;
235 const_iterator a = *this;
236 for(; a && *c; a++, c++ )
237 {
238 if( *a != *c )
239 return false;
240 }
241 if( a.isValid() != (*c!=(char)0) )
242 return false;
243 return true;
244 }
245
246 bool compare( const char *c, int nLen ) const
247 {
248 if( !pChunk ) return false;
249 const_iterator a = *this;
250 int j = 0;
251 for(; a && j < nLen; a++, c++, j++ )
252 {
253 if( *a != *c )
254 return false;
255 }
256 if( j < nLen )
257 return false;
258 return true;
259 }
260
261 bool compare( const String &s ) const
262 {
263 if( !pChunk ) return false;
264 return compare( s.begin() );
265 }
266
267 bool compare( const String &s, int nLen ) const
268 {
269 if( !pChunk ) return false;
270 return compare( s.begin(), nLen );
271 }
272
273 const_iterator find( const char c ) const
274 {
275 for( const_iterator i = *this; i; i++ )
276 {
277 if( *i == c )
278 return i;
279 }
280 return const_iterator( NULL, 0 );
281 }
282
283 const_iterator find( const char *pStr, int nLen ) const
284 {
285 for( const_iterator i = *this; i; i++ )
286 {
287 if( i.compare( pStr, nLen ) )
288 return i;
289 }
290 return const_iterator( NULL, 0 );
291 }
292
293 const_iterator find( const String &s ) const
294 {
295 for( const_iterator i = *this; i; i++ )
296 {
297 if( i.compare( s ) )
298 return i;
299 }
300 return const_iterator( NULL, 0 );
301 }
302
303 const_iterator find( const String &s, int nLen ) const
304 {
305 for( const_iterator i = *this; i; i++ )
306 {
307 if( i.compare( s, nLen ) )
308 return i;
309 }
310 return const_iterator( NULL, 0 );
311 }
312 } const_iterator;
313
314 typedef struct iterator
315 {
316 friend class String;
317 friend struct const_iterator;
318 private:
319 iterator( Chunk *pChunk, int iPos ) :
320 pChunk( pChunk ),
321 iPos( iPos )
322 {
323 }
324
325 Chunk *pChunk;
326 int iPos;
327
328 public:
329 iterator( const iterator &i ) :
330 pChunk( i.pChunk ),
331 iPos( i.iPos )
332 {
333 }
334
335 iterator() :
336 pChunk( NULL ),
337 iPos( 0 )
338 {
339 }
340
341 operator const_iterator() const
342 {
343 return const_iterator( pChunk, iPos );
344 }
345
346 bool operator==( const iterator &i ) const
347 {
348 return pChunk == i.pChunk && iPos == i.iPos;
349 }
350
351 bool operator!=( const iterator &i ) const
352 {
353 return !(*this == i);
354 }
355
356 iterator &operator=( const iterator &i )
357 {
358 pChunk = i.pChunk;
359 iPos = i.iPos;
360 return *this;
361 }
362
363 iterator &operator++()
364 {
365 if( !pChunk ) return *this;
366 iPos++;
367 if( iPos >= pChunk->nLength )
368 {
369 iPos = 0;
370 pChunk = pChunk->pNext;
371 }
372 return *this;
373 }
374
375 iterator &operator++( int )
376 {
377 if( !pChunk ) return *this;
378 iPos++;
379 if( iPos >= pChunk->nLength )
380 {
381 iPos = 0;
382 pChunk = pChunk->pNext;
383 }
384 return *this;
385 }
386
387 iterator &operator+=( int iAmnt )
388 {
389 if( !pChunk ) return *this;
390 iPos += iAmnt;
391 while( iPos >= pChunk->nLength )
392 {
393 iPos -= pChunk->nLength;
394 pChunk = pChunk->pNext;
395 if( pChunk == NULL )
396 break;
397 }
398 return *this;
399 }
400
401 iterator operator+( int iAmnt ) const
402 {
403 if( !pChunk ) return *this;
404 iterator ret( *this );
405 ret += iAmnt;
406 return ret;
407 }
408
409 char &operator*()
410 {
411 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
412 return pChunk->pData[iPos];
413 }
414
415 const char &operator*() const
416 {
417 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
418 return pChunk->pData[iPos];
419 }
420
421 bool operator==( const char &c ) const
422 {
423 if( !pChunk ) return false;
424 return pChunk->pData[iPos] == c;
425 }
426
427 bool operator!=( const char &c ) const
428 {
429 if( !pChunk ) return false;
430 return pChunk->pData[iPos] != c;
431 }
432
433 iterator &operator=( const char &c )
434 {
435 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
436 pChunk->pData[iPos] = c;
437 return *this;
438 }
439
440 operator bool() const
441 {
442 return pChunk != NULL;
443 }
444
445 bool isValid() const
446 {
447 return pChunk != NULL;
448 }
449
450 bool compare( const const_iterator &c ) const
451 {
452 const_iterator a( *this );
453 const_iterator b = c;
454 if( a == b )
455 return true;
456 for(; a && b; a++, b++ )
457 {
458 if( *a != *b )
459 return false;
460 }
461 if( (bool)a != (bool)b )
462 return false;
463 return true;
464 }
465
466 bool compare( const const_iterator &c, int nLen ) const
467 {
468 const_iterator a( *this );
469 const_iterator b = c;
470 if( a == b )
471 return true;
472 for(int j = 0; j < nLen; a++, b++, j++ )
473 {
474 if( !a || !b || *a != *b )
475 return false;
476 }
477 return true;
478 }
479
480 bool compare( const char *c ) const
481 {
482 if( !pChunk ) return false;
483 iterator a = *this;
484 for(; a && *c; a++, c++ )
485 {
486 if( *a != *c )
487 return false;
488 }
489 if( a.isValid() != (*c!=(char)0) )
490 return false;
491 return true;
492 }
493
494 bool compare( const char *c, int nLen ) const
495 {
496 if( !pChunk ) return false;
497 iterator a = *this;
498 int j = 0;
499 for(; a && j < nLen; a++, c++, j++ )
500 {
501 if( *a != *c )
502 return false;
503 }
504 if( j < nLen )
505 return false;
506 return true;
507 }
508
509 bool compare( const String &s ) const
510 {
511 if( !pChunk ) return false;
512 return compare( s.begin() );
513 }
514
515 bool compare( const String &s, int nLen ) const
516 {
517 if( !pChunk ) return false;
518 return compare( s.begin(), nLen );
519 }
520
521 iterator find( const char c ) const
522 {
523 for( iterator i = *this; i; i++ )
524 {
525 if( *i == c )
526 return i;
527 }
528 return iterator( NULL, 0 );
529 }
530
531 iterator find( const char *pStr, int nLen ) const
532 {
533 for( iterator i = *this; i; i++ )
534 {
535 if( i.compare( pStr, nLen ) )
536 return i;
537 }
538 return iterator( NULL, 0 );
539 }
540
541 iterator find( const String &s ) const
542 {
543 for( iterator i = *this; i; i++ )
544 {
545 if( i.compare( s ) )
546 return i;
547 }
548 return iterator( NULL, 0 );
549 }
550
551 iterator find( const String &s, int nLen ) const
552 {
553 for( iterator i = *this; i; i++ )
554 {
555 if( i.compare( s, nLen ) )
556 return i;
557 }
558 return iterator( NULL, 0 );
559 }
560 } iterator;
561
562 public:
563 String();
564 String( const char *pData );
565 String( const char *pData, long nLength );
566 String( const String &rSrc );
567 String( const String &rSrc, long nLength );
568 String( const String &rSrc, long nStart, long nLength );
569 String( long nSize );
570 String( const const_iterator &s );
571 String( const const_iterator &s, const const_iterator &e );
572 virtual ~String();
573
574 /**
575 * Append data to your string.
576 *@param pData (const char *) The data to append.
577 */
578 void append( const char *pData );
579
580 /**
581 * Append data to your string.
582 *@param pData (const char *) The data to append.
583 *@param nLen (long) The length of the data to append.
584 */
585 void append( const char *pData, long nLen );
586
587 /**
588 * Append data to your string.
589 *@param pData (const char *) The data to append.
590 *@param nStart (long) The start position to copy from.
591 *@param nLen (long) The length of the data to append.
592 */
593 void append( const char *pData, long nStart, long nLen );
594
595 /**
596 * Append a single char to your string.
597 *@param cData (const char &) The character to append.
598 */
599 void append( const char &cData );
600
601 /**
602 * Append another String to this one.
603 *@param sData (String &) The String to append.
604 *@todo This function can be made much faster by not using getStr()
605 */
606 void append( const String & sData );
607
608 /**
609 * Append another String to this one.
610 *@param sData (String &) The String to append.
611 *@param nLen How much data to append.
612 *@todo This function can be made much faster by not using getStr()
613 */
614 void append( const String & sData, long nLen );
615
616 /**
617 * Append another String to this one.
618 *@param sData (String &) The String to append.
619 *@param nStart Start position in sData to start copying from.
620 *@param nLen How much data to append.
621 *@todo This function can be made much faster by not using getStr()
622 */
623 void append( const String & sData, long nStart, long nLen );
624
625 /**
626 * Append data to this String using the passed in iterator as a base.
627 * The iterator is const, it is not changed.
628 *@param s Iterator from any compatible String to copy data from.
629 */
630 void append( const const_iterator &s );
631
632 /**
633 * Append data to this String using the passed in iterator as a base.
634 * The iterator is const, it is not changed.
635 *@param s Iterator from any compatible String to copy data from.
636 */
637 void append( const iterator &s );
638
639 /**
640 * Append data to this String using the passed in iterator as a base,
641 * and copy data until the ending iterator is reached. The character
642 * at the ending iterator is not copied.
643 * The iterators are const, they are not changed.
644 *@param s Iterator from any compatible String to copy data from.
645 *@param e Iterator to stop copying at.
646 */
647 void append( const const_iterator &s, const const_iterator &e );
648
649 /**
650 * Prepend another String to this one.
651 *@param sData (String &) The String to prepend.
652 *@todo This function can be made much faster by not using getStr()
653 */
654 void prepend( const String & sData );
655
656 /**
657 * Prepend data to your string.
658 *@param pData (const char *) The data to prepend.
659 */
660 void prepend( const char *pData );
661
662 /**
663 * Prepend data to your string.
664 *@param pData (const char *) The data to prepend.
665 *@param nLen (long) The length of the data to prepend.
666 */
667 void prepend( const char *pData, long nLen );
668
669 void prepend( const char c );
670
671 /**
672 * Insert pData before byte nPos, that is, the first byte of pData will
673 * start at nPos. This could probably be made faster by avoiding
674 * flattening.
675 */
676 void insert( long nPos, const char *pData, long nLen );
677
678 void insert( long nPos, const String &str );
679
680 /**
681 *@todo This function shouldn't use strlen, we should add our own to
682 * this class, one that can be overridden in a specific implementation.
683 */
684 void insert( long nPos, const char *pData );
685
686 void remove( long nPos, long nLen );
687
688 /**
689 * Clear all data from the string.
690 */
691 void clear();
692
693 String replace( const String &fnd, const String &rep ) const;
694
695 /**
696 * Force the string to resize
697 *@param nNewSize (long) The new size of the string.
698 */
699 void resize( long nNewSize );
700
701 /**
702 * Get the current size of the string.
703 *@returns (long) The current size of the string.
704 */
705 long getSize() const;
706
707 /**
708 * Get a pointer to the string array.
709 *@returns (char *) The string data.
710 */
711 char *getStr();
712
713 /**
714 * Get a const pointer to the string array.
715 *@returns (const char *) The string data.
716 */
717 const char *getStr() const;
718
719 /**
720 * A convinience function, this one won't cause as much work as the
721 * non-const getStr, so if you're not changing the data, consider it.
722 */
723 const char *getConstStr() const;
724
725 String getSubStrIdx( long iStart, long iSize=-1 ) const;
726
727 String getSubStr( const_iterator iBegin,
728 const_iterator iEnd=String::const_iterator() ) const;
729
730 Bu::List<String> split( const char c ) const;
731
732 /**
733 * Plus equals operator for String.
734 *@param pData (const char *) The data to append to your String.
735 */
736 String &operator+=( const char *pData );
737
738 /**
739 * Plus equals operator for String.
740 *@param rSrc (const String &) The String to append to your String.
741 */
742 String &operator+=( const String &rSrc );
743
744 String &operator+=( const String::const_iterator &i );
745
746 /**
747 * Plus equals operator for String.
748 *@param cData (const char) The character to append to your String.
749 */
750 String &operator+=( const char cData );
751
752 /**
753 * Assignment operator.
754 *@param pData (const char *) The character array to append to your
755 * String.
756 */
757 String &operator=( const char *pData );
758
759 String operator+( const String &rRight ) const;
760
761 String operator+( const char *pRight ) const;
762
763 String operator+( char *pRight ) const;
764
765 /**
766 * Reset your String to this character array.
767 *@param pData (const char *) The character array to set your String to.
768 */
769 void set( const char *pData );
770
771 /**
772 * Reset your String to this character array.
773 *@param pData (const char *) The character array to set your String to.
774 *@param nSize (long) The length of the inputted character array.
775 */
776 void set( const char *pData, long nSize );
777
778 void set( const char *pData, long nStart, long nSize );
779
780 void set( const String &rData );
781
782 void set( const String &rData, long nSize );
783
784 void set( const String &rData, long nStart, long nSize );
785
786 void set( const_iterator s );
787
788 void set( const_iterator s, const_iterator e );
789
790 /**
791 * Resize the string, possibly to make room for a copy. At the moment
792 * this operation *is* destructive. What was in the string will in no
793 * way be preserved. This is, however, very fast. If you want to
794 * keep your data check out resize.
795 *@param iSize the new size in bytes. The string is guranteed to have
796 * at least this much contiguous space available when done.
797 */
798 void setSize( long iSize );
799
800 /**
801 * Equals comparison operator.
802 *@param pData (const char *) The character array to compare your String
803 * to.
804 */
805 bool operator==( const char *pData ) const;
806
807 /**
808 * Equals comparison operator.
809 *@param pData (const String &) The String to compare your String to.
810 */
811 bool operator==( const String &pData ) const;
812
813 /**
814 * Not equals comparison operator.
815 *@param pData (const char *) The character array to compare your String
816 * to.
817 */
818 bool operator!=(const char *pData ) const;
819
820 /**
821 * Not equals comparison operator.
822 *@param pData (const String &) The String to compare your String to.
823 */
824 bool operator!=(const String &pData ) const;
825
826 bool operator<(const String &pData ) const;
827
828 bool operator<=(const String &pData ) const;
829
830 bool operator>(const String &pData ) const;
831
832 bool operator>=(const String &pData ) const;
833
834 /**
835 * Indexing operator
836 *@param nIndex (long) The index of the character you want.
837 *@returns (char &) The character at position (nIndex).
838 */
839 char &operator[]( long nIndex );
840
841 /**
842 * Const indexing operator
843 *@param nIndex (long) The index of the character you want.
844 *@returns (const char &) The character at position (nIndex).
845 */
846 const char &operator[]( long nIndex ) const;
847
848 bool isSet() const;
849
850 bool compareSub( const char *pData, long nIndex, long nLen ) const;
851
852 bool compareSub( const String &rData, long nIndex, long nLen ) const;
853
854 /**
855 * Is the character at index (nIndex) white space?
856 *@param nIndex (long) The index of the character you want to check.
857 *@returns (bool) Is it white space?
858 */
859 bool isWS( long nIndex ) const;
860
861 /**
862 * Is the character at index (nIndex) a letter?
863 *@param nIndex (long) The index of the character you want to check.
864 *@returns (bool) Is it a letter?
865 */
866 bool isAlpha( long nIndex ) const;
867
868 /**
869 * Convert your alpha characters to lower case.
870 */
871 String toLower() const;
872
873 /**
874 * Convert your alpha characters to upper case.
875 */
876 String toUpper() const;
877
878 const_iterator find( const char cChar,
879 const_iterator iStart=const_iterator() ) const;
880
881 const_iterator find( const char *sText, int nLen,
882 const_iterator iStart=const_iterator() ) const;
883
884 const_iterator find( const String &rStr,
885 const_iterator iStart=const_iterator() ) const;
886
887 const_iterator find( const String &rStr, int nLen,
888 const_iterator iStart=const_iterator() ) const;
889
890 iterator find( const char cChar,
891 const_iterator iStart=const_iterator() );
892
893 iterator find( const char *sText, int nLen,
894 const_iterator iStart=const_iterator() );
895
896 iterator find( const String &rStr,
897 const_iterator iStart=const_iterator() );
898
899 iterator find( const String &rStr, int nLen,
900 const_iterator iStart=const_iterator() );
901
902 /**
903 * Find the index of the first occurrance of cChar
904 *@param cChar The character to search for.
905 *@param iStart The position in the string to start searching from.
906 *@returns (long) The index of the first occurrance. -1 for not found.
907 */
908 long findIdx( const char cChar, long iStart=0 ) const;
909
910 /**
911 * Find the index of the first occurrance of sText
912 *@param sText The null-terminated string to search for.
913 *@param iStart The position in the string to start searching from.
914 *@returns The index of the first occurrance. -1 for not found.
915 */
916 long findIdx( const char *sText, long iStart=0 ) const;
917
918 /**
919 * Do a reverse search for (sText)
920 *@param sText (const char *) The string to search for.
921 *@returns (long) The index of the last occurrance. -1 for not found.
922 */
923 long rfindIdx( const char *sText ) const;
924
925 /**
926 * Remove nAmnt bytes from the front of the string. This function
927 * operates in O(n) time and should be used sparingly.
928 */
929 void trimFront( long nAmnt );
930
931 void trimBack( long iAmnt );
932
933 Bu::String trimWhitespace() const;
934
935 iterator begin();
936
937 const_iterator begin() const;
938
939 iterator end();
940
941 const_iterator end() const;
942
943 bool isEmpty() const;
944
945 private:
946 void flatten() const;
947 bool isFlat() const;
948
949 class FormatProxy
950 {
951 public:
952 FormatProxy( const String &rFmt );
953 virtual ~FormatProxy();
954
955 template<typename T>
956 FormatProxy &arg( const T &x )
957 {
958 lArgs.append( Arg( x ) );
959
960 return *this;
961 }
962
963 template<typename T>
964 FormatProxy &arg( const T &x, const Bu::Fmt &f )
965 {
966 lArgs.append( Arg( x, f ) );
967
968 return *this;
969 }
970
971 operator String() const;
972
973 private:
974 const String &rFmt;
975 class Arg
976 {
977 public:
978 template<typename T>
979 Arg( const T &v ) :
980 value( v )
981 {
982 }
983
984 template<typename T>
985 Arg( const T &v, const Bu::Fmt &f ) :
986 value( v ),
987 format( f )
988 {
989 }
990
991 Bu::Variant value;
992 Bu::Fmt format;
993 };
994 typedef Bu::List<Arg> ArgList;
995 ArgList lArgs;
996 };
997
998 public:
999 template<typename ArgType>
1000 FormatProxy arg( const ArgType &x )
1001 {
1002 return FormatProxy( *this ).arg( x );
1003 }
1004
1005 template<typename ArgType>
1006 FormatProxy arg( const ArgType &x, const Bu::Fmt &f )
1007 {
1008 return FormatProxy( *this ).arg( x, f );
1009 }
1010 };
1011
1012 template<class T> String operator+( const T *pLeft, const String &rRight )
1013 {
1014 Bu::String ret( pLeft );
1015 ret.append( rRight );
1016 return ret;
1017 }
1018
1019 ArchiveBase &operator<<( ArchiveBase &ar, const String &s );
1020 ArchiveBase &operator>>( ArchiveBase &ar, String &s );
1021
1022 template<typename T>
1023 uint32_t __calcHashCode( const T &k );
1024
1025 template<typename T>
1026 bool __cmpHashKeys( const T &a, const T &b );
1027
1028 template<> uint32_t __calcHashCode<String>( const String &k );
1029 template<> bool __cmpHashKeys<String>(
1030 const String &a, const String &b );
1031
1032 template<typename t> void __tracer_format( const t &v );
1033 template<> void __tracer_format<String>( const String &v );
1034
1035 bool &operator<<( bool &dst, const String &sIn );
1036 uint8_t &operator<<( uint8_t &dst, const String &sIn );
1037 int8_t &operator<<( int8_t &dst, const String &sIn );
1038 char &operator<<( char &dst, const String &sIn );
1039 uint16_t &operator<<( uint16_t &dst, const String &sIn );
1040 int16_t &operator<<( int16_t &dst, const String &sIn );
1041 uint32_t &operator<<( uint32_t &dst, const String &sIn );
1042 int32_t &operator<<( int32_t &dst, const String &sIn );
1043 uint64_t &operator<<( uint64_t &dst, const String &sIn );
1044 int64_t &operator<<( int64_t &dst, const String &sIn );
1045 float &operator<<( float &dst, const String &sIn );
1046 double &operator<<( double &dst, const String &sIn );
1047 long double &operator<<( long double &dst, const String &sIn );
1048 Bu::String &operator<<( Bu::String &dst, const String &sIn );
1049
1050 typedef Bu::List<String> StringList;
1051};
1052
1053#endif