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: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de>
33 // ==========================================================================
34 // Basic comparison code.
35 // ==========================================================================
36 
37 #ifndef SEQAN_INCLUDE_SEQAN_FUNDAMENTAL_COMPARISON_H_
38 #define SEQAN_INCLUDE_SEQAN_FUNDAMENTAL_COMPARISON_H_
39 
40 namespace seqan {
41 
42 // ============================================================================
43 // Forwards
44 // ============================================================================
45 
46 // Forwards for Metafunctions and Functions.
47 template <typename T> struct ValueSize;
48 template <typename T> inline typename ValueSize<T>::Type valueSize();
49 // Forwards for Metafunctions and Functions.
50 template <typename TValue> inline typename ValueSize<TValue>::Type ordValue(TValue const & c);
51 
52 // ============================================================================
53 // Tags, Classes, Enums
54 // ============================================================================
55 
56 // ============================================================================
57 // Metafunctions
58 // ============================================================================
59 
60 /*!
61  * @mfn CompareType
62  * @headerfile <seqan/basic.h>
63  * @brief Type to convert other types for comparisons.
64  *
65  * @signature CompareType<T1, T2>::Type;
66  *
67  * @tparam T2 Type of the right operand of a comparison.
68  * @tparam T1 Type of the left operand of a comparison.
69  *
70  * @return Type The resulting type to convert other type to.
71  *
72  * Comparisons are for example operators like <tt>==</tt> or <tt>&lt;</tt>.
73  *
74  * Do not implement, implement CompareTypeImpl instead.
75  *
76  * Note that there is no rule that guarantees that <tt>CompareType&lt;T1, T2&gt;::Type</tt> is the same as
77  * <tt>CompareType&lt;T2, T1&gt;::Type</tt>.  It is also possible, that only one of these two types is defined.
78  *
79  * This metafunction is used for the implementation of comparisons that involve SimpleType.
80  *
81  * @see CompareTypeImpl
82  */
83 
84 /*!
85  * @mfn CompareTypeImpl
86  * @headerfile <seqan/basic.h>
87  * @brief Implementation of CompareType.
88  *
89  * @signature CompareTypeImpl<T1, T2>::Type;
90  *
91  * @tparam T2 Type of the right operand of a comparison.
92  * @tparam T1 Type of the left operand of a comparison.
93  *
94  * @return Type The type to use for the comparison.
95  *
96  * @see CompareType
97  */
98 
99 // Given two types, the CompareType is a type that both types can be cast to
100 // and where the results are then used to compare two values.
101 
102 // step 3: choose the actual comparison type
103 template <typename T1, typename T2>
104 struct CompareTypeImpl;
105 
106 template <typename T>
107 struct CompareTypeImpl<T, T>
108 {
109     typedef T Type;
110 };
111 
112 // step 2: disolve all iterator proxies (see proxy_iterator.h)
113 template <typename T1, typename T2>
114 struct CompareTypeRemoveProxy:
115     CompareTypeImpl<T1, T2> {};
116 
117 // step 1: remove const from types
118 template <typename T1, typename T2>
119 struct CompareType:
120     CompareTypeRemoveProxy<typename RemoveConst<T1>::Type, typename RemoveConst<T2>::Type> {};
121 
122 // ============================================================================
123 // Functions
124 // ============================================================================
125 
126 // These functions are shortcuts to provide comparisons based on the same order
127 // that is imposed by ordValue
128 
129 template <typename TValue1, typename TValue2>
130 inline bool ordLess(TValue1 const & left, TValue2 const & right)
131 {
132     return ordValue(left) < ordValue(static_cast<TValue1>(right));
133 }
134 
135 template <typename TValue1, typename TValue2>
136 inline bool ordEqual(TValue1 const & left, TValue2 const & right)
137 {
138     return ordValue(left) == ordValue(static_cast<TValue1>(right));
139 }
140 
141 template <typename TValue1, typename TValue2>
142 inline bool ordGreater(TValue1 const & left, TValue2 const & right)
143 {
144     return ordValue(left) > ordValue(static_cast<TValue1>(right));
145 }
146 
147 }  // namespace seqan
148 
149 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_FUNDAMENTAL_COMPARISON_H_
150