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 // ==========================================================================
34 
35 #ifndef SEQAN_MODIFIER_MODIFIER_FUNCTORS_H_
36 #define SEQAN_MODIFIER_MODIFIER_FUNCTORS_H_
37 
38 #include <cctype>
39 
40 // TODO(holtgrew): Make the structs here into classes.
41 
42 namespace seqan
43 {
44 
45 // ==========================================================================
46 // Forwards
47 // ==========================================================================
48 
49 // ==========================================================================
50 // Classes, Enums, Typedefs
51 // ==========================================================================
52 
53 // --------------------------------------------------------------------------
54 // Class FunctorUpcase
55 // --------------------------------------------------------------------------
56 
57 /*!
58  * @class FunctorUpcase
59  * @headerfile <seqan/modifier.h>
60  * @brief Functor that returns the upper case character for a given character.
61  *
62  * @signature template <typename TInType[, typename TResult]>
63  *            struct FunctorUpcase;
64  *
65  * @tparam TInType The parameter/input type.
66  * @tparam TResult The return/result type, defaults to TInType.
67  *
68  *
69  * @fn FunctorUpcase::operator()
70  * @brief Function call operator.
71  * @signature TResult FunctorUpcase::operator()(in);
72  *
73  * @param[in] in The value to convert (<tt>in</tt>).
74  *
75  * @return TResult The converted value (<tt>TResult</tt>).
76  */
77 
78 template <typename InType, typename Result = InType>
79 struct FunctorUpcase : public std::unary_function<InType, Result>
80 {
operatorFunctorUpcase81     inline Result operator()(InType x) const
82     {
83         return toUpperValue(x);
84     }
85 };
86 
87 // --------------------------------------------------------------------------
88 // Class FunctorLowcase
89 // --------------------------------------------------------------------------
90 
91 /*!
92  * @class FunctorLowcase
93  * @headerfile <seqan/modifier.h>
94  * @brief Functor that returns the lower case character for a given character.
95  *
96  * @signature template <typename TInType[, typename TResult]>
97  *            struct FunctorLowcase;
98  *
99  * @tparam TInType The parameter/input type.
100  * @tparam TResult The return/result type, defaults to TInType.
101  *
102  *
103  * @fn FunctorLowcase::operator()
104  * @brief Function call operator.
105  * @signature TResult FunctorLowcase::operator()(in);
106  *
107  * @param[in] in The value to convert (<tt>in</tt>).
108  *
109  * @return TResult The converted value (<tt>TResult</tt>).
110  */
111 
112 template <typename InType, typename Result = InType>
113 struct FunctorLowcase : public std::unary_function<InType, Result>
114 {
operatorFunctorLowcase115     inline Result operator()(InType x) const
116     {
117         return tolower(x);
118     }
119 };
120 
121 // --------------------------------------------------------------------------
122 // Class FunctorConvert
123 // --------------------------------------------------------------------------
124 
125 /*!
126  * @class FunctorConvert
127  * @headerfile <seqan/modifier.h>
128  * @brief Functor that converts between two types.
129  *
130  * @signature template <typename TInType, typename TOutType>
131  *            struct FunctorConvert;
132  *
133  * @tparam TInType  The parameter/input type.
134  * @tparam TOutType The return/result type, defaults to TInType.
135  *
136  *
137  * @fn FunctorConvert::operator()
138  * @brief Function call operator.
139  * @signature TOutType FunctorLowcase::operator()(in);
140  *
141  * @param[in] in The value to convert (<tt>in</tt>).
142  *
143  * @return TOutType The converted value (<tt>TOutType</tt>).
144  */
145 
146 template <typename InType, typename OutType>
147 struct FunctorConvert : public std::unary_function<InType,OutType>
148 {
operatorFunctorConvert149     inline OutType operator()(InType x) const
150     {
151         return x;
152     }
153 };
154 
155 // --------------------------------------------------------------------------
156 // Helper Structs with Translation Tables
157 // --------------------------------------------------------------------------
158 
159 // Manual forward for the complementing of characters.
160 template <typename TValue> struct FunctorComplement;
161 
162 
163 template <typename T = void>
164 struct TranslateTableDna5ToDna5Complement_
165 {
166     static char const VALUE[5];
167 };
168 
169 template <typename T>
170 char const TranslateTableDna5ToDna5Complement_<T>::VALUE[5] = {'T', 'G', 'C', 'A', 'N'};
171 
172 template <typename T = void>
173 struct TranslateTableRna5ToRna5Complement_
174 {
175     static char const VALUE[5];
176 };
177 
178 template <typename T>
179 char const TranslateTableRna5ToRna5Complement_<T>::VALUE[5] = {'U', 'G', 'C', 'A', 'N'};
180 
181 template <typename T = void>
182 struct TranslateTableIupacToIupacComplement_
183 {
184     static signed char const VALUE[16];
185 };
186 
187 template <typename T>
188 signed char const TranslateTableIupacToIupacComplement_<T>::VALUE[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
189 
190 // --------------------------------------------------------------------------
191 // Class FunctorComplement
192 // --------------------------------------------------------------------------
193 
194 /*!
195  * @class FunctorComplement
196  * @headerfile <seqan/modifier.h>
197  * @brief Functor that returns the complement nucleotide for a given nucleotide.
198  *
199  * @signature template <typename TValue>
200  *            struct FunctorComplement.
201  *
202  * @tparam TValue The value type.
203  *
204  * @section Remarks
205  *
206  * If TValue is char, then the characters are complemented as Dna5.
207  *
208  *
209  * @fn FunctorComplement::operator()
210  * @brief Function call operator.
211  * @signature TValue FunctorComplement::operator()(in);
212  *
213  * @param[in] in The value to convert (<tt>in</tt>).
214  *
215  * @return TValue The converted value (<tt>TValue</tt>).
216  */
217 
218 template <>
219 struct FunctorComplement<char> : public std::unary_function<Dna5,Dna5>
220 {
221     inline Dna5 operator()(Dna5 x) const
222     {
223         return TranslateTableDna5ToDna5Complement_<>::VALUE[x.value];
224     }
225 };
226 
227 template <>
228 struct FunctorComplement<Dna> : public std::unary_function<Dna,Dna>
229 {
230     inline Dna operator()(Dna x) const
231     {
232         return TranslateTableDna5ToDna5Complement_<>::VALUE[x.value];
233     }
234 };
235 
236 template <>
237 struct FunctorComplement<Dna5> : public std::unary_function<Dna5,Dna5>
238 {
239     inline Dna5 operator()(Dna5 x) const
240     {
241         return TranslateTableDna5ToDna5Complement_<>::VALUE[x.value];
242     }
243 };
244 
245 template <>
246 struct FunctorComplement<Rna> : public std::unary_function<Rna,Rna>
247 {
248     inline Rna operator()(Rna x) const
249     {
250         return TranslateTableRna5ToRna5Complement_<>::VALUE[x.value];
251     }
252 };
253 
254 template <>
255 struct FunctorComplement<Rna5> : public std::unary_function<Rna5,Rna5>
256 {
257     inline Dna5 operator()(Rna5 x) const
258     {
259         return TranslateTableRna5ToRna5Complement_<>::VALUE[x.value];
260     }
261 };
262 
263 template <>
264 struct FunctorComplement<DnaQ> : public std::unary_function<DnaQ,DnaQ>
265 {
266     inline DnaQ operator()(DnaQ x) const
267     {
268         int qual = getQualityValue(x);
269         x = TranslateTableDna5ToDna5Complement_<>::VALUE[ordValue((Dna)x)];
270         assignQualityValue(x, qual);
271         return x;
272     }
273 };
274 
275 template <>
276 struct FunctorComplement<Dna5Q> : public std::unary_function<Dna5Q,Dna5Q>
277 {
278     inline Dna5Q operator()(Dna5Q x) const {
279         int qual = getQualityValue(x);
280         x = TranslateTableDna5ToDna5Complement_<>::VALUE[ordValue((Dna5)x)];
281         assignQualityValue(x, qual);
282         return x;
283     }
284 };
285 
286 template <>
287 struct FunctorComplement<Iupac> : public std::unary_function<Iupac,Iupac>
288 {
289     inline Iupac operator()(Iupac x) const
290     {
291         return TranslateTableIupacToIupacComplement_<>::VALUE[x.value];
292     }
293 };
294 
295 
296 }  // namespace seqan
297 
298 #endif  // SEQAN_MODIFIER_MODIFIER_FUNCTORS_H_
299