1 // ========================================================================== 2 // SeqAn - The Library for Sequence Analysis 3 // ========================================================================== 4 // Copyright (c) 2006-2015, Knut Reinert, FU Berlin 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above copyright 13 // notice, this list of conditions and the following disclaimer in the 14 // documentation and/or other materials provided with the distribution. 15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of 16 // its contributors may be used to endorse or promote products derived 17 // from this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE 23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 29 // DAMAGE. 30 // 31 // ========================================================================== 32 // Author: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de> 33 // ========================================================================== 34 // Tags, declarations and generic code for the String class and its 35 // specializations. 36 // ========================================================================== 37 38 #ifndef SEQAN_SEQUENCE_STRING_ARRAY_BASE_H_ 39 #define SEQAN_SEQUENCE_STRING_ARRAY_BASE_H_ 40 41 namespace seqan { 42 43 // ============================================================================ 44 // Forwards 45 // ============================================================================ 46 47 // ============================================================================ 48 // Tags, Classes, Enums 49 // ============================================================================ 50 51 template <typename TSpec = void> 52 struct Alloc {}; 53 54 // TODO(holtgrew): This requires some work: explain it, maybe rather put this into a group since the text object appears in no function's signatures. 55 56 /*! 57 * @concept TextConcept 58 * @brief Concept for a type that can be as text of an index. 59 * @headerfile <seqan/sequence.h> 60 * 61 * @signature concept TextConcept; 62 * 63 * Certain algorithms and data structures can work for both strings and string sets but need to treat these two 64 * types slightly different. Examples are index data structures and algorithms that build the indices and use 65 * the indices for lookup. 66 * 67 * To facilitate writing of generic algorithms, the TextConcept concept gives a common interface to both for this 68 * kind of algorithms. 69 * 70 * @see String 71 * @see StringSet 72 */ 73 74 /*! 75 * @mfn TextConcept#StringSetLimits 76 * @brief Return type of string set limits for TextConcept types. 77 * 78 * @signature StringSetLimits<TText>::Type; 79 * 80 * @tparam TText The type of the text. 81 * 82 * @return Type The type of string set limits objects. 83 */ 84 85 /*! 86 * @mfn TextConcept#SAValue 87 * @brief The default alphabet type of a suffix array, i.e. the type to store a 88 * position of a string or string set. 89 * 90 * @signature SAValue<TText>::Type 91 * 92 * @tparam TText The text type to query. 93 * 94 * @return TReturn A type to store a position in a <tt>TText</tt>. This could be an integer for strings or a 95 * pair of integers for string sets. 96 * 97 * @section Usage 98 * 99 * This type should be removed for functions returning positions in texts such as online or index-based search. 100 * Thus, always use this metafunction for declaring position variables. 101 * 102 * Use the functions @link TextConcept#posLocalize @endlink, @link TextConcept#posGlobalize @endlink, @link 103 * TextConcept#getSeqNo @endlink, and @link TextConcept#getSeqOffset @endlink for conversion between local 104 * and global positions in texts. 105 * 106 * @section Examples 107 * 108 * The following shows the original definition of the SAValue metafunction in SeqAn. 109 * 110 * @code{.cpp} 111 * template <typename TString, typename TSpec> 112 * struct SAValue<StringSet<TString, TSpec> > 113 * { 114 * typedef Pair< 115 * typename Size<StringSet<TString, TSpec> >::Type, 116 * typename SAValue<TString>::Type, 117 * Pack 118 * > Type; 119 * }; 120 * @endcode 121 */ 122 123 /*! 124 * @fn TextConcept#stringSetLimits 125 * @brief Return string delimiter positions for TextConcept types. 126 * 127 * @signature TStringSetLimits stringSetLimits(text); 128 * 129 * @param[in] text The text to query for its string set limits. 130 * 131 * @return TStringSetLimits The string set limits (of type @link TextConcept#StringSetLimits @endlink). 132 */ 133 134 /*! 135 * @fn TextConcept#posLocalToX 136 * @brief Converts a local to a local/global position. 137 * 138 * @signature void posLocalToX(dst, localPos, limits); 139 * 140 * @param[in] dst The local or global position (pair or integer value) is written here. 141 * @param[in] localPos The local position. 142 * @param[in] limits The string limits as returned by @link TextConcept#stringSetLimits @endlink. 143 */ 144 145 /*! 146 * @class String 147 * @implements StringConcept 148 * @implements TextConcept 149 * @implements SegmentableConcept 150 * @headerfile <seqan/sequence.h> 151 * @brief @link StringConcept Sequence @endlink container class. 152 * 153 * @signature template <typename TValue, typename TSpec> 154 * class String<TValue, TSpec>; 155 * 156 * @tparam TValue The element type of the string. 157 * @tparam TSpec The tag for selecting the string specialization. 158 * 159 * The String class is for storing sequences and thus at the core of the sequence analysis library SeqAn. They 160 * are models for the @link StringConcept sequence concept @endlink but extend the sequence concept by allowing 161 * implicit conversion of other sequence into strings as long as the element conversion works: 162 * 163 * @snippet demos/sequence/string.cpp initializing strings 164 * 165 * Aside from that, the usual operations (appending, insertion, removing, element access) are available as well. 166 * 167 * @snippet demos/sequence/string.cpp usual operations 168 * 169 * Strings have a size (the actual number of elements) and a capacity (the number of elements that memory has been 170 * allocated for). Note that clearing a string does not free the memory (as the STL, SeqAn assumes that strings will 171 * later require a similar amount of memory as before). Using @link ContainerConcept#shrinkToFit @endlink, the user can 172 * force a re-allocation of the memory such that the string afterward uses the minimal amount of memory to accomodate 173 * all of its objects. 174 * 175 * @snippet demos/sequence/string.cpp clear and resize 176 * 177 * @section Examples 178 * 179 * This example shows a brute force pattern matching scheme for two character Strings. Creation of String "text" shows 180 * the usage of some available String operating functions. See class @link StringSet @endlink for an example of a 181 * String container with other than simple type values. See class @link Index @endlink example for efficiently finding 182 * the same pattern matches using an index. 183 * 184 * @include demos/sequence/string2.cpp 185 * 186 * The output is as follows: 187 * 188 * @include demos/sequence/string2.cpp.stdout 189 * 190 * @see StringSet 191 */ 192 193 /*! 194 * @fn String::String 195 * @brief Constructor. 196 * 197 * @signature String::String() 198 * @signature String::String(other) 199 * 200 * @param[in] other The source for the copy constructor. Can be of any @link StringConcept sequence @endlink type 201 * as long as <tt>other</tt>'s elements are convertible to the value type of this string. 202 * 203 * Default and copy constructor are implemented. 204 */ 205 206 /*! 207 * @fn String::operator= 208 * @brief The String assignment operator allows assignment of convertible sequences. 209 * 210 * @signature TString String::operator=(other) 211 * 212 * @param[in] other The other string. Must be a sequence whose elements are convertible into this String's type. 213 * 214 * @return TString Reference to the String objecta after assignment. 215 */ 216 217 // TODO(holtgrew): The conversion functions rather belong into their own group than to the concept. The original documentation was a bit misleading and needs to be updated. 218 219 /*! 220 * @fn TextConcept#posLocalize 221 * @brief Converts a local/global to a local position. 222 * @headerfile <seqan/sequence.h> 223 * 224 * @signature void posLocalize(result, pos, limits) 225 * 226 * @param[in] pos A local or global position (pair or integer value). 227 * @param[in] limits The limits string returned by @link TextConcept#stringSetLimits @endlink. 228 * @param[in] result Reference to the resulting corresponding local position of 229 * <tt>pos</tt>. 230 */ 231 232 /*! 233 * @fn TextConcept#posGlobalize 234 * @brief Converts a local/global to a global position. 235 * @headerfile <seqan/sequence.h> 236 * 237 * @signature TPos posGlobalize(pos, limits) 238 * 239 * @param[in] pos A local or global position (pair or integer value). Types: Pair 240 * @param[in] limits The limits string returned by @link TextConcept#stringSetLimits @endlink. 241 * 242 * @return TPos The corresponding global position of <tt>pos</tt>. If 243 * <tt>pos</tt> is an integral type <tt>pos</tt> is returned. If 244 * not, <tt>limits[getSeqNo(pos, limits)] + getSeqOffset(pos, 245 * limits)</tt> is returned. 246 */ 247 248 /*! 249 * @fn TextConcept#getSeqNo 250 * @brief Returns the sequence number of a position. 251 * @headerfile <seqan/sequence.h> 252 * 253 * @signature TSeqNo getSeqNo(pos[, limits]); 254 * 255 * @param[in] pos A position. Types: Pair 256 * @param[in] limits The limits string returned by @link TextConcept#stringSetLimits @endlink. 257 * 258 * @return TSeqNo A single integer value that identifies the string within the stringset <tt>pos</tt> points at. If 259 * <tt>limits</tt> is omitted or @link Nothing @endlink <tt>getSeqNo</tt> returns 0.If <tt>pos</tt> is a 260 * local position (of class @link Pair @endlink) then <tt>i1</tt> is returned.If <tt>pos</tt> is a global 261 * position (integer type and <tt>limits</tt> is a @link String @endlink) then <tt>pos</tt> is converted 262 * to a local position and <tt>i1</tt> is returned. 263 */ 264 265 /*! 266 * @fn TextConcept#getSeqOffset 267 * @brief Returns the local sequence offset of a position. 268 * @headerfile <seqan/sequence.h> 269 * 270 * @signature TOffset getSeqOffset(pos[, limits]); 271 * 272 * @param[in] pos A position. Types: Pair 273 * @param[in] limits The limits string returned by @link TextConcept#stringSetLimits @endlink. 274 * 275 * @return TOffset A single integer value that identifies the position within the string <tt>pos</tt> points at.If 276 * <tt>limits</tt> is omitted or @link Nothing @endlink <tt>getSeqNo</tt> returns <tt>pos</tt>. If 277 * <tt>pos</tt> is a local position (of class @link Pair @endlink) then <tt>i2</tt> is returned.If 278 * <tt>pos</tt> is a global position (integer type and <tt>limits</tt> is a @link String @endlink) then 279 * <tt>pos</tt> is converted to a local position and <tt>i2</tt> is returned. 280 */ 281 282 template <typename TValue, typename TSpec = Alloc<> > 283 class String; 284 285 // ============================================================================ 286 // Metafunctions 287 // ============================================================================ 288 289 // ---------------------------------------------------------------------------- 290 // Metafunction Value 291 // ---------------------------------------------------------------------------- 292 293 template <typename TValue, typename TSpec> 294 struct Value<String<TValue, TSpec> > 295 { 296 typedef TValue Type; 297 }; 298 299 template <typename TValue, typename TSpec> 300 struct Value<String<TValue, TSpec> const > 301 : public Value<String<TValue, TSpec> > 302 {}; 303 304 // ---------------------------------------------------------------------------- 305 // Metafunction Spec 306 // ---------------------------------------------------------------------------- 307 308 template <typename TValue, typename TSpec> 309 struct Spec<String<TValue, TSpec> > 310 { 311 typedef TSpec Type; 312 }; 313 template <typename TValue, typename TSpec> 314 struct Spec<String<TValue, TSpec> const>: 315 public Spec<String<TValue, TSpec> > 316 { 317 }; 318 319 // ---------------------------------------------------------------------------- 320 // Metafunction StringSpec 321 // ---------------------------------------------------------------------------- 322 323 template <typename T> 324 struct StringSpec 325 { 326 typedef Alloc<> Type; 327 }; 328 329 template <typename T> 330 struct StringSpec<T const> : StringSpec<T> {}; 331 332 template <typename TValue, typename TSpec> 333 struct StringSpec<String<TValue, TSpec> > 334 { 335 typedef TSpec Type; 336 }; 337 338 // ---------------------------------------------------------------------------- 339 // Metafunction Chunk 340 // ---------------------------------------------------------------------------- 341 342 template <typename TValue, typename TSpec> 343 struct Chunk<String<TValue, TSpec> >: 344 Chunk<typename Iterator<String<TValue, TSpec>, Rooted>::Type> {}; 345 346 // ---------------------------------------------------------------------------- 347 // Metafunction IsSequence 348 // ---------------------------------------------------------------------------- 349 350 template <typename TValue, typename TSpec> 351 struct IsSequence<String<TValue, TSpec> > : True {}; 352 353 // ---------------------------------------------------------------------------- 354 // Concept StringConcept 355 // ---------------------------------------------------------------------------- 356 357 template <typename TValue, typename TSpec> 358 SEQAN_CONCEPT_IMPL((String<TValue, TSpec>), (StringConcept)); // resizable container 359 360 template <typename TValue, typename TSpec> 361 SEQAN_CONCEPT_IMPL((String<TValue, TSpec> const), (ContainerConcept)); // read-only container 362 363 // ---------------------------------------------------------------------------- 364 // Internal Metafunction TempCopy_ 365 // ---------------------------------------------------------------------------- 366 367 template <typename T> 368 struct TempCopy_ 369 { 370 typedef typename Value<T>::Type TValue_; 371 typedef typename RemoveConst_<TValue_>::Type TValueNotConst_; 372 typedef String<TValueNotConst_, Alloc<> > Type; 373 }; 374 375 // ============================================================================ 376 // Functions 377 // ============================================================================ 378 379 // TODO(holtgrew): Where to move this documentation/specification-only stuff? 380 381 // ---------------------------------------------------------------------------- 382 // Function swap() 383 // ---------------------------------------------------------------------------- 384 385 template <typename TAlphabet, typename TSpec> 386 inline void 387 swap(String<TAlphabet, TSpec> & left, 388 String<TAlphabet, TSpec> & right) 389 { 390 391 typedef String<TAlphabet, TSpec> TString; 392 393 TString tmp(left, Move()); 394 move(left, right); 395 move(right, tmp); 396 } 397 398 // ---------------------------------------------------------------------------- 399 // Function shareResources() 400 // ---------------------------------------------------------------------------- 401 402 template <typename TValue, typename TSpec> 403 inline bool 404 shareResources(String<TValue, TSpec> const & obj1, 405 TValue const & obj2) 406 { 407 return (begin(obj1) >= &obj2) && (end(obj1) <= &obj2); 408 } 409 410 template <typename TValue, typename TSpec> 411 inline bool 412 shareResources(TValue const & obj1, 413 String<TValue, TSpec> const & obj2) 414 { 415 return (begin(obj2) >= &obj1) && (end(obj2) <= &obj1); 416 } 417 418 // TODO(holtgrew): Where to move this documentation/specification-only stuff? 419 // ---------------------------------------------------------------------------- 420 // Function value() 421 // ---------------------------------------------------------------------------- 422 423 template <typename TValue, typename TSpec, typename TPos> 424 SEQAN_HOST_DEVICE inline typename Reference< String<TValue, TSpec> >::Type 425 value(String<TValue, TSpec> & me, 426 TPos const & pos) 427 { 428 #if SEQAN_ENABLE_DEBUG 429 typedef typename Position< String<TValue, TSpec> >::Type TStringPos SEQAN_TYPEDEF_FOR_DEBUG; 430 #endif 431 SEQAN_ASSERT_LT_MSG(static_cast<TStringPos>(pos), static_cast<TStringPos>(length(me)), "Trying to access an element behind the last one!"); 432 return *(begin(me, Standard()) + pos); 433 } 434 435 template <typename TValue, typename TSpec, typename TPos> 436 SEQAN_HOST_DEVICE inline typename Reference< String<TValue, TSpec> const >::Type 437 value(String<TValue, TSpec> const & me, 438 TPos const & pos) 439 { 440 #if SEQAN_ENABLE_DEBUG 441 typedef typename Position< String<TValue, TSpec> const >::Type TStringPos SEQAN_TYPEDEF_FOR_DEBUG; 442 #endif 443 SEQAN_ASSERT_LT_MSG(static_cast<TStringPos>(pos), static_cast<TStringPos>(length(me)), "Trying to access an element behind the last one!"); 444 return *(begin(me, Standard()) + pos); 445 } 446 447 // ---------------------------------------------------------------------------- 448 // Function length() 449 // ---------------------------------------------------------------------------- 450 451 template <typename TValue, typename TSpec> 452 SEQAN_HOST_DEVICE inline typename Size< String<TValue, TSpec> const>::Type 453 length(String<TValue, TSpec> const & me) 454 { 455 return end(me, Standard()) - begin(me, Standard()); 456 } 457 458 // ---------------------------------------------------------------------------- 459 // Function empty() 460 // ---------------------------------------------------------------------------- 461 462 template <typename TValue, typename TSpec> 463 SEQAN_HOST_DEVICE inline bool 464 empty(String<TValue, TSpec> const & me) 465 { 466 return end(me, Standard()) == begin(me, Standard()); 467 } 468 469 // ---------------------------------------------------------------------------- 470 // Function clear() 471 // ---------------------------------------------------------------------------- 472 473 template <typename TValue, typename TSpec> 474 inline void 475 clear(String<TValue, TSpec> & me) 476 { 477 arrayDestruct(begin(me, Standard()), end(me, Standard())); 478 _setLength(me, 0); 479 } 480 481 // ---------------------------------------------------------------------------- 482 // Function length() 483 // ---------------------------------------------------------------------------- 484 485 template <typename TExpand> 486 struct ClearSpaceStringBase_ 487 { 488 }; 489 490 // ---------------------------------------------------------------------------- 491 // Internal Function _clearSpace() 492 // ---------------------------------------------------------------------------- 493 494 template <> 495 struct ClearSpaceStringBase_<Insist> 496 { 497 template <typename T> 498 static inline typename Size<T>::Type 499 _clearSpace_( 500 T & seq, 501 typename Size<T>::Type size) 502 { 503 arrayDestruct(begin(seq, Standard()), end(seq, Standard())); 504 _setLength(seq, size); 505 return size; 506 } 507 508 template <typename T> 509 static inline typename Size<T>::Type 510 _clearSpace_( 511 T & seq, 512 typename Size<T>::Type size, 513 typename Size<T>::Type limit) 514 { 515 arrayDestruct(begin(seq, Standard()), end(seq, Standard())); 516 if (limit < size) 517 { 518 size = limit; 519 } 520 _setLength(seq, size); 521 return size; 522 } 523 524 template <typename T> 525 static inline typename Size<T>::Type 526 _clearSpace_( 527 T & seq, 528 typename Size<T>::Type size, 529 typename Size<T>::Type start, 530 typename Size<T>::Type end) 531 { 532 typename Size<T>::Type new_length = length(seq) + size - (end - start); 533 arrayClearSpace(begin(seq, Standard()) + start, length(seq) - start, end - start, size); 534 _setLength(seq, new_length); 535 return size; 536 } 537 538 template <typename T> 539 static typename Size<T>::Type 540 _clearSpace_( 541 T & seq, 542 typename Size<T>::Type size, 543 typename Size<T>::Type start, 544 typename Size<T>::Type end, 545 typename Size<T>::Type limit) 546 { 547 typename Value<T>::Type * seq_buffer = begin(seq); 548 typename Size<T>::Type seq_length = length(seq); 549 550 if (limit > start + size) 551 { 552 typename Size<T>::Type removed_size = end - start; 553 typename Size<T>::Type new_length = seq_length - removed_size + size; 554 if (limit < new_length) 555 { 556 arrayDestruct(seq_buffer + limit, seq_buffer + new_length); 557 seq_length -= new_length - limit; 558 } 559 arrayClearSpace(seq_buffer + start, seq_length - start, end - start, size); 560 _setLength(seq, new_length); 561 return size; 562 } 563 else 564 { 565 arrayDestruct(seq_buffer + start, seq_buffer + seq_length); 566 _setLength(seq, limit); 567 if (limit > start) return limit - start; 568 else return 0; 569 } 570 } 571 /* 572 template <typename T> 573 static inline typename Size<T>::Type 574 _clearSpace_( 575 T & seq, 576 typename Size<T>::Type size, 577 typename Iterator<T>::Type start, 578 typename Iterator<T>::Type end) 579 { 580 typename Iterator<T>::Type seq_begin = begin(seq); 581 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, Insist()); 582 } 583 584 template <typename T> 585 static inline typename Size<T>::Type 586 _clearSpace_( 587 T & seq, 588 typename Size<T>::Type size, 589 typename Iterator<T>::Type start, 590 typename Iterator<T>::Type end, 591 typename Size<T>::Type limit) 592 { 593 typename Iterator<T>::Type seq_begin = begin(seq); 594 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, limit, Insist()); 595 } 596 */ 597 }; 598 599 600 template <> 601 struct ClearSpaceStringBase_<Limit> 602 { 603 604 template <typename T> 605 static inline typename Size<T>::Type 606 _clearSpace_( 607 T & seq, 608 typename Size<T>::Type size) 609 { 610 return _clearSpace(seq, size, capacity(seq), Insist()); 611 } 612 613 template <typename T> 614 static inline typename Size<T>::Type 615 _clearSpace_( 616 T & seq, 617 typename Size<T>::Type size, 618 typename Size<T>::Type limit) 619 { 620 typename Size<T>::Type seq_capacity = capacity(seq); 621 if (limit > seq_capacity) 622 { 623 limit = seq_capacity; 624 } 625 return _clearSpace(seq, size, limit, Insist()); 626 } 627 628 template <typename T> 629 static inline typename Size<T>::Type 630 _clearSpace_( 631 T & seq, 632 typename Size<T>::Type size, 633 typename Size<T>::Type start, 634 typename Size<T>::Type end) 635 { 636 return _clearSpace(seq, size, start, end, capacity(seq), Insist()); 637 } 638 639 template <typename T> 640 static typename Size<T>::Type 641 _clearSpace_( 642 T & seq, 643 typename Size<T>::Type size, 644 typename Size<T>::Type start, 645 typename Size<T>::Type end, 646 typename Size<T>::Type limit) 647 { 648 typename Size<T>::Type seq_capacity = capacity(seq); 649 if (limit > seq_capacity) 650 { 651 limit = seq_capacity; 652 } 653 return _clearSpace(seq, size, start, end, limit, Insist()); 654 } 655 656 /* 657 template <typename T> 658 static inline typename Size<T>::Type 659 _clearSpace_( 660 T & seq, 661 typename Size<T>::Type size, 662 typename Iterator<T>::Type start, 663 typename Iterator<T>::Type end) 664 { 665 typename Iterator<T>::Type seq_begin = begin(seq); 666 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, Insist()); 667 } 668 669 template <typename T> 670 static inline typename Size<T>::Type 671 _clearSpace_( 672 T & seq, 673 typename Size<T>::Type size, 674 typename Iterator<T>::Type start, 675 typename Iterator<T>::Type end, 676 typename Size<T>::Type limit) 677 { 678 typename Iterator<T>::Type seq_begin = begin(seq); 679 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, limit, Insist()); 680 } 681 */ 682 }; 683 684 template <typename TExpand> 685 struct ClearSpaceExpandStringBase_ 686 { 687 template <typename T> 688 static inline typename Size<T>::Type 689 _clearSpace_( 690 T & seq, 691 typename Size<T>::Type size) 692 { 693 arrayDestruct(begin(seq, Standard()), end(seq, Standard())); 694 typename Size<T>::Type old_capacity = capacity(seq); 695 typename Value<T>::Type * old_array = _reallocateStorage(seq, size, TExpand()); 696 if (old_array) 697 { 698 _deallocateStorage(seq, old_array, old_capacity); 699 } 700 _setLength(seq, size); 701 return size; 702 } 703 704 template <typename T> 705 static inline typename Size<T>::Type 706 _clearSpace_( 707 T & seq, 708 typename Size<T>::Type size, 709 typename Size<T>::Type limit) 710 { 711 arrayDestruct(begin(seq, Standard()), end(seq, Standard())); 712 if (limit < size) 713 { 714 size = limit; 715 } 716 typename Size<T>::Type old_capacity = capacity(seq); 717 typename Value<T>::Type * old_array = _reallocateStorage(seq, size, limit, TExpand()); 718 if (old_array) 719 { 720 _deallocateStorage(seq, old_array, old_capacity); 721 } 722 _setLength(seq, size); 723 return size; 724 } 725 726 template <typename T> 727 static typename Size<T>::Type 728 _clearSpace_( 729 T & seq, 730 typename Size<T>::Type size, 731 typename Size<T>::Type start, 732 typename Size<T>::Type end) 733 { 734 typename Size<T>::Type old_length = length(seq); 735 typename Size<T>::Type removed_size = end - start; 736 typename Size<T>::Type new_length = old_length - removed_size + size; 737 738 SEQAN_ASSERT_LEQ(start, end); 739 SEQAN_ASSERT_LEQ(start, old_length); 740 741 typename Size<T>::Type old_capacity = capacity(seq); 742 typename Value<T>::Type * old_array = _reallocateStorage(seq, new_length, TExpand()); 743 typename Value<T>::Type * seq_array = begin(seq); 744 745 if (old_array) 746 { 747 arrayConstructMove(old_array, old_array + start, seq_array); 748 arrayConstructMove(old_array + end, old_array + old_length, seq_array + start + size); 749 _deallocateStorage(seq, old_array, old_capacity); 750 // TODO(weese:) Did we miss to destruct the old_array here, e.g. with arrayDestruct 751 } 752 else 753 { 754 arrayClearSpace(seq_array + start, old_length - start, removed_size, size); 755 } 756 757 _setLength(seq, new_length); 758 759 return size; 760 } 761 762 template <typename T> 763 static typename Size<T>::Type 764 _clearSpace_( 765 T & seq, 766 typename Size<T>::Type size, 767 typename Size<T>::Type start, 768 typename Size<T>::Type end, 769 typename Size<T>::Type limit) 770 { 771 typename Size<T>::Type old_length = length(seq); 772 typename Size<T>::Type removed_size = end - start; 773 typename Size<T>::Type need_length = old_length - removed_size + size; 774 775 SEQAN_ASSERT_LEQ(start, end); 776 SEQAN_ASSERT_LEQ(start, old_length); 777 778 typename Size<T>::Type new_length = need_length; 779 typename Size<T>::Type length_to_copy = old_length; 780 if (limit < need_length) 781 { 782 new_length = limit; 783 length_to_copy = new_length - size + removed_size; 784 } 785 786 bool keep_second_part = (new_length > start + size); 787 788 typename Size<T>::Type old_capacity = capacity(seq); 789 typename Value<T>::Type * old_array = _reallocateStorage(seq, new_length, limit, TExpand()); 790 typename Value<T>::Type * seq_array = begin(seq); 791 792 if (old_array) 793 {//new buffer allocated 794 typename Size<T>::Type keep_start_length = (start > new_length) ? new_length : start; 795 arrayConstructMove(old_array, old_array + keep_start_length, seq_array); 796 if (keep_second_part) 797 { 798 arrayConstructMove(old_array + end, old_array + length_to_copy, seq_array + start + size); 799 } 800 _deallocateStorage(seq, old_array, old_capacity); 801 } 802 else 803 { 804 if (keep_second_part) 805 { 806 arrayClearSpace(seq_array + start, length_to_copy - start, end - start, size); 807 if (length_to_copy < old_length) 808 { 809 arrayDestruct(seq_array + length_to_copy, seq_array + old_length); 810 } 811 } 812 else 813 { 814 arrayDestruct(seq_array + start, seq_array + old_length); 815 } 816 } 817 818 _setLength(seq, new_length); 819 820 if (keep_second_part) return size; 821 else if (new_length > start) return new_length - start; 822 else return 0; 823 } 824 825 /* 826 template <typename T> 827 static inline typename Size<T>::Type 828 _clearSpace_( 829 T & seq, 830 typename Size<T>::Type size, 831 typename Iterator<T>::Type start, 832 typename Iterator<T>::Type end) 833 { 834 typename Iterator<T>::Type seq_begin = begin(seq); 835 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, TExpand()); 836 } 837 838 template <typename T> 839 static inline typename Size<T>::Type 840 _clearSpace_( 841 T & seq, 842 typename Size<T>::Type size, 843 typename Iterator<T>::Type start, 844 typename Iterator<T>::Type end, 845 typename Size<T>::Type limit) 846 { 847 typename Iterator<T>::Type seq_begin = begin(seq); 848 return _clearSpace(seq, size, start - seq_begin, end - seq_begin, limit, TExpand()); 849 } 850 */ 851 }; 852 853 template <> 854 struct ClearSpaceStringBase_<Exact>: 855 ClearSpaceExpandStringBase_<Exact> 856 { 857 }; 858 859 template <> 860 struct ClearSpaceStringBase_<Generous>: 861 ClearSpaceExpandStringBase_<Generous> 862 { 863 }; 864 865 template<typename TValue, typename TSpec, typename TSize, typename TExpand> 866 inline typename Size< String<TValue, TSpec> >::Type 867 _clearSpace(String<TValue, TSpec> & me, 868 TSize size, 869 Tag<TExpand>) 870 { 871 return ClearSpaceStringBase_<Tag<TExpand> >::_clearSpace_(me, size); 872 } 873 874 template<typename TValue, typename TSpec, typename TSize, typename TCapacity, typename TExpand> 875 inline typename Size< String<TValue, TSpec> >::Type 876 _clearSpace(String<TValue, TSpec> & me, 877 TSize size, 878 TCapacity limit, 879 Tag<TExpand>) 880 { 881 return ClearSpaceStringBase_<Tag<TExpand> >::_clearSpace_(me, size, limit); 882 } 883 884 template<typename TValue, typename TSpec, typename TSize, typename TPosition, typename TExpand> 885 inline typename Size< String<TValue, TSpec> >::Type 886 _clearSpace(String<TValue, TSpec> & me, 887 TSize size, 888 TPosition pos_begin, 889 TPosition pos_end, 890 Tag<TExpand>) 891 { 892 return ClearSpaceStringBase_<Tag<TExpand> >::_clearSpace_(me, size, pos_begin, pos_end); 893 } 894 895 template<typename TValue, typename TSpec, typename TSize, typename TPosition, typename TCapacity, typename TExpand> 896 inline typename Size< String<TValue, TSpec> >::Type 897 _clearSpace(String<TValue, TSpec> & me, 898 TSize size, 899 TPosition pos_begin, 900 TPosition pos_end, 901 TCapacity limit, 902 Tag<TExpand>) 903 { 904 return ClearSpaceStringBase_<Tag<TExpand> >::_clearSpace_(me, size, pos_begin, pos_end, limit); 905 } 906 907 // ---------------------------------------------------------------------------- 908 // Function resizeSpace() 909 // ---------------------------------------------------------------------------- 910 911 template<typename TValue, typename TSpec, typename TSize, typename TBeginPosition, typename TEndPosition, typename TExpand> 912 inline typename Size< String<TValue, TSpec> >::Type 913 resizeSpace(String<TValue, TSpec> & me, 914 TSize size, 915 TBeginPosition pos_begin, 916 TEndPosition pos_end, 917 Tag<TExpand> tag) 918 { 919 typedef typename Size< String<TValue, TSpec> >::Type TSize_; 920 typedef typename Position<String<TValue, TSpec> >::Type TPos_; 921 TSize_ ret_ = _clearSpace( 922 me, 923 static_cast<TSize_>(size), 924 static_cast<TPos_>(pos_begin), 925 static_cast<TPos_>(pos_end), 926 tag); 927 arrayConstruct(iter(me, pos_begin), iter(me, pos_begin) + ret_); 928 return ret_; 929 } 930 931 template<typename TValue, typename TSpec, typename TSize, typename TBeginPosition, typename TEndPosition, typename TCapacity, typename TExpand> 932 inline typename Size< String<TValue, TSpec> >::Type 933 resizeSpace(String<TValue, TSpec> & me, 934 TSize size, 935 TBeginPosition pos_begin, 936 TEndPosition pos_end, 937 TCapacity limit, 938 Tag<TExpand> tag) 939 { 940 typedef typename Size< String<TValue, TSpec> >::Type TSize_; 941 typedef typename Position<String<TValue, TSpec> >::Type TPos_; 942 TSize_ ret_ = _clearSpace( 943 me, 944 static_cast<TSize_>(size), 945 static_cast<TPos_>(pos_begin), 946 static_cast<TPos_>(pos_end), 947 static_cast<TSize_>(limit), 948 tag); 949 arrayConstruct(iter(me, pos_begin), iter(me, pos_begin) + ret_); 950 return ret_; 951 } 952 953 // ---------------------------------------------------------------------------- 954 // Function assign() 955 // ---------------------------------------------------------------------------- 956 957 // Facade version without overflow tag. Forwards to version with overflow 958 // tag, using Metafunction.DefaultOverflowImplicity. 959 960 template<typename TTargetValue, typename TTargetSpec, typename TSource> 961 inline void 962 assign(String<TTargetValue, TTargetSpec> & target, 963 TSource & source) 964 { 965 typedef String<TTargetValue, TTargetSpec> TTarget; 966 assign(target, source, typename DefaultOverflowImplicit<TTarget>::Type()); 967 } 968 969 template<typename TTargetValue, typename TTargetSpec, typename TSource> 970 inline void 971 assign(String<TTargetValue, TTargetSpec> & target, 972 TSource const & source) 973 { 974 typedef String<TTargetValue, TTargetSpec> TTarget; 975 assign(target, source, typename DefaultOverflowImplicit<TTarget>::Type()); 976 } 977 978 // Helper struct for assigning strings. 979 980 template <typename TExpand> 981 struct AssignString_ 982 { 983 template <typename TTarget, typename TSource> 984 static inline void 985 assign_( 986 TTarget & target, 987 TSource & source) 988 { 989 if (empty(source) && empty(target)) 990 return; // Do nothing if both source and target are empty. 991 if (!getObjectId(source) || !shareResources(target, source)) 992 { 993 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), TExpand()); 994 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard())); 995 } 996 else 997 { 998 if ((void *) &target == (void *) &source) return; 999 1000 typename TempCopy_<TSource>::Type temp(source, length(source)); 1001 assign(target, temp, TExpand()); 1002 } 1003 } 1004 1005 template <typename TTarget, typename TSource> 1006 static inline void 1007 assign_( 1008 TTarget & target, 1009 TSource & source, 1010 typename Size<TTarget>::Type limit) 1011 { 1012 if (!getObjectId(source) || !shareResources(target, source)) 1013 { 1014 typename Size<TTarget>::Type part_length = _clearSpace(target, typename Size<TTarget>::Type(length(source)), limit, TExpand()); 1015 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard())); 1016 } 1017 else 1018 { 1019 if ((void *) &target == (void *) &source) return; 1020 1021 typename Size<TTarget>::Type source_length = length(source); 1022 if (source_length > limit) source_length = limit; 1023 1024 typename TempCopy_<TSource>::Type temp(source, source_length); 1025 assign(target, temp, TExpand()); 1026 } 1027 } 1028 }; 1029 1030 // Interface for assign with overflow strategy tag. Forwards to static 1031 // functions of helper struct. 1032 1033 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TExpand> 1034 inline void 1035 assign(String<TTargetValue, TTargetSpec> & target, 1036 TSource const & source, 1037 Tag<TExpand>) 1038 { 1039 AssignString_<Tag<TExpand> >::assign_(target, source); 1040 } 1041 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TSize, typename TExpand> 1042 inline void 1043 assign(String<TTargetValue, TTargetSpec> & target, 1044 TSource const & source, 1045 TSize limit, 1046 Tag<TExpand>) 1047 { 1048 AssignString_<Tag<TExpand> >::assign_(target, source, limit); 1049 } 1050 1051 //// TODO(holtgrew): Still required with dropped VC++ 2003 support? 1052 ////this variant is a workaround for the "const array"-bug of VC++ 1053 // 1054 //template<typename TTargetValue, typename TTargetSpec, typename TSourceValue, typename TExpand> 1055 //inline void 1056 //assign(String<TTargetValue, TTargetSpec> & target, 1057 // TSourceValue const * source, 1058 // Tag<TExpand>) 1059 //{ 1060 // AssignString_<Tag<TExpand> >::assign_(target, source); 1061 //} 1062 //template<typename TTargetValue, typename TTargetSpec, typename TSourceValue, typename TSize, typename TExpand> 1063 //inline void 1064 //assign(String<TTargetValue, TTargetSpec> & target, 1065 // TSourceValue const * source, 1066 // TSize limit, 1067 // Tag<TExpand>) 1068 //{ 1069 // AssignString_<Tag<TExpand> >::assign_(target, source, limit); 1070 //} 1071 1072 // ---------------------------------------------------------------------------- 1073 // Function move() 1074 // ---------------------------------------------------------------------------- 1075 1076 //implementation of move for contiguous sequences 1077 //note: there is a problem, if sizeof(TSourceValue) and sizeof(TTargetValue) are not a multiple 1078 // of each other, since in this case the correct size cannot be determined afterwards 1079 // when calling the deallocate function. 1080 // ???TODO 1081 template <typename TTarget, typename TSource> 1082 void 1083 _moveContiguous(TTarget & target, 1084 TSource & source) 1085 { 1086 typedef typename Value<TSource>::Type TSourceValue; 1087 typedef typename Value<TTarget>::Type TTargetValue; 1088 1089 clear(target); 1090 1091 typename Iterator<TSource, Standard>::Type source_begin = begin(source, Standard()); 1092 typename Iterator<TTarget, Standard>::Type target_begin = (typename Iterator<TTarget, Standard>::Type) begin(source, Standard()); 1093 1094 typename Size<TTarget>::Type size = sizeof(TSourceValue) * capacity(source); 1095 if (size >= sizeof(TTargetValue)) 1096 { 1097 if (sizeof(TSourceValue) <= 2) ++size; //regard the "end of string termination" case 1098 typename Size<TTarget>::Type target_capacity = size / sizeof(TTargetValue); 1099 if (sizeof(TTargetValue) <= 2) --target_capacity; //regard the "end of string termination" case 1100 1101 typename Size<TTarget>::Type target_length = length(source); 1102 if (target_length > target_capacity) 1103 { 1104 target_length = target_capacity; 1105 } 1106 1107 if (sizeof(TSourceValue) >= sizeof(TTargetValue)) 1108 { 1109 arrayMoveForward(source_begin, source_begin + target_length, target_begin); 1110 } 1111 else 1112 { 1113 arrayMoveBackward(source_begin, source_begin + target_length, target_begin); 1114 } 1115 1116 _setBegin(target, target_begin); 1117 _setLength(target, target_length); 1118 _setCapacity(target, target_capacity); 1119 1120 typedef typename Iterator<TSource, Standard>::Type TSourceIterator; 1121 _setBegin(source, TSourceIterator(0)); 1122 _setLength(source, 0); 1123 _setCapacity(source, 0); 1124 } 1125 else 1126 { 1127 clear(source); 1128 } 1129 } 1130 1131 template<typename TTargetValue, typename TTargetSpec, typename TSource> 1132 inline void 1133 move(String<TTargetValue, TTargetSpec> & target, 1134 TSource & source) 1135 { 1136 typedef String<TTargetValue, TTargetSpec> TTarget; 1137 move(target, source, typename DefaultOverflowImplicit<TTarget>::Type()); 1138 } 1139 1140 template<typename TTargetValue, typename TTargetSpec, typename TSource> 1141 inline void 1142 move(String<TTargetValue, TTargetSpec> & target, 1143 TSource const & source) 1144 { 1145 typedef String<TTargetValue, TTargetSpec> TTarget; 1146 move(target, source, typename DefaultOverflowImplicit<TTarget>::Type()); 1147 } 1148 1149 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TTag> 1150 inline void 1151 move(String<TTargetValue, TTargetSpec> & target, 1152 TSource & source, 1153 Tag<TTag> const & tag) 1154 { 1155 assign(target, source, tag); 1156 } 1157 1158 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TTag> 1159 inline void 1160 move(String<TTargetValue, TTargetSpec> & target, 1161 TSource const & source, 1162 Tag<TTag> const & tag) 1163 { 1164 assign(target, source, tag); 1165 } 1166 1167 // TODO(holtgrew): Garbage? 1168 1169 ////////////////////////////////////////////////////////////////////////////// 1170 // valueConstructMove: 1171 // it is usually better for strings to default construct and move instead of 1172 // copy construct strings 1173 1174 /* 1175 template <typename TIterator, typename TValue, typename TSpec> 1176 inline void 1177 valueConstructMove(TIterator it, 1178 String<TValue, TSpec> const & value) 1179 { 1180 valueConstruct(it); 1181 move(*it, value); 1182 } 1183 */ 1184 1185 // ---------------------------------------------------------------------------- 1186 // Function _stringCheckForOverlap 1187 // ---------------------------------------------------------------------------- 1188 1189 template <typename TIter1, typename TIter2, typename TSize> 1190 inline bool 1191 _stringCheckForPossibleOverlap(TIter1 const &, TIter2 const &, TSize) 1192 { 1193 return true; 1194 } 1195 1196 template <typename TIter, typename TSize> 1197 inline bool 1198 _stringCheckForPossibleOverlap(TIter const &it1, TIter const &it2, TSize length) 1199 { 1200 // return false if [it1,it1+length) and [it2,it2+length) are not overlapping 1201 return !(it2 + length <= it1 || it1 + length <= it2); 1202 } 1203 1204 // ---------------------------------------------------------------------------- 1205 // Function append() 1206 // ---------------------------------------------------------------------------- 1207 1208 template <typename TExpand> 1209 struct AppendString_ 1210 { 1211 template <typename TTarget, typename TSource> 1212 static inline void 1213 append_(TTarget & target, 1214 TSource & source) 1215 { 1216 if (!getObjectId(source) || !shareResources(target, source) || 1217 !_stringCheckForPossibleOverlap(begin(source, Standard()), end(target, Standard()), length(source))) 1218 { 1219 typename Size<TTarget>::Type target_length = length(target); 1220 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), target_length, target_length, TExpand()); 1221 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard()) + target_length); 1222 } 1223 else 1224 { 1225 typename TempCopy_<TSource>::Type temp(source, length(source)); 1226 append(target, temp, TExpand()); 1227 } 1228 } 1229 1230 template <typename TTarget, typename TSource> 1231 static inline void 1232 append_(TTarget & target, 1233 TSource & source, 1234 typename Size<TTarget>::Type limit) 1235 { 1236 typename Iterator<TTarget, Standard>::Type target_begin = begin(target, Standard()); 1237 if (!getObjectId(source) || !shareResources(target, source)) 1238 { 1239 typename Size<TTarget>::Type target_length = length(target); 1240 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), target_length, target_length, limit, TExpand()); 1241 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard()) + target_length); 1242 } 1243 else 1244 { 1245 typename Size<TTarget>::Type target_length = length(target); 1246 if (target_length >= limit) 1247 { 1248 arrayDestruct(target_begin + limit, target_begin + target_length); 1249 _setLength(target, limit); 1250 } 1251 else 1252 { 1253 limit -= target_length; 1254 typename Size<TTarget>::Type source_length = length(source) ; 1255 if (source_length > limit) source_length = limit; 1256 1257 typename TempCopy_<TSource>::Type temp(source, source_length); 1258 append(target, temp, TExpand()); 1259 } 1260 } 1261 } 1262 }; 1263 1264 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TExpand> 1265 inline void 1266 append(String<TTargetValue, TTargetSpec> & target, 1267 TSource const & source, 1268 Tag<TExpand>) 1269 { 1270 AppendString_<Tag<TExpand> >::append_(target, source); 1271 } 1272 1273 template<typename TTargetValue, typename TTargetSpec, typename TSource, typename TExpand> 1274 inline void 1275 append(String<TTargetValue, TTargetSpec> & target, 1276 TSource const & source, 1277 typename Size< String<TTargetValue, TTargetSpec> >::Type limit, 1278 Tag<TExpand>) 1279 { 1280 AppendString_<Tag<TExpand> >::append_(target, source, limit); 1281 } 1282 1283 // TODO(holtgrew): Still required with dropped VC++ 2003 support? 1284 //this variant is a workaround for the "const array"-bug of VC++ 1285 1286 template<typename TTargetValue, typename TTargetSpec, typename TSourceValue, typename TExpand> 1287 inline void 1288 append(String<TTargetValue, TTargetSpec> & target, 1289 TSourceValue * source, 1290 Tag<TExpand>) 1291 { 1292 AppendString_<Tag<TExpand> >::append_(target, source); 1293 } 1294 1295 template<typename TTargetValue, typename TTargetSpec, typename TSourceValue, typename TExpand> 1296 inline void 1297 append(String<TTargetValue, TTargetSpec> & target, 1298 TSourceValue * source, 1299 typename Size< String<TTargetValue, TTargetSpec> >::Type limit, 1300 Tag<TExpand>) 1301 { 1302 AppendString_<Tag<TExpand> >::append_(target, source, limit); 1303 } 1304 1305 // ---------------------------------------------------------------------------- 1306 // Function appendValue() 1307 // ---------------------------------------------------------------------------- 1308 1309 template <typename TExpand> 1310 struct AppendValueToString_ 1311 { 1312 template <typename T, typename TValue> 1313 static inline void 1314 appendValue_(T & me, 1315 TValue SEQAN_FORWARD_CARG _value) 1316 { 1317 typedef typename Value<T>::Type TTargetValue; 1318 typedef typename Size<T>::Type TSize; 1319 1320 TSize me_length = length(me); 1321 if (capacity(me) <= me_length) 1322 { 1323 TTargetValue temp_copy(SEQAN_FORWARD(TValue, _value)); //temp copy because resize could invalidate _value 1324 // TODO(holtgrew): The resize() function will default construct the last element. This is slow. Get rid of this. 1325 TSize new_length = reserve(me, me_length + 1, TExpand()); 1326 if (me_length < new_length) 1327 { 1328 // *(begin(me) + me_length) = temp_copy; 1329 valueConstruct(begin(me, Standard()) + me_length, SEQAN_FORWARD(TTargetValue, temp_copy)); //??? this should be valueMoveConstruct 1330 _setLength(me, me_length + 1); 1331 } 1332 } 1333 else 1334 { 1335 valueConstruct(begin(me, Standard()) + me_length, SEQAN_FORWARD(TValue, _value)); 1336 _setLength(me, me_length + 1); 1337 } 1338 } 1339 }; 1340 1341 template <typename TTargetValue, typename TTargetSpec, typename TValue, typename TExpand> 1342 inline void 1343 appendValue(String<TTargetValue, TTargetSpec> & me, 1344 TValue SEQAN_FORWARD_CARG _value, 1345 Tag<TExpand>) 1346 { 1347 AppendValueToString_<Tag<TExpand> >::appendValue_(me, SEQAN_FORWARD(TValue, _value)); 1348 } 1349 1350 // ---------------------------------------------------------------------------- 1351 // Function appendValue(Serial) 1352 // ---------------------------------------------------------------------------- 1353 1354 template <typename TTargetValue, typename TTargetSpec, typename TValue, typename TExpand> 1355 inline void 1356 appendValue(String<TTargetValue, TTargetSpec> & me, 1357 TValue SEQAN_FORWARD_CARG _value, 1358 Tag<TExpand> const & expandTag, 1359 Serial) 1360 { 1361 appendValue(me, SEQAN_FORWARD(TValue, _value), expandTag); 1362 } 1363 1364 ////////////////////////////////////////////////////////////////////////////// 1365 // insertValue 1366 ////////////////////////////////////////////////////////////////////////////// 1367 1368 template <typename TExpand> 1369 struct InsertValueToString_ 1370 { 1371 template <typename T, typename TPosition, typename TValue> 1372 static inline void 1373 insertValue_(T & me, 1374 TPosition pos, 1375 TValue & _value) 1376 { 1377 typename Value<T>::Type temp_copy = _value; //temp copy because resizeSpace could invalidate _value 1378 resizeSpace(me, 1, pos, pos, TExpand()); 1379 if ((typename Size<T>::Type) pos < length(me)) 1380 moveValue(me, pos, temp_copy); 1381 } 1382 }; 1383 1384 template <typename TTargetValue, typename TTargetSpec, typename TPosition, typename TValue, typename TExpand> 1385 inline void 1386 insertValue(String<TTargetValue, TTargetSpec> & me, 1387 TPosition pos, 1388 TValue const & _value, 1389 Tag<TExpand>) 1390 { 1391 InsertValueToString_<Tag<TExpand> >::insertValue_(me, pos, _value); 1392 } 1393 1394 // ---------------------------------------------------------------------------- 1395 // Function replace() 1396 // ---------------------------------------------------------------------------- 1397 1398 template <typename TExpand> 1399 struct ReplaceString_ 1400 { 1401 template <typename TTarget, typename TSource> 1402 static inline void 1403 replace_(TTarget & target, 1404 typename Size<TTarget>::Type pos_begin, 1405 typename Size<TTarget>::Type pos_end, 1406 TSource & source) 1407 { 1408 if (!getObjectId(source) || !shareResources(target, source)) 1409 { 1410 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), pos_begin, pos_end, TExpand()); 1411 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard()) + pos_begin); 1412 } 1413 else 1414 { 1415 typename TempCopy_<TSource>::Type temp(source, length(source)); 1416 replace(target, pos_begin, pos_end, temp, TExpand()); 1417 } 1418 } 1419 1420 template <typename TTarget, typename TSource> 1421 static inline void 1422 replace_(TTarget & target, 1423 typename Size<TTarget>::Type pos_begin, 1424 typename Size<TTarget>::Type pos_end, 1425 TSource & source, 1426 typename Size<TTarget>::Type limit) 1427 { 1428 if (!getObjectId(source) || !shareResources(target, source)) 1429 { 1430 typename Size<TTarget>::Type part_length = _clearSpace(target, length(source), pos_begin, pos_end, limit, TExpand()); 1431 arrayConstructCopy(begin(source, Standard()), begin(source, Standard()) + part_length, begin(target, Standard()) + pos_begin); 1432 } 1433 else 1434 { 1435 if (pos_begin >= limit) 1436 { 1437 arrayDestruct(begin(target) + limit, end(target)); 1438 _setLength(target, limit); 1439 } 1440 else 1441 { 1442 limit -= pos_begin; 1443 typename Size<TTarget>::Type source_length = length(source) ; 1444 if (source_length > limit) source_length = limit; 1445 1446 typename TempCopy_<TSource>::Type temp(source, source_length); 1447 replace(target, pos_begin, pos_end, temp, limit, TExpand()); 1448 } 1449 } 1450 } 1451 1452 }; 1453 1454 template<typename TTargetValue, typename TTargetSpec, typename TPositionBegin, typename TPositionEnd, typename TSource, typename TExpand> 1455 inline void 1456 replace(String<TTargetValue, TTargetSpec> & target, 1457 TPositionBegin pos_begin, 1458 TPositionEnd pos_end, 1459 TSource const & source, 1460 Tag<TExpand>) 1461 { 1462 ReplaceString_<Tag<TExpand> >::replace_(target, pos_begin, pos_end, source); 1463 } 1464 1465 template<typename TTargetValue, typename TTargetSpec, typename TPositionBegin, typename TPositionEnd, typename TSource, typename TExpand> 1466 inline void 1467 replace(String<TTargetValue, TTargetSpec> & target, 1468 TPositionBegin pos_begin, 1469 TPositionEnd pos_end, 1470 TSource const & source, 1471 typename Size< String<TTargetValue, TTargetSpec> >::Type limit, 1472 Tag<TExpand>) 1473 { 1474 ReplaceString_<Tag<TExpand> >::replace_(target, pos_begin, pos_end, source, limit); 1475 } 1476 1477 // TODO(holtgrew): Still required with dropped VC++ 2003 support? 1478 //this variant is a workaround for the "const array"-bug of VC++ 1479 1480 template<typename TTargetValue, typename TTargetSpec, typename TPositionBegin, typename TPositionEnd, typename TSourceValue, typename TExpand> 1481 inline void 1482 replace(String<TTargetValue, TTargetSpec> & target, 1483 TPositionBegin pos_begin, 1484 TPositionEnd pos_end, 1485 TSourceValue const * source, 1486 Tag<TExpand>) 1487 { 1488 ReplaceString_<Tag<TExpand> >::replace_(target, pos_begin, pos_end, source); 1489 } 1490 1491 template<typename TTargetValue, typename TTargetSpec, typename TPositionBegin, typename TPositionEnd, typename TSourceValue, typename TExpand> 1492 inline void 1493 replace(String<TTargetValue, TTargetSpec> & target, 1494 TPositionBegin pos_begin, 1495 TPositionEnd pos_end, 1496 TSourceValue const * source, 1497 typename Size< String<TTargetValue, TTargetSpec> >::Type limit, 1498 Tag<TExpand>) 1499 { 1500 ReplaceString_<Tag<TExpand> >::replace_(target, pos_begin, pos_end, source, limit); 1501 } 1502 1503 // ---------------------------------------------------------------------------- 1504 // Internal Function _reallocateStorage() 1505 // ---------------------------------------------------------------------------- 1506 1507 template <typename TValue, typename TSpec, typename TSize> 1508 inline typename Value<String<TValue, TSpec> >::Type * 1509 _reallocateStorage( 1510 String<TValue, TSpec> & me, 1511 TSize new_capacity) 1512 { 1513 return _allocateStorage(me, new_capacity); 1514 } 1515 1516 template <typename TValue, typename TSpec, typename TSize> 1517 inline typename Value<String<TValue, TSpec> >::Type * 1518 _reallocateStorage( 1519 String<TValue, TSpec> & me, 1520 TSize new_capacity, 1521 Exact) 1522 { 1523 typedef typename Size<String<TValue, TSpec> >::Type TStringSize; 1524 if (static_cast<TStringSize>(new_capacity) <= capacity(me)) 1525 return 0; 1526 1527 return _reallocateStorage(me, new_capacity); 1528 } 1529 1530 template <typename TValue, typename TSpec, typename TSize, typename TSize2> 1531 inline typename Value<String<TValue, TSpec> >::Type * 1532 _reallocateStorage( 1533 String<TValue, TSpec> & me, 1534 TSize new_capacity, 1535 TSize2 limit, 1536 Exact) 1537 { 1538 typedef typename Size<String<TValue, TSpec> >::Type TStringSize; 1539 if (static_cast<TStringSize>(new_capacity) <= capacity(me)) 1540 return 0; 1541 1542 if (new_capacity > limit) new_capacity = limit; 1543 return _reallocateStorage(me, new_capacity); 1544 } 1545 1546 template <typename TValue, typename TSpec, typename TSize> 1547 inline typename Value<String<TValue, TSpec> >::Type * 1548 _reallocateStorage( 1549 String<TValue, TSpec> & me, 1550 TSize new_capacity, 1551 Generous) 1552 { 1553 typedef typename Size<String<TValue, TSpec> >::Type TStringSize; 1554 if (static_cast<TStringSize>(new_capacity) <= capacity(me)) 1555 return 0; 1556 1557 new_capacity = computeGenerousCapacity(me, new_capacity); 1558 return _reallocateStorage(me, new_capacity); 1559 } 1560 1561 template <typename TValue, typename TSpec, typename TSize, typename TSize2> 1562 inline typename Value<String<TValue, TSpec> >::Type * 1563 _reallocateStorage( 1564 String<TValue, TSpec> & me, 1565 TSize new_capacity, 1566 TSize2 limit, 1567 Generous) 1568 { 1569 typedef typename Size<String<TValue, TSpec> >::Type TStringSize; 1570 if (static_cast<TStringSize>(new_capacity) <= capacity(me)) 1571 return 0; 1572 1573 new_capacity = computeGenerousCapacity(me, new_capacity); 1574 if (new_capacity > limit) new_capacity = limit; 1575 return _reallocateStorage(me, new_capacity); 1576 } 1577 1578 template <typename TValue, typename TSpec, typename TSize> 1579 inline typename Value<String<TValue, TSpec> >::Type * 1580 _reallocateStorage( 1581 String<TValue, TSpec> &, 1582 TSize, 1583 Insist) 1584 { 1585 return 0; 1586 } 1587 1588 template <typename TValue, typename TSpec, typename TSize, typename TSize2> 1589 inline typename Value<String<TValue, TSpec> >::Type * 1590 _reallocateStorage( 1591 String<TValue, TSpec> &, 1592 TSize, 1593 TSize2, 1594 Insist) 1595 { 1596 return 0; 1597 } 1598 1599 template <typename TValue, typename TSpec, typename TSize> 1600 inline typename Value<String<TValue, TSpec> >::Type * 1601 _reallocateStorage( 1602 String<TValue, TSpec> &, 1603 TSize, 1604 Limit) 1605 { 1606 return 0; 1607 } 1608 1609 template <typename TValue, typename TSpec, typename TSize, typename TSize2> 1610 inline typename Value<String<TValue, TSpec> >::Type * 1611 _reallocateStorage( 1612 String<TValue, TSpec> &, 1613 TSize, 1614 TSize2, 1615 Limit) 1616 { 1617 return 0; 1618 } 1619 1620 // ---------------------------------------------------------------------------- 1621 // Function reserve() 1622 // ---------------------------------------------------------------------------- 1623 1624 template <typename TValue, typename TSpec, typename TSize_> 1625 inline void 1626 _reserveStorage( 1627 String<TValue, TSpec> & /*seq*/, 1628 TSize_ /*new_capacity*/, 1629 Insist) 1630 { 1631 // do nothing 1632 } 1633 1634 template <typename TValue, typename TSpec, typename TSize_> 1635 inline void 1636 _reserveStorage( 1637 String<TValue, TSpec> & /*seq*/, 1638 TSize_ /*new_capacity*/, 1639 Limit) 1640 { 1641 // do nothing 1642 } 1643 1644 template <typename TValue, typename TSpec, typename TSize_, typename TExpand> 1645 inline void 1646 _reserveStorage( 1647 String<TValue, TSpec> & seq, 1648 TSize_ new_capacity, 1649 Tag<TExpand> tag) 1650 { 1651 typedef typename Size< String<TValue, TSpec> >::Type TSize; 1652 1653 TSize old_capacity = capacity(seq); 1654 1655 // if (old_capacity == (TSize)new_capacity) return; 1656 // if (!IsSameType<TExpand,TagExact_>::VALUE && old_capacity > (TSize)new_capacity) return; 1657 if (old_capacity >= (TSize)new_capacity) return; 1658 1659 TSize seq_length = length(seq); 1660 typename Value< String<TValue, TSpec> >::Type * old_array = _reallocateStorage(seq, new_capacity, tag); 1661 if (old_array) 1662 {//buffer was replaced, destruct old buffer 1663 // arrayConstructCopy(old_array, old_array + seq_length, begin(seq, Standard())); 1664 arrayConstructMove(old_array, old_array + seq_length, begin(seq, Standard())); 1665 arrayDestruct(old_array, old_array + seq_length); 1666 _deallocateStorage(seq, old_array, old_capacity); 1667 } 1668 _setLength(seq, seq_length); 1669 } 1670 1671 template <typename TValue, typename TSpec, typename TSize_, typename TExpand> 1672 inline typename Size< String<TValue, TSpec> >::Type 1673 reserve( 1674 String<TValue, TSpec> & seq, 1675 TSize_ new_capacity, 1676 Tag<TExpand> tag) 1677 { 1678 _reserveStorage(seq, new_capacity, tag); 1679 return _capacityReturned(seq, new_capacity, tag); 1680 } 1681 1682 // ---------------------------------------------------------------------------- 1683 // Function resize() 1684 // ---------------------------------------------------------------------------- 1685 1686 template <typename TExpand> 1687 struct _Resize_String 1688 { 1689 template <typename T> 1690 static inline typename Size<T>::Type 1691 resize_( 1692 T & me, 1693 typename Size<T>::Type new_length) 1694 { 1695 typedef typename Size<T>::Type TSize; 1696 TSize me_length = length(me); 1697 if (new_length < me_length) 1698 { 1699 arrayDestruct(begin(me, Standard()) + new_length, begin(me, Standard()) + me_length); 1700 } 1701 else 1702 { 1703 typename Size<T>::Type me_capacity = capacity(me); 1704 if (new_length > me_capacity) 1705 { 1706 TSize new_capacity = reserve(me, new_length, TExpand()); 1707 if (new_capacity < new_length) 1708 { 1709 new_length = new_capacity; 1710 } 1711 } 1712 if (new_length > me_length) 1713 { 1714 arrayConstruct(begin(me, Standard()) + me_length, begin(me, Standard()) + new_length); 1715 } 1716 } 1717 1718 _setLength(me, new_length); 1719 return new_length; 1720 } 1721 1722 template <typename T, typename TValue> 1723 static inline typename Size<T>::Type 1724 resize_( 1725 T & me, 1726 typename Size<T>::Type new_length, 1727 TValue const & val) 1728 { 1729 typedef typename Size<T>::Type TSize; 1730 TSize me_length = length(me); 1731 if (new_length < me_length) 1732 { 1733 arrayDestruct(begin(me, Standard()) + new_length, begin(me, Standard()) + me_length); 1734 } 1735 else 1736 { 1737 TSize me_capacity = capacity(me); 1738 if (new_length > me_capacity) 1739 { 1740 TValue tempCopy = val; // reserve could invalidate val 1741 TSize new_capacity = reserve(me, new_length, TExpand()); 1742 if (new_capacity < new_length) 1743 { 1744 new_length = new_capacity; 1745 } 1746 arrayConstruct(begin(me, Standard()) + me_length, begin(me, Standard()) + new_length, tempCopy); 1747 } else 1748 if (new_length > me_length) 1749 { 1750 arrayConstruct(begin(me, Standard()) + me_length, begin(me, Standard()) + new_length, val); 1751 } 1752 } 1753 1754 _setLength(me, new_length); 1755 return new_length; 1756 } 1757 }; 1758 1759 template <typename TValue, typename TSpec, typename TSize, typename TExpand> 1760 inline typename Size< String<TValue, TSpec> >::Type 1761 resize( 1762 String<TValue, TSpec> & me, 1763 TSize new_length, 1764 Tag<TExpand>) 1765 { 1766 return _Resize_String<Tag<TExpand> >::resize_(me, new_length); 1767 } 1768 1769 template <typename TValue, typename TSpec, typename TSize, typename TValue2, typename TExpand> 1770 inline typename Size< String<TValue, TSpec> >::Type 1771 resize( 1772 String<TValue, TSpec> & me, 1773 TSize new_length, 1774 TValue2 const & val, 1775 Tag<TExpand>) 1776 { 1777 return _Resize_String<Tag<TExpand> >::resize_(me, new_length, val); 1778 } 1779 1780 // ---------------------------------------------------------------------------- 1781 // Function operator+=(), shortcut to append() 1782 // ---------------------------------------------------------------------------- 1783 1784 // TODO(holtgrew): Maybe move to a string_shortcuts.h? 1785 1786 template <typename TLeftValue, typename TLeftSpec, typename TRight > 1787 inline 1788 String<TLeftValue, TLeftSpec> & 1789 operator+=(String<TLeftValue, TLeftSpec> & left, 1790 TRight const & right) 1791 { 1792 append(left, right); 1793 return left; 1794 } 1795 1796 // The comparator functions forward to the code in sequence_lexical.h. 1797 1798 // ---------------------------------------------------------------------------- 1799 // Function operator==() 1800 // ---------------------------------------------------------------------------- 1801 1802 template <typename TLeftValue, typename TLeftSpec, typename TRight > 1803 inline bool 1804 operator==(String<TLeftValue, TLeftSpec> const & left, 1805 TRight const & right) 1806 { 1807 typename Comparator<String<TLeftValue, TLeftSpec> >::Type _lex(left, right); 1808 return isEqual(_lex); 1809 } 1810 1811 template <typename TLeftValue, typename TRightValue, typename TRightSpec > 1812 inline bool 1813 operator==(TLeftValue * left, 1814 String<TRightValue, TRightSpec> const & right) 1815 { 1816 typename Comparator<String<TRightValue, TRightSpec> >::Type _lex(left, right); 1817 return isEqual(_lex); 1818 } 1819 1820 // ---------------------------------------------------------------------------- 1821 // Function operator!=() 1822 // ---------------------------------------------------------------------------- 1823 1824 template <typename TLeftValue, typename TLeftSpec, typename TRight > 1825 inline bool 1826 operator!=(String<TLeftValue, TLeftSpec> const & left, 1827 TRight const & right) 1828 { 1829 typename Comparator<String<TLeftValue, TLeftSpec> >::Type _lex(left, right); 1830 return isNotEqual(_lex); 1831 } 1832 1833 template <typename TLeftValue, typename TRightValue, typename TRightSpec > 1834 inline bool 1835 operator!=(TLeftValue * left, 1836 String<TRightValue, TRightSpec> const & right) 1837 { 1838 typename Comparator<String<TRightValue, TRightSpec> >::Type _lex(left, right); 1839 return isNotEqual(_lex); 1840 } 1841 1842 // ---------------------------------------------------------------------------- 1843 // Function operator<() 1844 // ---------------------------------------------------------------------------- 1845 1846 template <typename TLeftValue, typename TLeftSpec, typename TRight> 1847 inline bool 1848 operator<(String<TLeftValue, TLeftSpec> const & left, 1849 TRight const & right) 1850 { 1851 return isLess(left, right, typename DefaultPrefixOrder<String<TLeftValue, TLeftSpec> >::Type()); 1852 } 1853 1854 template <typename TLeftValue, typename TRightValue, typename TRightSpec > 1855 inline bool 1856 operator<(TLeftValue * left, 1857 String<TRightValue, TRightSpec> const & right) 1858 { 1859 return isLess(left, right, typename DefaultPrefixOrder<TLeftValue *>::Type()); 1860 } 1861 1862 // ---------------------------------------------------------------------------- 1863 // Function operator<=() 1864 // ---------------------------------------------------------------------------- 1865 1866 template <typename TLeftValue, typename TLeftSpec, typename TRight> 1867 inline bool 1868 operator<=(String<TLeftValue, TLeftSpec> const & left, 1869 TRight const & right) 1870 { 1871 return isLessOrEqual(left, right, typename DefaultPrefixOrder<String<TLeftValue, TLeftSpec> >::Type()); 1872 } 1873 1874 template <typename TLeftValue, typename TRightValue, typename TRightSpec > 1875 inline bool 1876 operator<=(TLeftValue * left, 1877 String<TRightValue, TRightSpec> const & right) 1878 { 1879 return isLessOrEqual(left, right, typename DefaultPrefixOrder<TLeftValue *>::Type()); 1880 } 1881 1882 // ---------------------------------------------------------------------------- 1883 // Function operator>() 1884 // ---------------------------------------------------------------------------- 1885 1886 template <typename TLeftValue, typename TLeftSpec, typename TRight> 1887 inline bool 1888 operator>(String<TLeftValue, TLeftSpec> const & left, 1889 TRight const & right) 1890 { 1891 return isGreater(left, right, typename DefaultPrefixOrder<String<TLeftValue, TLeftSpec> >::Type()); 1892 } 1893 template <typename TLeftValue, typename TRightValue, typename TRightSpec > 1894 inline bool 1895 operator>(TLeftValue * left, 1896 String<TRightValue, TRightSpec> const & right) 1897 { 1898 return isGreater(left, right, typename DefaultPrefixOrder<TLeftValue *>::Type()); 1899 } 1900 1901 // ---------------------------------------------------------------------------- 1902 // Function operator>=() 1903 // ---------------------------------------------------------------------------- 1904 1905 template <typename TLeftValue, typename TLeftSpec, typename TRight> 1906 inline bool 1907 operator>=(String<TLeftValue, TLeftSpec> const & left, 1908 TRight const & right) 1909 { 1910 return isGreaterOrEqual(left, right, typename DefaultPrefixOrder<String<TLeftValue, TLeftSpec> >::Type()); 1911 } 1912 template <typename TLeftValue, typename TRightValue, typename TRightSpec> 1913 inline bool 1914 operator>=(TLeftValue * left, 1915 String<TRightValue, TRightSpec> const & right) 1916 { 1917 return isGreaterOrEqual(left, right, typename DefaultPrefixOrder<TLeftValue *>::Type()); 1918 } 1919 1920 // ---------------------------------------------------------------------------- 1921 // Function beginPosition() 1922 // ---------------------------------------------------------------------------- 1923 1924 /*! 1925 * @fn String#beginPosition 1926 * @headerfile <seqan/sequence.h> 1927 * @brief Return 0 for compatibility with @link Segment @endlink. 1928 * 1929 * @signature TPos beginPosition(str); 1930 * 1931 * @param[in] seg The String to use. 1932 * 1933 * @return TPos Always 0. 1934 */ 1935 1936 1937 // ---------------------------------------------------------------------------- 1938 // Function endPosition() 1939 // ---------------------------------------------------------------------------- 1940 1941 /*! 1942 * @fn String#endPosition 1943 * @headerfile <seqan/sequence.h> 1944 * @brief Return length of string for compatibility with @link Segment @endlink. 1945 * 1946 * @signature TPos endPosition(str); 1947 * 1948 * @param[in] seg The string to use. 1949 * 1950 * @return TPos Length of the string. 1951 */ 1952 1953 // ---------------------------------------------------------------------------- 1954 // Function reserveChunk() 1955 // ---------------------------------------------------------------------------- 1956 1957 template <typename TValue, typename TSpec, typename TSize> 1958 inline void reserveChunk(String<TValue, TSpec> &str, TSize size, Output) 1959 { 1960 reserve(str, length(str) + size); 1961 } 1962 1963 template <typename TValue, typename TSpec, typename TSize> 1964 inline void reserveChunk(String<TValue, TSpec> const &, TSize, Input) 1965 {} 1966 1967 // ---------------------------------------------------------------------------- 1968 // Function getChunk() 1969 // ---------------------------------------------------------------------------- 1970 1971 template <typename TChunk, typename TValue, typename TSpec> 1972 inline void 1973 getChunk(TChunk &result, String<TValue, TSpec> &cont, Output) 1974 { 1975 return assignRange(result, end(cont, Standard()), begin(cont, Standard()) + capacity(cont)); 1976 } 1977 1978 // ---------------------------------------------------------------------------- 1979 // Function advanceChunk() 1980 // ---------------------------------------------------------------------------- 1981 1982 // extend target string size 1983 template <typename TValue, typename TSpec, typename TSize> 1984 inline void advanceChunk(String<TValue, TSpec> &str, TSize size) 1985 { 1986 _setLength(str, length(str) + size); 1987 } 1988 1989 template <typename TValue, typename TStringSpec, typename TSpec, typename TSize> 1990 inline void advanceChunk(Iter<String<TValue, TStringSpec>, TSpec> &iter, TSize size) 1991 { 1992 typedef String<TValue, TStringSpec> TContainer; 1993 typedef Iter<TContainer, TSpec> TIter; 1994 1995 iter += size; 1996 1997 TContainer &cont = container(iter); 1998 typename Position<TIter>::Type pos = position(iter); 1999 2000 if (pos > length(cont)) 2001 _setLength(cont, pos); 2002 } 2003 2004 // ---------------------------------------------------------------------------- 2005 // Function operator<<() for streams. 2006 // ---------------------------------------------------------------------------- 2007 2008 template <typename TStream, typename TValue, typename TSpec> 2009 inline TStream & 2010 operator<<(TStream & target, 2011 String<TValue, TSpec> const & source) 2012 { 2013 typename DirectionIterator<TStream, Output>::Type it = directionIterator(target, Output()); 2014 write(it, source); 2015 return target; 2016 } 2017 2018 // ---------------------------------------------------------------------------- 2019 // Function operator>>() for streams. 2020 // ---------------------------------------------------------------------------- 2021 2022 template <typename TStream, typename TValue, typename TSpec> 2023 inline TStream & 2024 operator>>(TStream & source, 2025 String<TValue, TSpec> & target) 2026 { 2027 typename DirectionIterator<TStream, Input>::Type it = directionIterator(source, Input());; 2028 read(it, target); 2029 return source; 2030 } 2031 2032 // ---------------------------------------------------------------------------- 2033 // Function assignValueById 2034 // ---------------------------------------------------------------------------- 2035 2036 template<typename TValue, typename TSpec, typename TId, typename TValue2> 2037 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TId> >, void) 2038 assignValueById(String<TValue, TSpec> & me, 2039 TId id, 2040 TValue2 const & obj) 2041 { 2042 if (length(me) <= id) 2043 resize(me, id + 1, TValue()); 2044 assignValue(me, id, obj); 2045 } 2046 2047 // ---------------------------------------------------------------------------- 2048 // Function getValueById 2049 // ---------------------------------------------------------------------------- 2050 2051 template<typename TValue, typename TSpec, typename TId> 2052 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TId> >, TValue) 2053 getValueById(String<TValue, TSpec> & me, 2054 TId id) 2055 { 2056 if (id < length(me)) 2057 return getValue(me, id); 2058 else 2059 return TValue(); 2060 } 2061 2062 } // namespace seqan 2063 2064 #endif // #ifndef SEQAN_SEQUENCE_STRING_ARRAY_BASE_H_ 2065