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 &gt;= 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 &lt;= 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 &lt;= 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&lt;T&gt;::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>&lt;typeof(value)&gt;</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