1 // ========================================================================== 2 // SeqAn - The Library for Sequence Analysis 3 // ========================================================================== 4 // Copyright (c) 2006-2018, 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: David Weese <david.weese@fu-berlin.de> 33 // Author: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de> 34 // ========================================================================== 35 // Concept definitions for alphabets. 36 // ========================================================================== 37 38 // SEQAN_NO_GENERATED_FORWARDS 39 40 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_CONCEPT_H_ 41 #define SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_CONCEPT_H_ 42 43 namespace seqan { 44 45 // ============================================================================ 46 // Concepts for generic alphabets 47 // ============================================================================ 48 49 /*! 50 * @concept AlphabetConcept 51 * @extends AssignableConcept 52 * @extends DefaultConstructibleConcept 53 * @extends CopyConstructibleConcept 54 * @headerfile <seqan/basic.h> 55 * @brief Natural container value. 56 * 57 * @signature concept AlphabetConcept; 58 * 59 * @section Examples 60 * 61 * Valid expressions (<tt>v</tt> is of type <tt>T</tt>): 62 * 63 * @code{.cpp} 64 * unsigned bpv = BitsPerValue<T>::VALUE; 65 * @endcode 66 */ 67 68 /*! 69 * @mfn AlphabetConcept#BitsPerValue 70 * @headerfile <seqan/basic.h> 71 * @brief Number of bits needed to store a value. 72 * 73 * @signature BitsPerValue<T>::VALUE 74 * 75 * @tparam T A class. 76 * 77 * @return VALUE The number of bits needed to store a value. 78 */ 79 80 // Forwards for Metafunctions and Functions. 81 template <typename T> struct BitsPerValue; 82 83 // minimal requirements for the alphabet of a String class 84 SEQAN_CONCEPT_REFINE(AlphabetConcept, (TValue), (Assignable)(DefaultConstructible)(CopyConstructible)) 85 { 86 typedef typename BitsPerValue<TValue>::Type TBitsPerValue; 87 88 TValue val, val2; 89 SEQAN_CONCEPT_USAGE(AlphabetConcept)90 SEQAN_CONCEPT_USAGE(AlphabetConcept) 91 { 92 SEQAN_STATIC_ASSERT_MSG(BitsPerValue<TValue>::VALUE != 0, "Alphabet types must implement the BitsPerValue metafunction with non-zero value."); 93 94 // assign must be available as an equivalent to '=' 95 assign(val, val2); 96 // swap(val, val2); 97 98 TBitsPerValue b = BitsPerValue<TValue>::VALUE; 99 100 ignoreUnusedVariableWarning(b); 101 } 102 }; 103 104 // ============================================================================ 105 // Concepts For Alphabets From The Mathematics Domain. 106 // ============================================================================ 107 108 /*! 109 * @concept OrderedAlphabetConcept 110 * @extends AlphabetConcept 111 * @extends ComparableConcept 112 * @headerfile <seqan/basic.h> 113 * 114 * @brief Totally strict ordered alphabet. 115 * 116 * @signature concept OrderedAlphabetConcept; 117 */ 118 119 /*! 120 * @fn OrderedAlphabetConcept::operator< 121 * @brief Less-than operator. 122 * 123 * @signature bool OrderedAlphabetConcept::operator<(other); 124 * 125 * @param[in] other Object of the same type to compare to this. 126 * 127 * @return bool True in case of this object being smaller than <tt>other</tt> 128 */ 129 130 /*! 131 * @mfn OrderedAlphabetConcept#MaxValue 132 * @headerfile <seqan/basic.h> 133 * @brief Supremum for a given type. 134 * 135 * @signature MaxValue<T>::VALUE 136 * 137 * @tparam T An ordered type. 138 * 139 * @return VALUE The largest value that <tt>T</tt> can represent. 140 * 141 * @see OrderedAlphabetConcept#maxValue 142 */ 143 144 /*! 145 * @mfn OrderedAlphabetConcept#MinValue 146 * @headerfile <seqan/basic.h> 147 * @brief Infimum for a given type. 148 * 149 * @signature MinValue<T>::VALUE 150 * 151 * @tparam T An ordered type. 152 * 153 * @return VALUE The smallest value that <tt>T</tt> can represent. 154 * 155 * @see OrderedAlphabetConcept#minValue 156 */ 157 158 /*! 159 * @fn OrderedAlphabetConcept#supremumValueImpl 160 * @brief Implements maxValue. 161 * 162 * @signature T supremumValueImpl(valuePointerTag); 163 * 164 * @param[in] valuePointerTag A pointer that is used as a tag to specify the value type. The pointer needs not to point 165 * to a valid object, so it is possible to use a null pointer here. 166 * 167 * @return T A value <tt>inf</tt> that holds: <tt>inf >= i</tt> for all values <tt>i</tt>. 168 * 169 * This function implements OrderedAlphabetConcept#maxValue. It is recommended to use OrderedAlphabetConcept#maxValue 170 * rather than <tt>supremumValueImpl</tt>. 171 * 172 * @section Status 173 * 174 * @deprecated Will be removed in favour of MaxValue. 175 * 176 * @see OrderedAlphabetConcept#maxValue 177 */ 178 179 /*! 180 * @fn OrderedAlphabetConcept#maxValue 181 * @brief Supremum for a given type. 182 * 183 * @signature T maxValue<T>(); 184 * 185 * @tparam T The type to get the max value of. 186 * 187 * @return T A value <tt>inf</tt> that holds: <tt>inf >= i</tt> for all values <tt>i</tt> of type <tt>T</tt>. 188 * 189 * The function is implemented in supremumValueImpl. Do not specialize <tt>maxValue</tt>, specialize supremumValueImpl 190 * instead! 191 * 192 * @section Status 193 * 194 * @deprecated Will be removed in favour of MaxValue. 195 * 196 * @see OrderedAlphabetConcept#supremumValueImpl 197 * @see OrderedAlphabetConcept#minValue 198 * @see OrderedAlphabetConcept#MaxValue 199 */ 200 201 /*! 202 * @fn OrderedAlphabetConcept#infimumValueImpl 203 * @brief Implements minValue. 204 * 205 * @signature T infimumValueImpl(valuePointerTag); 206 * 207 * @param[in] valuePointerTag A pointer that is used as a tag to specify the value type. The pointer needs not to point 208 * to a valid object, so it is possible to use a null pointer here. 209 * 210 * @return T A value <tt>inf</tt> that holds: <tt>inf <= i</tt> for all values <tt>i</tt>. 211 * 212 * This function implements minValue. It is recommended to use minValue rather than <tt>infimumValueImpl</tt>. 213 * 214 * @section Status 215 * 216 * @deprecated Will be removed in favour of MinValue. 217 * 218 * @see OrderedAlphabetConcept#minValue 219 */ 220 221 /*! 222 * @fn OrderedAlphabetConcept#minValue 223 * @brief Infimum for a given type. 224 * 225 * @signature T minValue<T>(); 226 * 227 * @tparam T An ordered type. 228 * 229 * @return T A value <tt>inf</tt> that holds: <tt>inf <= i</tt> for all values <tt>i</tt> of type <tt>T</tt>. 230 * 231 * The function is implemented in infimumValueImpl. Do not specialize <tt>minValue</tt>, specialize infimumValueImpl 232 * instead! 233 * 234 * @section Status 235 * 236 * @deprecated Will be removed in favour of MinValue. 237 * 238 * @see OrderedAlphabetConcept#infimumValueImpl 239 * @see OrderedAlphabetConcept#maxValue 240 * @see OrderedAlphabetConcept#MinValue 241 */ 242 243 // Forwards for Metafunctions and Functions. 244 template <typename T> struct MinValue; 245 template <typename T> struct MaxValue; 246 template <typename T> T minValue(); 247 template <typename T> T minValue(T); 248 template <typename T> T maxValue(); 249 template <typename T> T maxValue(T); 250 251 SEQAN_CONCEPT_REFINE(OrderedAlphabetConcept, (TValue), (AlphabetConcept)(Comparable)) 252 { 253 TValue val; 254 SEQAN_CONCEPT_USAGE(OrderedAlphabetConcept)255 SEQAN_CONCEPT_USAGE(OrderedAlphabetConcept) 256 { 257 // type consistency checks 258 // sameType(minValue(val), val); // minValue() is deprecated 259 // sameType(minValue<TValue>(), val); // minValue() is deprecated 260 sameType(MinValue<TValue>::VALUE, val); 261 // sameType(maxValue(val), val); // maxValue() is deprecated 262 // sameType(maxValue<TValue>(), val); // maxValue() is deprecated 263 sameType(MaxValue<TValue>::VALUE, val); 264 265 // TODO(holtgrew): This does not work in C++98, we need C++11 with constexpr. 266 // TODO(holtgrew): Do these tests for each alphabet in runtime tests. 267 // sanity checks 268 // SEQAN_STATIC_ASSERT_MSG(MinValue<TValue>::VALUE <= MaxValue<TValue>::VALUE, "Minimal alphabet value must be less or equal to the maximal value."); 269 270 // TODO(holtgrew): This does not work in C++98, we need C++11 with constexpr, cannot cast non-integral and non-enumeration types at compile time in C++98. 271 // 0 must be an element of the alphabet, as we want to be able 272 // to initialize a TValue variable to omit uninitialized warnings. 273 // SEQAN_STATIC_ASSERT_MSG(MinValue<TValue>::VALUE <= static_cast<TValue>(0), "0 must be convertible to a valid alphabet value."); 274 // SEQAN_STATIC_ASSERT_MSG(static_cast<TValue>(0) <= MaxValue<TValue>::VALUE, "0 must be convertible to a valid alphabet value."); 275 } 276 }; 277 278 /*! 279 * @concept FiniteOrderedAlphabetConcept 280 * @headerfile <seqan/basic.h> 281 * @extends OrderedAlphabetConcept 282 * @brief An type that is of finite domain and totally ordered and thus has a minimum and maximum value. 283 */ 284 285 /*! 286 * @mfn FiniteOrderedAlphabetConcept#ValueSize 287 * @brief Number of different values a value type object can have. 288 * 289 * @signature ValueSize<T>::Type; 290 * @signature ValueSize<T>::VALUE; 291 * 292 * @tparam T A type to query for its value size. 293 * 294 * @return VALUE The number of different values a value of type T can have. The type is <tt>Type</tt>. 295 * @return Type The type of the result <tt>VALUE</tt>. 296 * 297 * This function is only defined for integral types like <tt>unsigned</tt>, <tt>int</tt>, or Dna. For floating point 298 * numbers and the 64 bit types <tt>int64_t</tt> and <tt>uint64_t</tt>, it returns 0 since there is no standard 299 * compliant way to return the number of values for these types. 300 * 301 * Note that you cannot get pointers or references to <tt>ValueSize<T>::VALUE</tt> in your program. You can use 302 * @link FiniteOrderedAlphabetConcept#valueSize @endlink in your programs without problems, though. When you get 303 * problems in your tests, use the "unary plus" workaround from the examples section. 304 * 305 * @section Examples 306 * 307 * The temporary assignment workaround. 308 * 309 * @code{.cpp} 310 * SEQAN_ASSERT_EQ(ValueSize<bool>::VALUE, 2u); // Linker error. 311 * SEQAN_ASSERT_EQ(+ValueSize<bool>::VALUE, 2u); // OK 312 * SEQAN_ASSERT_EQ(valueSize<bool>(), 2u); // OK 313 * @endcode 314 */ 315 316 /*! 317 * @fn FiniteOrderedAlphabetConcept#ordValue 318 * @headerfile <seqan/sequence.h> 319 * @brief Maps an alphabet 1-to-1 to the interval [0..ValueSize). 320 * 321 * @signature T ordValue(value); 322 * 323 * @param[in] value Arbitrary character value. Types: SimpleType 324 * 325 * @return T An unsigned value (result of Size<tt><typeof(value)></tt> between 0 and ValueSize of the type of value. 326 * 327 * This function first converts value to its unsigned value type and after that to an <tt>unsigned int</tt>. You can't 328 * use <tt>(unsigned int)c</tt> for a character <tt>c</tt> as on some systems <tt>char</tt> is signed and a <tt>-1</tt> 329 * would be mapped to <tt>0xffffffff</tt> instead of <tt>0x000000ff</tt>. 330 */ 331 332 /*! 333 * @fn FiniteOrderedAlphabetConcept#valueSize 334 * @brief Returns size of an alphabet. 335 * 336 * @signature T1 valueSize<T2>(); 337 * 338 * @tparam T2 Type to query for value size. 339 * 340 * @return T1 Number of values in type <tt>T2</tt>. 341 * 342 * @see FiniteOrderedAlphabetConcept#ValueSize 343 */ 344 345 // Forwards for Metafunctions and Functions. 346 template <typename T> struct ValueSize; 347 template <typename T> typename ValueSize<T>::Type valueSize(); 348 // Forwards for Metafunctions and Functions. 349 template <typename TValue> inline typename ValueSize<TValue>::Type ordValue(TValue const & c); 350 351 SEQAN_CONCEPT_REFINE(FiniteOrderedAlphabetConcept, (TValue), (OrderedAlphabetConcept)) 352 { 353 typedef typename ValueSize<TValue>::Type TSize; 354 355 TValue val; 356 TSize size; 357 358 SEQAN_CONCEPT_ASSERT((UnsignedIntegerConcept<TSize>)); 359 SEQAN_CONCEPT_USAGE(FiniteOrderedAlphabetConcept)360 SEQAN_CONCEPT_USAGE(FiniteOrderedAlphabetConcept) 361 { 362 // a finite alphabet must be countable 363 sameType(ordValue(val), size); 364 sameType(valueSize<TValue>(), size); 365 sameType(ValueSize<TValue>::VALUE, size); 366 367 // alphabet must be non-empty 368 SEQAN_STATIC_ASSERT_MSG(static_cast<TSize>(0) < ValueSize<TValue>::VALUE, "Alphabet size be greater than zero."); 369 370 // convert integer to alphabet value 371 val = 0; 372 val = size; 373 TValue val2(0); 374 TValue val3(size); 375 376 ignoreUnusedVariableWarning(val2); 377 ignoreUnusedVariableWarning(val3); 378 } 379 }; 380 381 // ============================================================================ 382 // Concepts For Alphabets From The Bioinformatics Domain. 383 // ============================================================================ 384 /*! 385 * @concept AlphabetWithGapsConcept 386 * @extends AlphabetConcept 387 * @headerfile <seqan/basic.h> 388 * 389 * @brief An alphabet that includes a specific gap character. 390 */ 391 392 /*! 393 * @fn AlphabetWithGapsConcept#gapValueImpl 394 * @brief Implements gapValue. 395 * 396 * @signature T gapValueImpl(valuePointerTag); 397 * 398 * @param[in] valuePointerTag A pointer that is used as a tag to specify the value type. The pointer needs not to 399 * point to a valid object, so it is possible to use a null pointer here. 400 * 401 * @return T A gap character. 402 * 403 * This function implements gapValue. It is recommended to use gapValue rather than <tt>gapValueImpl</tt>. 404 * 405 * @see AlphabetWithGapsConcept#gapValue 406 */ 407 408 /*! 409 * @fn AlphabetWithGapsConcept#gapValue 410 * @brief Return the "gap" value from an alphabet. 411 * 412 * @signature T gapValue<T>(); 413 * 414 * @tparam T The alphabet type to query the gap value from. 415 * 416 * @return T The gap character. 417 * 418 * The function is implemented in gapValueImpl. Do not specialize <tt>gapValue</tt>, specialize link gapValueImpl 419 * instead! 420 * 421 * @see AlphabetWithGapsConcept#gapValueImpl 422 */ 423 424 // Forwards for Metafunctions and Functions. 425 template <typename T> T gapValue(); 426 template <typename T> T gapValueImpl(T *); 427 428 SEQAN_CONCEPT_REFINE(AlphabetWithGapsConcept, (TValue), (AlphabetConcept)) 429 { 430 TValue val; 431 SEQAN_CONCEPT_USAGE(AlphabetWithGapsConcept)432 SEQAN_CONCEPT_USAGE(AlphabetWithGapsConcept) 433 { 434 // Test the availability and return type of gapValue() and gapValueImpl(). 435 sameType(gapValue<TValue>(), val); 436 sameType(gapValueImpl<TValue>(static_cast<TValue *>(0)), val); 437 } 438 }; 439 440 /*! 441 * @concept AlphabetWithUnknownValueConcept 442 * @extends AlphabetConcept 443 * @headerfile <seqan/basic.h> 444 * 445 * @brief An alphabet which includes a specific "unknown" character. 446 */ 447 448 /*! 449 * @fn AlphabetWithUnknownValueConcept#unknownValue 450 * 451 * @brief Return the "unknown" value from an alphabet. 452 * 453 * @signature T unknownValue<T>(); 454 * 455 * @tparam T The alphabet type to query the unknown value from. 456 * 457 * @return TReturn The "unknown" value. 458 * 459 * @see AlphabetWithUnknownValueConcept#unknownValueImpl 460 */ 461 462 /*! 463 * @fn AlphabetWithUnknownValueConcept#unknownValueImpl 464 * @brief Implements unknownValue. 465 * 466 * @signature T gapValueImpl(valuePointerTag) 467 * 468 * @param[in] valuePointerTag A pointer that is used as a tag to specify the value type. The pointer needs not to 469 * point to a valid object, so it is possible to use a null pointer here. 470 * 471 * @return TReturn A "unknown" character. 472 * 473 * This function implements unknownValue. It is recommended to use gapValue rather than <tt>gapValueImpl</tt>. 474 * 475 * @see AlphabetWithUnknownValueConcept#unknownValue 476 */ 477 478 // Forwards for Metafunctions and Functions. 479 template <typename T> T unknownValue(); 480 template <typename T> T unknownValueImpl(T *); 481 482 SEQAN_CONCEPT_REFINE(AlphabetWithUnknownValueConcept, (TValue), (AlphabetConcept)) 483 { 484 TValue val; 485 SEQAN_CONCEPT_USAGE(AlphabetWithUnknownValueConcept)486 SEQAN_CONCEPT_USAGE(AlphabetWithUnknownValueConcept) 487 { 488 // Test the availability and return type of unknownValue() and unknownValueImpl(). 489 sameType(unknownValue<TValue>(), val); 490 sameType(unknownValueImpl<TValue>(static_cast<TValue *>(0)), val); 491 } 492 }; 493 494 /*! 495 * @concept AlphabetWithQualitiesConcept 496 * @extends AlphabetConcept 497 * @headerfile <seqan/basic.h> 498 * 499 * @brief An alphabet where qualities can be attached to the characters. 500 */ 501 502 /*! 503 * @mfn AlphabetWithQualitiesConcept#HasQualities 504 * @headerfile <seqan/basic.h> 505 * @brief Return whether the given type stores qualities besides the alphabet. 506 * 507 * @signature HasQualities<TAlphabet>::VALUE; 508 * @signature HasQualities<TAlphabet>::Type; 509 * 510 * @tparam TAlphabet The alphabe to query. 511 * 512 * @return VALUE <tt>true</tt> or <tt>false</tt> 513 * @return Type <tt>True</tt> or <tt>False</tt> 514 */ 515 516 /*! 517 * @mfn AlphabetWithQualitiesConcept#QualityValueSize 518 * @brief Return the number of quality values in characters from alphabet with qualities. 519 * 520 * @signature QualityValueSize<TAlphabet>::VALUE; 521 * 522 * @tparam TAlphabet The alphabet to query for its value size. 523 * 524 * @return VALUE The cardinality of the set of qualities. 525 */ 526 527 /*! 528 * @fn AlphabetWithQualitiesConcept#getQualityValue 529 * @brief Returns the quality of a character from an alphabet with integrated quality, e.g. the quality associated with 530 * a specified element from a sequence. 531 * @signature int getQualityValue(c); 532 * 533 * @param[in] c Character to retrieve the quality from. 534 * 535 * @return int Quality value of <tt>c</tt>. The quality value is an <tt>int</tt> value between 0 and 62 (inclusive). 536 * 537 * @section Examples 538 * 539 * @code{.cpp} 540 * String<Dna5Q> seq = "TATA"; 541 * // Assign quality value to first 'T' in sequence seq 542 * assignQualityValue(seq[0], 35); 543 * // Print quality value of first 'T', and default quality value of first 'A' 544 * std::cout << getQualityValue(seq[0]) << std::endl; // Defined as 35 545 * std::cout << getQualityValue(seq[1]) << std::endl; // Default value 60 546 * @endcode 547 * 548 * @see AlphabetWithQualitiesConcept#assignQualityValue 549 * @see convertQuality 550 */ 551 552 /*! 553 * @fn AlphabetWithQualitiesConcept#assignQualityValue 554 * @brief Assigns quality to a character from an alphabet with integrated quality, e.g. to a specified element from a 555 * sequence. 556 * 557 * @signature void assignQualityValue(c, q); 558 * 559 * @param[out] c Target character to assign quality to. 560 * @param[in] q Quality to assign to the character. The quality value is an integral value between 0 and 62 561 * (inclusive). 562 * 563 * If <tt>q</tt> is a <tt>char</tt> then <tt>'!'</tt> is subtracted from <tt>q</tt>. This is useful for ASCII encoded 564 * PHRED scores. 565 * 566 * @see AlphabetWithQualitiesConcept#getQualityValue 567 * @see convertQuality 568 * @see assignQualities 569 */ 570 571 // TODO(holtgrew): What about different quality types? Guess scaling? Look at how other packages do this. 572 573 SEQAN_CONCEPT_REFINE(AlphabetWithQualitiesConcept, (TValue), (AlphabetConcept)) 574 { 575 TValue val; 576 SEQAN_CONCEPT_USAGE(AlphabetWithQualitiesConcept)577 SEQAN_CONCEPT_USAGE(AlphabetWithQualitiesConcept) 578 { 579 // TODO(holtgrew): Write me! 580 } 581 }; 582 583 584 } // namespace seqan 585 586 #endif // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_CONCEPT_H_ 587