diff options
Diffstat (limited to '')
-rw-r--r-- | src/fstring.cpp | 11 | ||||
-rw-r--r-- | src/fstring.h | 174 | ||||
-rw-r--r-- | src/hash.cpp | 82 | ||||
-rw-r--r-- | src/hash.h | 37 | ||||
-rw-r--r-- | src/tests/fstring.cpp | 10 |
5 files changed, 186 insertions, 128 deletions
diff --git a/src/fstring.cpp b/src/fstring.cpp index 8fe2941..82d024d 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp | |||
@@ -1,2 +1,13 @@ | |||
1 | #include "fstring.h" | 1 | #include "fstring.h" |
2 | #include "hash.h" | ||
3 | |||
4 | template<> uint32_t __calcHashCode<FString>( const FString &k ) | ||
5 | { | ||
6 | return __calcHashCode( k.c_str() ); | ||
7 | } | ||
8 | |||
9 | template<> bool __cmpHashKeys<FString>( const FString &a, const FString &b ) | ||
10 | { | ||
11 | return a == b; | ||
12 | } | ||
2 | 13 | ||
diff --git a/src/fstring.h b/src/fstring.h index db54cdd..95ba382 100644 --- a/src/fstring.h +++ b/src/fstring.h | |||
@@ -13,7 +13,15 @@ struct FStringChunk | |||
13 | }; | 13 | }; |
14 | 14 | ||
15 | /** | 15 | /** |
16 | * | 16 | * Flexible String class. This class was designed with string passing and |
17 | * generation in mind. Like the standard string class you can specify what | ||
18 | * datatype to use for each character. Unlike the standard string class, | ||
19 | * collection of appended and prepended terms is done lazily, making long | ||
20 | * operations that involve many appends very inexpensive. In addition internal | ||
21 | * ref-counting means that if you pass strings around between functions there's | ||
22 | * almost no overhead in time or memory since a reference is created and no | ||
23 | * data is actually copied. This also means that you never need to put any | ||
24 | * FBasicString into a ref-counting container class. | ||
17 | */ | 25 | */ |
18 | template< typename chr=char, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > > | 26 | template< typename chr=char, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > > |
19 | class FBasicString | 27 | class FBasicString |
@@ -49,6 +57,7 @@ public: | |||
49 | append( pData, nLength ); | 57 | append( pData, nLength ); |
50 | } | 58 | } |
51 | 59 | ||
60 | /* | ||
52 | FBasicString( MyType &rSrc ) : | 61 | FBasicString( MyType &rSrc ) : |
53 | nLength( 0 ), | 62 | nLength( 0 ), |
54 | pnRefs( NULL ), | 63 | pnRefs( NULL ), |
@@ -56,9 +65,9 @@ public: | |||
56 | pLast( NULL ) | 65 | pLast( NULL ) |
57 | { | 66 | { |
58 | joinShare( rSrc ); | 67 | joinShare( rSrc ); |
59 | } | 68 | }*/ |
60 | 69 | ||
61 | FBasicString( const FBasicString<chr, chralloc, chunkalloc> &rSrc ) : | 70 | FBasicString( const MyType &rSrc ) : |
62 | nLength( 0 ), | 71 | nLength( 0 ), |
63 | pnRefs( NULL ), | 72 | pnRefs( NULL ), |
64 | pFirst( NULL ), | 73 | pFirst( NULL ), |
@@ -68,7 +77,8 @@ public: | |||
68 | // In the case that the source were flat, we could get a reference, it | 77 | // In the case that the source were flat, we could get a reference, it |
69 | // would make some things faster, but not matter in many other cases. | 78 | // would make some things faster, but not matter in many other cases. |
70 | 79 | ||
71 | copyFrom( rSrc ); | 80 | joinShare( rSrc ); |
81 | //copyFrom( rSrc ); | ||
72 | } | 82 | } |
73 | 83 | ||
74 | virtual ~FBasicString() | 84 | virtual ~FBasicString() |
@@ -118,28 +128,7 @@ public: | |||
118 | 128 | ||
119 | void clear() | 129 | void clear() |
120 | { | 130 | { |
121 | if( pFirst == NULL ) | 131 | realClear(); |
122 | return; | ||
123 | |||
124 | if( isShared() ) | ||
125 | { | ||
126 | decRefs(); | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | Chunk *i = pFirst; | ||
131 | for(;;) | ||
132 | { | ||
133 | Chunk *n = i->pNext; | ||
134 | aChr.deallocate( i->pData, i->nLength+1 ); | ||
135 | aChunk.deallocate( i, 1 ); | ||
136 | if( n == NULL ) | ||
137 | break; | ||
138 | i = n; | ||
139 | } | ||
140 | pFirst = pLast = NULL; | ||
141 | nLength = 0; | ||
142 | } | ||
143 | } | 132 | } |
144 | 133 | ||
145 | chr *c_str() | 134 | chr *c_str() |
@@ -150,6 +139,15 @@ public: | |||
150 | flatten(); | 139 | flatten(); |
151 | return pFirst->pData; | 140 | return pFirst->pData; |
152 | } | 141 | } |
142 | |||
143 | const chr *c_str() const | ||
144 | { | ||
145 | if( pFirst == NULL ) | ||
146 | return NULL; | ||
147 | |||
148 | flatten(); | ||
149 | return pFirst->pData; | ||
150 | } | ||
153 | 151 | ||
154 | MyType &operator +=( const chr *pData ) | 152 | MyType &operator +=( const chr *pData ) |
155 | { | 153 | { |
@@ -168,26 +166,20 @@ public: | |||
168 | 166 | ||
169 | MyType &operator =( const MyType &rSrc ) | 167 | MyType &operator =( const MyType &rSrc ) |
170 | { | 168 | { |
171 | if( rSrc.isFlat() ) | 169 | //if( rSrc.isFlat() ) |
172 | { | 170 | //{ |
173 | joinShare( rSrc ); | 171 | joinShare( rSrc ); |
174 | } | 172 | //} |
175 | else | 173 | //else |
176 | { | 174 | //{ |
177 | copyFrom( rSrc ); | 175 | // copyFrom( rSrc ); |
178 | } | 176 | //} |
177 | // | ||
179 | 178 | ||
180 | return (*this); | 179 | return (*this); |
181 | } | 180 | } |
182 | 181 | ||
183 | MyType &operator =( MyType &rSrc ) | 182 | bool operator ==( const chr *pData ) const |
184 | { | ||
185 | joinShare( rSrc ); | ||
186 | |||
187 | return (*this); | ||
188 | } | ||
189 | |||
190 | bool operator ==( const chr *pData ) | ||
191 | { | 183 | { |
192 | if( pFirst == NULL ) { | 184 | if( pFirst == NULL ) { |
193 | if( pData == NULL ) | 185 | if( pData == NULL ) |
@@ -206,8 +198,33 @@ public: | |||
206 | 198 | ||
207 | return true; | 199 | return true; |
208 | } | 200 | } |
201 | |||
202 | bool operator ==( const MyType &pData ) const | ||
203 | { | ||
204 | if( pFirst == pData.pFirst ) | ||
205 | return true; | ||
206 | if( pFirst == NULL ) | ||
207 | return false; | ||
208 | |||
209 | flatten(); | ||
210 | pData.flatten(); | ||
211 | const chr *a = pData.pFirst->pData; | ||
212 | chr *b = pFirst->pData; | ||
213 | for( ; *a!=(chr)0; a++, b++ ) | ||
214 | { | ||
215 | if( *a != *b ) | ||
216 | return false; | ||
217 | } | ||
218 | |||
219 | return true; | ||
220 | } | ||
209 | 221 | ||
210 | bool operator !=(const chr *pData ) | 222 | bool operator !=(const chr *pData ) const |
223 | { | ||
224 | return !(*this == pData); | ||
225 | } | ||
226 | |||
227 | bool operator !=(const MyType &pData ) const | ||
211 | { | 228 | { |
212 | return !(*this == pData); | 229 | return !(*this == pData); |
213 | } | 230 | } |
@@ -218,9 +235,16 @@ public: | |||
218 | 235 | ||
219 | return pFirst->pData[nIndex]; | 236 | return pFirst->pData[nIndex]; |
220 | } | 237 | } |
238 | |||
239 | const chr &operator[]( long nIndex ) const | ||
240 | { | ||
241 | flatten(); | ||
242 | |||
243 | return pFirst->pData[nIndex]; | ||
244 | } | ||
221 | 245 | ||
222 | private: | 246 | private: |
223 | void flatten() | 247 | void flatten() const |
224 | { | 248 | { |
225 | if( isFlat() ) | 249 | if( isFlat() ) |
226 | return; | 250 | return; |
@@ -241,9 +265,36 @@ private: | |||
241 | if( i == NULL ) | 265 | if( i == NULL ) |
242 | break; | 266 | break; |
243 | } | 267 | } |
244 | clear(); | 268 | realClear(); |
245 | 269 | ||
246 | appendChunk( pNew ); | 270 | pLast = pFirst = pNew; |
271 | nLength = pNew->nLength; | ||
272 | } | ||
273 | |||
274 | void realClear() const | ||
275 | { | ||
276 | if( pFirst == NULL ) | ||
277 | return; | ||
278 | |||
279 | if( isShared() ) | ||
280 | { | ||
281 | decRefs(); | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | Chunk *i = pFirst; | ||
286 | for(;;) | ||
287 | { | ||
288 | Chunk *n = i->pNext; | ||
289 | aChr.deallocate( i->pData, i->nLength+1 ); | ||
290 | aChunk.deallocate( i, 1 ); | ||
291 | if( n == NULL ) | ||
292 | break; | ||
293 | i = n; | ||
294 | } | ||
295 | pFirst = pLast = NULL; | ||
296 | nLength = 0; | ||
297 | } | ||
247 | } | 298 | } |
248 | 299 | ||
249 | void copyFrom( const FBasicString<chr, chralloc, chunkalloc> &rSrc ) | 300 | void copyFrom( const FBasicString<chr, chralloc, chunkalloc> &rSrc ) |
@@ -279,14 +330,14 @@ private: | |||
279 | return (pnRefs != NULL); | 330 | return (pnRefs != NULL); |
280 | } | 331 | } |
281 | 332 | ||
282 | Chunk *newChunk() | 333 | Chunk *newChunk() const |
283 | { | 334 | { |
284 | Chunk *pNew = aChunk.allocate( 1 ); | 335 | Chunk *pNew = aChunk.allocate( 1 ); |
285 | pNew->pNext = NULL; | 336 | pNew->pNext = NULL; |
286 | return pNew; | 337 | return pNew; |
287 | } | 338 | } |
288 | 339 | ||
289 | Chunk *newChunk( long nLen ) | 340 | Chunk *newChunk( long nLen ) const |
290 | { | 341 | { |
291 | Chunk *pNew = aChunk.allocate( 1 ); | 342 | Chunk *pNew = aChunk.allocate( 1 ); |
292 | pNew->pNext = NULL; | 343 | pNew->pNext = NULL; |
@@ -365,7 +416,7 @@ private: | |||
365 | * that was being shared so that this copy can be changed. This should be | 416 | * that was being shared so that this copy can be changed. This should be |
366 | * added before any call that will change this object; | 417 | * added before any call that will change this object; |
367 | */ | 418 | */ |
368 | void unShare() | 419 | void unShare() const |
369 | { | 420 | { |
370 | if( isShared() == false ) | 421 | if( isShared() == false ) |
371 | return; | 422 | return; |
@@ -382,8 +433,8 @@ private: | |||
382 | break; | 433 | break; |
383 | } | 434 | } |
384 | decRefs(); | 435 | decRefs(); |
385 | appendChunk( pNew ); | 436 | pLast = pFirst = pNew; |
386 | decRefs(); | 437 | nLength = pNew->nLength; |
387 | } | 438 | } |
388 | 439 | ||
389 | /** | 440 | /** |
@@ -391,7 +442,7 @@ private: | |||
391 | * count hits zero because of this, it destroys the share. This is not | 442 | * count hits zero because of this, it destroys the share. This is not |
392 | * safe to call on it's own, it's much better to call unShare. | 443 | * safe to call on it's own, it's much better to call unShare. |
393 | */ | 444 | */ |
394 | void decRefs() | 445 | void decRefs() const |
395 | { | 446 | { |
396 | if( isShared() ) | 447 | if( isShared() ) |
397 | { | 448 | { |
@@ -414,14 +465,14 @@ private: | |||
414 | * itself. This should only be called when the refcount for the share has | 465 | * itself. This should only be called when the refcount for the share has |
415 | * or is about to reach zero. | 466 | * or is about to reach zero. |
416 | */ | 467 | */ |
417 | void destroyShare() | 468 | void destroyShare() const |
418 | { | 469 | { |
419 | delete pnRefs; | 470 | delete pnRefs; |
420 | pnRefs = NULL; | 471 | pnRefs = NULL; |
421 | clear(); | 472 | realClear(); |
422 | } | 473 | } |
423 | 474 | ||
424 | void cpy( chr *dest, const chr *src, long count ) | 475 | void cpy( chr *dest, const chr *src, long count ) const |
425 | { | 476 | { |
426 | for( int j = 0; j < count; j++ ) | 477 | for( int j = 0; j < count; j++ ) |
427 | { | 478 | { |
@@ -441,15 +492,20 @@ private: | |||
441 | } | 492 | } |
442 | 493 | ||
443 | private: | 494 | private: |
444 | long nLength; | 495 | mutable long nLength; |
445 | mutable uint32_t *pnRefs; | 496 | mutable uint32_t *pnRefs; |
446 | Chunk *pFirst; | 497 | mutable Chunk *pFirst; |
447 | Chunk *pLast; | 498 | mutable Chunk *pLast; |
448 | 499 | ||
449 | chralloc aChr; | 500 | mutable chralloc aChr; |
450 | chunkalloc aChunk; | 501 | mutable chunkalloc aChunk; |
451 | }; | 502 | }; |
452 | 503 | ||
453 | typedef FBasicString<char> FString; | 504 | typedef FBasicString<char> FString; |
454 | 505 | ||
506 | #include "hash.h" | ||
507 | template<> uint32_t __calcHashCode<FString>( const FString &k ); | ||
508 | template<> bool __cmpHashKeys<FString>( const FString &a, const FString &b ); | ||
509 | |||
510 | |||
455 | #endif | 511 | #endif |
diff --git a/src/hash.cpp b/src/hash.cpp index d428dd6..004d6dd 100644 --- a/src/hash.cpp +++ b/src/hash.cpp | |||
@@ -2,48 +2,57 @@ | |||
2 | 2 | ||
3 | subExceptionDef( HashException ) | 3 | subExceptionDef( HashException ) |
4 | 4 | ||
5 | template<> uint32_t __calcHashCode<const int>( const int k ) | 5 | template<> uint32_t __calcHashCode<int>( const int &k ) |
6 | { | 6 | { |
7 | return k; | 7 | return k; |
8 | } | 8 | } |
9 | 9 | ||
10 | template<> bool __cmpHashKeys<const int>( const int a, const int b ) | 10 | template<> bool __cmpHashKeys<int>( const int &a, const int &b ) |
11 | { | 11 | { |
12 | return a == b; | 12 | return a == b; |
13 | } | 13 | } |
14 | 14 | ||
15 | template<> uint32_t __calcHashCode<int>( int k ) | 15 | template<> uint32_t __calcHashCode<unsigned int>( const unsigned int &k ) |
16 | { | 16 | { |
17 | return k; | 17 | return k; |
18 | } | 18 | } |
19 | 19 | ||
20 | template<> bool __cmpHashKeys<int>( int a, int b ) | 20 | template<> bool __cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b ) |
21 | { | 21 | { |
22 | return a == b; | 22 | return a == b; |
23 | } | 23 | } |
24 | 24 | ||
25 | template<> uint32_t __calcHashCode<const unsigned int>( const unsigned int k ) | 25 | template<> |
26 | uint32_t __calcHashCode<const char *>( const char * const &k ) | ||
26 | { | 27 | { |
27 | return k; | 28 | if (k == NULL) |
28 | } | 29 | { |
30 | return 0; | ||
31 | } | ||
32 | |||
33 | unsigned long int nPos = 0; | ||
34 | for( const char *s = k; *s; s++ ) | ||
35 | { | ||
36 | nPos = *s + (nPos << 6) + (nPos << 16) - nPos; | ||
37 | } | ||
29 | 38 | ||
30 | template<> bool __cmpHashKeys<const unsigned int>( const unsigned int a, const unsigned int b ) | 39 | return nPos; |
31 | { | ||
32 | return a == b; | ||
33 | } | 40 | } |
34 | 41 | ||
35 | template<> uint32_t __calcHashCode<unsigned int>( unsigned int k ) | 42 | template<> bool __cmpHashKeys<const char *>( const char * const &a, const char * const &b ) |
36 | { | 43 | { |
37 | return k; | 44 | if( a == b ) |
38 | } | 45 | return true; |
39 | 46 | ||
40 | template<> bool __cmpHashKeys<unsigned int>( unsigned int a, unsigned int b ) | 47 | for(int j=0; a[j] == b[j]; j++ ) |
41 | { | 48 | if( *a == '\0' ) |
42 | return a == b; | 49 | return true; |
50 | |||
51 | return false; | ||
43 | } | 52 | } |
44 | 53 | ||
45 | template<> | 54 | template<> |
46 | uint32_t __calcHashCode<const char *>( const char * k ) | 55 | uint32_t __calcHashCode<char *>( char * const &k ) |
47 | { | 56 | { |
48 | if (k == NULL) | 57 | if (k == NULL) |
49 | { | 58 | { |
@@ -59,30 +68,19 @@ uint32_t __calcHashCode<const char *>( const char * k ) | |||
59 | return nPos; | 68 | return nPos; |
60 | } | 69 | } |
61 | 70 | ||
62 | template<> bool __cmpHashKeys<const char *>( const char *a, const char *b ) | 71 | template<> bool __cmpHashKeys<char *>( char * const &a, char * const &b ) |
63 | { | 72 | { |
64 | if( a == b ) | 73 | if( a == b ) |
65 | return true; | 74 | return true; |
66 | 75 | ||
67 | for(; *a == *b; a++, b++ ) | 76 | for(int j=0; a[j] == b[j]; j++ ) |
68 | if( *a == '\0' ) | 77 | if( *a == '\0' ) |
69 | return true; | 78 | return true; |
70 | 79 | ||
71 | return false; | 80 | return false; |
72 | } | 81 | } |
73 | 82 | ||
74 | template<> | 83 | template<> uint32_t __calcHashCode<std::string>( const std::string &k ) |
75 | uint32_t __calcHashCode<char *>( char *k ) | ||
76 | { | ||
77 | return __calcHashCode<const char *>((const char *)k ); | ||
78 | } | ||
79 | |||
80 | template<> bool __cmpHashKeys<char *>( char *a, char *b ) | ||
81 | { | ||
82 | return __cmpHashKeys<const char *>((const char *)a, (const char *)b ); | ||
83 | } | ||
84 | |||
85 | template<> uint32_t __calcHashCode<const std::string>( const std::string k ) | ||
86 | { | 84 | { |
87 | std::string::size_type j, sz = k.size(); | 85 | std::string::size_type j, sz = k.size(); |
88 | const char *s = k.c_str(); | 86 | const char *s = k.c_str(); |
@@ -96,28 +94,20 @@ template<> uint32_t __calcHashCode<const std::string>( const std::string k ) | |||
96 | return nPos; | 94 | return nPos; |
97 | } | 95 | } |
98 | 96 | ||
99 | template<> bool __cmpHashKeys<const std::string>( const std::string a, const std::string b ) | 97 | template<> bool __cmpHashKeys<std::string>( const std::string &a, const std::string &b ) |
100 | { | 98 | { |
101 | return a == b; | 99 | return a == b; |
102 | } | 100 | } |
103 | 101 | ||
104 | template<> uint32_t __calcHashCode<std::string>( std::string k ) | 102 | template<> uint32_t __calcHashCode<Hashable>( const Hashable &k ) |
105 | { | ||
106 | return __calcHashCode<const std::string>( k ); | ||
107 | } | ||
108 | |||
109 | template<> bool __cmpHashKeys<std::string>( std::string a, std::string b ) | ||
110 | { | 103 | { |
111 | return __cmpHashKeys<const std::string>( a, b ); | 104 | return 0; |
105 | //return k.getHashCode(); | ||
112 | } | 106 | } |
113 | 107 | ||
114 | template<> uint32_t __calcHashCode<Hashable &>( Hashable &k ) | 108 | template<> bool __cmpHashKeys<Hashable>( const Hashable &a, const Hashable &b ) |
115 | { | 109 | { |
116 | return k.getHashCode(); | 110 | return false; |
117 | } | 111 | //return a.compareForHash( b ); |
118 | |||
119 | template<> bool __cmpHashKeys<Hashable &>( Hashable &a, Hashable &b ) | ||
120 | { | ||
121 | return a.compareForHash( b ); | ||
122 | } | 112 | } |
123 | 113 | ||
@@ -18,10 +18,10 @@ enum eHashException | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | template<typename T> | 20 | template<typename T> |
21 | uint32_t __calcHashCode( T k ); | 21 | uint32_t __calcHashCode( const T &k ); |
22 | 22 | ||
23 | template<typename T> | 23 | template<typename T> |
24 | bool __cmpHashKeys( T a, T b ); | 24 | bool __cmpHashKeys( const T &a, const T &b ); |
25 | 25 | ||
26 | struct __calcNextTSize_fast | 26 | struct __calcNextTSize_fast |
27 | { | 27 | { |
@@ -649,31 +649,22 @@ protected: | |||
649 | sizecalc szCalc; | 649 | sizecalc szCalc; |
650 | }; | 650 | }; |
651 | 651 | ||
652 | template<> uint32_t __calcHashCode<const int>( const int k ); | 652 | template<> uint32_t __calcHashCode<int>( const int &k ); |
653 | template<> bool __cmpHashKeys<const int>( const int a, const int b ); | 653 | template<> bool __cmpHashKeys<int>( const int &a, const int &b ); |
654 | 654 | ||
655 | template<> uint32_t __calcHashCode<int>( int k ); | 655 | template<> uint32_t __calcHashCode<unsigned int>( const unsigned int &k ); |
656 | template<> bool __cmpHashKeys<int>( int a, int b ); | 656 | template<> bool __cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b ); |
657 | 657 | ||
658 | template<> uint32_t __calcHashCode<const unsigned int>( const unsigned int k ); | 658 | template<> uint32_t __calcHashCode<const char *>( const char * const &k ); |
659 | template<> bool __cmpHashKeys<const unsigned int>( const unsigned int a, const unsigned int b ); | 659 | template<> bool __cmpHashKeys<const char *>( const char * const &a, const char * const &b ); |
660 | 660 | ||
661 | template<> uint32_t __calcHashCode<unsigned int>( unsigned int k ); | 661 | template<> uint32_t __calcHashCode<char *>( char * const &k ); |
662 | template<> bool __cmpHashKeys<unsigned int>( unsigned int a, unsigned int b ); | 662 | template<> bool __cmpHashKeys<char *>( char * const &a, char * const &b ); |
663 | 663 | ||
664 | template<> uint32_t __calcHashCode<const char *>( const char *k ); | 664 | template<> uint32_t __calcHashCode<std::string>( const std::string &k ); |
665 | template<> bool __cmpHashKeys<const char *>( const char *a, const char *b ); | 665 | template<> bool __cmpHashKeys<std::string>( const std::string &a, const std::string &b ); |
666 | 666 | ||
667 | template<> uint32_t __calcHashCode<char *>( char *k ); | 667 | template<> uint32_t __calcHashCode<Hashable>( const Hashable &k ); |
668 | template<> bool __cmpHashKeys<char *>( char *a, char *b ); | 668 | template<> bool __cmpHashKeys<Hashable>( const Hashable &a, const Hashable &b ); |
669 | |||
670 | template<> uint32_t __calcHashCode<const std::string>( const std::string k ); | ||
671 | template<> bool __cmpHashKeys<const std::string>( const std::string a, const std::string b ); | ||
672 | |||
673 | template<> uint32_t __calcHashCode<std::string>( std::string k ); | ||
674 | template<> bool __cmpHashKeys<std::string>( std::string a, std::string b ); | ||
675 | |||
676 | template<> uint32_t __calcHashCode<Hashable &>( Hashable &k ); | ||
677 | template<> bool __cmpHashKeys<Hashable &>( Hashable &a, Hashable &b ); | ||
678 | 669 | ||
679 | #endif | 670 | #endif |
diff --git a/src/tests/fstring.cpp b/src/tests/fstring.cpp index cb85282..33e24b4 100644 --- a/src/tests/fstring.cpp +++ b/src/tests/fstring.cpp | |||
@@ -1,3 +1,4 @@ | |||
1 | #include "hash.h" | ||
1 | #include "fstring.h" | 2 | #include "fstring.h" |
2 | 3 | ||
3 | FString genThing() | 4 | FString genThing() |
@@ -11,6 +12,11 @@ FString genThing() | |||
11 | return bob; | 12 | return bob; |
12 | } | 13 | } |
13 | 14 | ||
15 | void thing( FString str ) | ||
16 | { | ||
17 | printf("Hey: %s\n", str.c_str() ); | ||
18 | } | ||
19 | |||
14 | #define pem printf("---------\n%08X: %s\n%08X: %s\n", (unsigned int)str.c_str(), str.c_str(), (unsigned int)str2.c_str(), str2.c_str() ); | 20 | #define pem printf("---------\n%08X: %s\n%08X: %s\n", (unsigned int)str.c_str(), str.c_str(), (unsigned int)str2.c_str(), str2.c_str() ); |
15 | int main( int argc, char *argv ) | 21 | int main( int argc, char *argv ) |
16 | { | 22 | { |
@@ -33,5 +39,9 @@ int main( int argc, char *argv ) | |||
33 | 39 | ||
34 | str = str2; | 40 | str = str2; |
35 | pem; | 41 | pem; |
42 | |||
43 | thing( str2 ); | ||
44 | |||
45 | printf("%d == %d\n", __calcHashCode( str ), __calcHashCode( str.c_str() ) ); | ||
36 | } | 46 | } |
37 | 47 | ||