00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00051 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR
00052 #define STLSOFT_INCL_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR
00053
00054 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define STLSOFT_VER_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR_MAJOR 4
00056 # define STLSOFT_VER_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR_MINOR 0
00057 # define STLSOFT_VER_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR_REVISION 2
00058 # define STLSOFT_VER_STLSOFT_STRING_HPP_FAST_STRING_CONCATENATOR_EDIT 134
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00077 # include <stlsoft/stlsoft.h>
00078 #endif
00079
00080 #ifndef _STLSOFT_NO_NAMESPACE
00081 namespace stlsoft
00082 {
00083 #endif
00084 template< ss_typename_param_k S
00085 , ss_typename_param_k C
00086 , ss_typename_param_k T
00087 >
00088 class fast_string_concatenator;
00089 #ifndef _STLSOFT_NO_NAMESPACE
00090 }
00091 #endif
00092
00093 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
00094 # include <stlsoft/string/char_traits.hpp>
00095 #endif
00096
00097 #ifndef STLSOFT_INCL_ALGORITHM
00098 # define STLSOFT_INCL_ALGORITHM
00099 # include <algorithm>
00100 #endif
00101
00102
00103
00104
00105
00106 #ifndef _STLSOFT_NO_NAMESPACE
00107 namespace stlsoft
00108 {
00109 #endif
00110
00111
00112
00113
00114
00120 class fsc_seed
00121 {};
00122
00123 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00124
00125 template <ss_typename_param_k S>
00126 class fsc_seed_t
00127 : public fsc_seed
00128 {
00129 public:
00130 typedef S string_type;
00131 };
00132
00133 #endif
00134
00135 #ifndef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00136 # error fast_string_concatenator cannot be used when default template arguments are not supported
00137 #endif
00138
00143 template< ss_typename_param_k S
00144 , ss_typename_param_k C = ss_typename_type_def_k S::value_type
00145 , ss_typename_param_k T = char_traits<C>
00146 >
00147 class fast_string_concatenator
00148 {
00151 public:
00152 typedef S string_type;
00153 typedef C char_type;
00154 typedef T traits_type;
00155 typedef fast_string_concatenator<S, C, T> class_type;
00156 typedef ss_size_t size_type;
00157 private:
00158 #if !defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00159 typedef ss_typename_type_k S::iterator string_iterator_type;
00160 #endif
00162
00165 public:
00166 fast_string_concatenator(string_type const& lhs, string_type const& rhs);
00167 fast_string_concatenator(string_type const& lhs, char_type const* rhs);
00168 fast_string_concatenator(string_type const& lhs, char_type const rhs);
00169 fast_string_concatenator(char_type const* lhs, string_type const& rhs);
00170 fast_string_concatenator(char_type const lhs, string_type const& rhs);
00171
00172 fast_string_concatenator(class_type const& lhs, string_type const& rhs);
00173 fast_string_concatenator(class_type const& lhs, char_type const* rhs);
00174 fast_string_concatenator(class_type const& lhs, char_type const rhs);
00175
00176 fast_string_concatenator(fsc_seed const& lhs, string_type const& rhs);
00177
00178
00179 fast_string_concatenator(class_type const& lhs, class_type const& rhs);
00180 fast_string_concatenator(string_type const& lhs, class_type const& rhs);
00181 fast_string_concatenator(char_type const* lhs, class_type const& rhs);
00182 fast_string_concatenator(char_type const lhs, class_type const& rhs);
00184
00187 public:
00188 operator string_type() const;
00190
00193 private:
00194 size_type length() const
00195 {
00196 return m_lhs.length() + m_rhs.length();
00197 }
00198 #if defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00199 char_type *write(char_type *s) const
00200 {
00201 return m_rhs.write(m_lhs.write(s));
00202 }
00203 #else
00204 string_iterator_type write(string_iterator_type s) const
00205 {
00206 return m_rhs.write(m_lhs.write(s));
00207 }
00208 #endif
00209
00210 private:
00211 struct Data;
00212
00213 friend struct Data;
00214
00215 struct Data
00216 {
00217 enum DataType
00218 {
00219 seed
00220 , single
00221 , cstring
00222 , concat
00223 };
00224
00226 struct CString
00227 {
00228 ss_size_t len;
00229 char_type const *s;
00230 };
00232 union DataRef
00233 {
00234 CString cstring;
00235 char_type ch;
00236 class_type const *concat;
00237 };
00238 Data(string_type const& str)
00239 : type(cstring)
00240 {
00241 ref.cstring.len = str.length();
00242 ref.cstring.s = str.data();
00243 }
00244 Data(char_type const* s)
00245 : type(cstring)
00246 {
00247 ref.cstring.len = traits_type::length(s);
00248 ref.cstring.s = s;
00249 }
00250 Data(char_type const ch)
00251 : type(single)
00252 {
00253 ref.ch = ch;
00254 }
00255 Data(class_type const& fc)
00256 : type(concat)
00257 {
00258 ref.concat = &fc;
00259 }
00260 Data(fsc_seed const&)
00261 : type(seed)
00262 {}
00263
00264 size_type length() const
00265 {
00266 size_type len;
00267
00268
00269
00270 STLSOFT_ASSERT(type == cstring || type == single || type == concat || type == seed);
00271
00272 switch(type)
00273 {
00274 case seed:
00275 len = 0;
00276 break;
00277 case single:
00278 len = 1;
00279 break;
00280 case cstring:
00281 len = ref.cstring.len;
00282 break;
00283 case concat:
00284 len = ref.concat->length();
00285 break;
00286 }
00287
00288 STLSOFT_ASSERT(!(len < 0));
00289
00290 return len;
00291 }
00292
00293 #if defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00294 char_type *write(char_type *s) const
00295 #else
00296 string_iterator_type write(string_iterator_type s) const
00297 #endif
00298 {
00299 size_type len;
00300
00301
00302
00303 STLSOFT_ASSERT(type == cstring || type == single || type == concat || type == seed);
00304
00305 #if defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00306
00307 STLSOFT_ASSERT(&[1]&*s == s + 1);
00308 #else
00309
00310 STLSOFT_ASSERT(&s[1] == s + 1);
00311 #endif
00312
00313 switch(type)
00314 {
00315 case seed:
00316 break;
00317 case single:
00318 *(s++) = ref.ch;
00319 break;
00320 case cstring:
00321 len = ref.cstring.len;
00322 #if defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00323 memcpy(s, ref.cstring.s, sizeof(C) * (len));
00324 #else
00325 std::copy(&ref.cstring.s[0], &ref.cstring.s[0] + len, s);
00326 #endif
00327 s += len;
00328 break;
00329 case concat:
00330 s = ref.concat->write(s);
00331 break;
00332 }
00333
00334 return s;
00335 }
00336
00337 DataRef ref;
00338 DataType const type;
00339 };
00341
00344 private:
00345 Data m_lhs;
00346 Data m_rhs;
00348
00349
00350 private:
00351 fast_string_concatenator& operator =(class_type const&);
00352 };
00353
00354
00355
00356
00357
00358 #ifdef STLSOFT_UNITTEST
00359 # include "./unittest/fast_string_concatenator_unittest_.h"
00360 #endif
00361
00362
00363
00364
00365
00366 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00367
00368 template< ss_typename_param_k S
00369 , ss_typename_param_k C
00370 , ss_typename_param_k T
00371 >
00372 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(S const& lhs, S const& rhs)
00373 : m_lhs(lhs)
00374 , m_rhs(rhs)
00375 {}
00376
00377 template< ss_typename_param_k S
00378 , ss_typename_param_k C
00379 , ss_typename_param_k T
00380 >
00381 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(S const& lhs, C const* rhs)
00382 : m_lhs(lhs)
00383 , m_rhs(rhs)
00384 {}
00385
00386 template< ss_typename_param_k S
00387 , ss_typename_param_k C
00388 , ss_typename_param_k T
00389 >
00390 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(S const& lhs, C const rhs)
00391 : m_lhs(lhs)
00392 , m_rhs(rhs)
00393 {}
00394
00395 template< ss_typename_param_k S
00396 , ss_typename_param_k C
00397 , ss_typename_param_k T
00398 >
00399 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(C const* lhs, S const& rhs)
00400 : m_lhs(lhs)
00401 , m_rhs(rhs)
00402 {}
00403
00404 template< ss_typename_param_k S
00405 , ss_typename_param_k C
00406 , ss_typename_param_k T
00407 >
00408 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(C const lhs, S const& rhs)
00409 : m_lhs(lhs)
00410 , m_rhs(rhs)
00411 {}
00412
00413 template< ss_typename_param_k S
00414 , ss_typename_param_k C
00415 , ss_typename_param_k T
00416 >
00417 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(fast_string_concatenator const& lhs, S const& rhs)
00418 : m_lhs(lhs)
00419 , m_rhs(rhs)
00420 {}
00421
00422 template< ss_typename_param_k S
00423 , ss_typename_param_k C
00424 , ss_typename_param_k T
00425 >
00426 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(fast_string_concatenator const& lhs, C const* rhs)
00427 : m_lhs(lhs)
00428 , m_rhs(rhs)
00429 {}
00430
00431 template< ss_typename_param_k S
00432 , ss_typename_param_k C
00433 , ss_typename_param_k T
00434 >
00435 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(fast_string_concatenator const& lhs, C const rhs)
00436 : m_lhs(lhs)
00437 , m_rhs(rhs)
00438 {}
00439
00440
00441 template< ss_typename_param_k S
00442 , ss_typename_param_k C
00443 , ss_typename_param_k T
00444 >
00445 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(fast_string_concatenator const& lhs, fast_string_concatenator const& rhs)
00446 : m_lhs(lhs)
00447 , m_rhs(rhs)
00448 {}
00449
00450 template< ss_typename_param_k S
00451 , ss_typename_param_k C
00452 , ss_typename_param_k T
00453 >
00454 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(S const& lhs, fast_string_concatenator const& rhs)
00455 : m_lhs(lhs)
00456 , m_rhs(rhs)
00457 {}
00458
00459 template< ss_typename_param_k S
00460 , ss_typename_param_k C
00461 , ss_typename_param_k T
00462 >
00463 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(C const* lhs, fast_string_concatenator const& rhs)
00464 : m_lhs(lhs)
00465 , m_rhs(rhs)
00466 {}
00467
00468 template< ss_typename_param_k S
00469 , ss_typename_param_k C
00470 , ss_typename_param_k T
00471 >
00472 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(C const lhs, fast_string_concatenator const& rhs)
00473 : m_lhs(lhs)
00474 , m_rhs(rhs)
00475 {}
00476
00477 template< ss_typename_param_k S
00478 , ss_typename_param_k C
00479 , ss_typename_param_k T
00480 >
00481 inline fast_string_concatenator<S, C, T>::fast_string_concatenator(fsc_seed const& lhs, S const& rhs)
00482 : m_lhs(lhs)
00483 , m_rhs(rhs)
00484 {}
00485
00486 template< ss_typename_param_k S
00487 , ss_typename_param_k C
00488 , ss_typename_param_k T
00489 >
00490 #if defined(STLSOFT_COMPILER_IS_GCC)
00491 inline fast_string_concatenator<S, C, T>::operator S() const
00492 #else
00493 inline fast_string_concatenator<S, C, T>::operator ss_typename_type_k fast_string_concatenator<S, C, T>::string_type() const
00494 #endif
00495 {
00496 size_type len = length();
00497 string_type s(len, '~');
00498 #if defined(STLSOFT_FAST_STRING_CONCATENATION_ASSUME_CONTIGUOUS_STORAGE)
00499
00500 char_type &c0 = s.operator[](0);
00501
00502
00503
00504
00505 write(&c0);
00506
00507 STLSOFT_ASSERT(s.length() == traits_type::length(&c0));
00508 #else
00509 write(s.begin());
00510
00511 STLSOFT_ASSERT(s.length() == traits_type::length(s.c_str()));
00512 #endif
00513
00514 return s;
00515 }
00516
00517 #endif
00518
00519
00520
00521
00522
00523 template< ss_typename_param_k S
00524 , ss_typename_param_k C
00525 , ss_typename_param_k T
00526 >
00527 inline fast_string_concatenator<S, C, T> operator +(fsc_seed const& lhs, S const& rhs)
00528 {
00529 return fast_string_concatenator<S, C, T>(lhs, rhs);
00530 }
00531
00532 #if 0
00533 template< ss_typename_param_k S
00534 , ss_typename_param_k C
00535 , ss_typename_param_k T
00536 >
00537 inline fast_string_concatenator<S, C, T> operator +(S const& lhs, fsc_seed const& rhs)
00538 {
00539 return fast_string_concatenator<S, C, T>(lhs, rhs);
00540 }
00541 #endif
00542
00543 template< ss_typename_param_k S
00544 , ss_typename_param_k C
00545 , ss_typename_param_k T
00546 >
00547 inline fast_string_concatenator<S, C, T> const& operator +(fsc_seed const& , fast_string_concatenator<S, C, T> const& rhs)
00548 {
00549 return rhs;
00550 }
00551
00552 #if 0
00553 template< ss_typename_param_k S
00554 , ss_typename_param_k C
00555 , ss_typename_param_k T
00556 >
00557 inline fast_string_concatenator<S, C, T> const& operator +(fast_string_concatenator<S, C, T> const& , fsc_seed const& rhs)
00558 {
00559 return rhs;
00560 }
00561 #endif
00562
00563
00564
00565
00566 #if 0
00567 template< ss_typename_param_k S
00568 , ss_typename_param_k C
00569 , ss_typename_param_k T
00570 >
00571 inline fast_string_concatenator<S, C, T> operator +(S const& lhs, S const& rhs)
00572 {
00573 return fast_string_concatenator<S, C, T>(lhs, rhs);
00574 }
00575
00576 template< ss_typename_param_k S
00577 , ss_typename_param_k C
00578 , ss_typename_param_k T
00579 >
00580 inline fast_string_concatenator<S, C, T> operator +(S const& lhs, C const* rhs)
00581 {
00582 return fast_string_concatenator<S, C, T>(lhs, rhs);
00583 }
00584
00585 template< ss_typename_param_k S
00586 , ss_typename_param_k C
00587 , ss_typename_param_k T
00588 >
00589 inline fast_string_concatenator<S, C, T> operator +(S const& lhs, C const rhs)
00590 {
00591 return fast_string_concatenator<S, C, T>(lhs, rhs);
00592 }
00593
00594 template< ss_typename_param_k S
00595 , ss_typename_param_k C
00596 , ss_typename_param_k T
00597 >
00598 inline fast_string_concatenator<S, C, T> operator +(C const* lhs, S const& rhs)
00599 {
00600 return fast_string_concatenator<S, C, T>(lhs, rhs);
00601 }
00602
00603 template< ss_typename_param_k S
00604 , ss_typename_param_k C
00605 , ss_typename_param_k T
00606 >
00607 inline fast_string_concatenator<S, C, T> operator +(C const lhs, S const& rhs)
00608 {
00609 return fast_string_concatenator<S, C, T>(lhs, rhs);
00610 }
00611 #endif
00612
00613 template< ss_typename_param_k S
00614 , ss_typename_param_k C
00615 , ss_typename_param_k T
00616 >
00617 inline fast_string_concatenator<S, C, T> operator +(fast_string_concatenator<S, C, T> const& lhs, S const& rhs)
00618 {
00619 return fast_string_concatenator<S, C, T>(lhs, rhs);
00620 }
00621
00622 template< ss_typename_param_k S
00623 , ss_typename_param_k C
00624 , ss_typename_param_k T
00625 >
00626 inline fast_string_concatenator<S, C, T> operator +(fast_string_concatenator<S, C, T> const& lhs, C const* rhs)
00627 {
00628 return fast_string_concatenator<S, C, T>(lhs, rhs);
00629 }
00630
00631 template< ss_typename_param_k S
00632 , ss_typename_param_k C
00633 , ss_typename_param_k T
00634 >
00635 inline fast_string_concatenator<S, C, T> operator +(fast_string_concatenator<S, C, T> const& lhs, C const rhs)
00636 {
00637 return fast_string_concatenator<S, C, T>(lhs, rhs);
00638 }
00639
00640
00641 template< ss_typename_param_k S
00642 , ss_typename_param_k C
00643 , ss_typename_param_k T
00644 >
00645 inline fast_string_concatenator<S, C, T> operator +(fast_string_concatenator<S, C, T> const& lhs, fast_string_concatenator<S, C, T> const& rhs)
00646 {
00647 return fast_string_concatenator<S, C, T>(lhs, rhs);
00648 }
00649
00650 template< ss_typename_param_k S
00651 , ss_typename_param_k C
00652 , ss_typename_param_k T
00653 >
00654 inline fast_string_concatenator<S, C, T> operator +(S const& lhs, fast_string_concatenator<S, C, T> const& rhs)
00655 {
00656 return fast_string_concatenator<S, C, T>(lhs, rhs);
00657 }
00658
00659 template< ss_typename_param_k S
00660 , ss_typename_param_k C
00661 , ss_typename_param_k T
00662 >
00663 inline fast_string_concatenator<S, C, T> operator +(C const* lhs, fast_string_concatenator<S, C, T> const& rhs)
00664 {
00665 return fast_string_concatenator<S, C, T>(lhs, rhs);
00666 }
00667
00668 template< ss_typename_param_k S
00669 , ss_typename_param_k C
00670 , ss_typename_param_k T
00671 >
00672 inline fast_string_concatenator<S, C, T> operator +(C const lhs, fast_string_concatenator<S, C, T> const& rhs)
00673 {
00674 return fast_string_concatenator<S, C, T>(lhs, rhs);
00675 }
00676
00677
00678
00679 #ifndef _STLSOFT_NO_NAMESPACE
00680 }
00681 #endif
00682
00683
00684
00685 #endif
00686
00687