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: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
33 // ==========================================================================
34 // This header forward declares / contains prototypes of fundamental
35 // metafunctions.  The rule of thumb for a metafunction to get promoted to
36 // "fundamental" is if it corresponds to a C++98/C++11 global typedef or is
37 // defined for many types.
38 // ==========================================================================
39 
40 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_FUNDAMENTAL_METAFUNCTIONS_H_
41 #define SEQAN_INCLUDE_SEQAN_BASIC_FUNDAMENTAL_METAFUNCTIONS_H_
42 
43 #include <seqan/basic/basic_metaprogramming.h>
44 
45 namespace seqan {
46 
47 // ============================================================================
48 // Forwards
49 // ============================================================================
50 
51 // ============================================================================
52 // Tags, Classes, Enums
53 // ============================================================================
54 
55 // ============================================================================
56 // Metafunctions
57 // ============================================================================
58 
59 // ----------------------------------------------------------------------------
60 // Metafunction Value
61 // ----------------------------------------------------------------------------
62 
63 /*!
64  * @mfn Value
65  * @headerfile <seqan/basic.h>
66  * @brief Type of the items in the container or behind an iterator.
67  *
68  * @signature Value<T[, I]>::Type;
69  *
70  * @tparam T The type to query for its value type.
71  * @tparam I Optional int, for types with multiple entries.  Defaults to 0.
72  *
73  * The value type of a container T is the type of the elements in T.  for example, the value type of a sequence of int
74  * is int.
75  */
76 
77 template <typename T, const int I = 0>
78 struct Value;
79 
80 // ----------------------------------------------------------------------------
81 // Metafunction GetValue
82 // ----------------------------------------------------------------------------
83 
84 /*!
85  * @mfn GetValue
86  * @headerfile <seqan/basic.h>
87  * @brief Type for reading values.
88  *
89  * @signature GetValue<T>::Type;
90  *
91  * @tparam T Type of the value-holding object.
92  *
93  * Depending on T, the GetValue-type can either be Value&lt;T&gt;::Type &amp; or Value&lt;T&gt;::Type.
94  *
95  * @section Remarks
96  *
97  * <tt>GetValue</tt> is the return type of @Function.getValue@ that allows a (read-only) access to objects.  Do not
98  * confuse it with value that returns a reference to the value.
99  */
100 
101 template <typename T>
102 struct GetValue;
103 
104 // ----------------------------------------------------------------------------
105 // Metafunction Reference
106 // ----------------------------------------------------------------------------
107 
108 /*!
109  * @mfn Reference
110  * @headerfile <seqan/basic.h>
111  * @brief Reference type.
112  *
113  * @signature Reference<T>::Type;
114  *
115  * @tparam T A type.
116  *
117  * @return Type Either <tt>Value&lt;T&gt;Type &amp;</tt> or a proxy object Proxy for <tt>T</tt>.
118  */
119 
120 template <typename T>
121 struct Reference;
122 
123 // ----------------------------------------------------------------------------
124 // Metafunction Size
125 // ----------------------------------------------------------------------------
126 
127 /*!
128  * @mfn Size
129  * @headerfile <seqan/basic.h>
130  * @brief Type of an object that is suitable to hold size information.
131  *
132  * @signature Size<T>::Type;
133  *
134  * @tparam Type for which the size type is determined.
135  *
136  * @returns Type Size type of <tt>T</tt>.
137  */
138 
139 template <typename T>
140 struct Size;
141 
142 // ----------------------------------------------------------------------------
143 // Metafunction Difference
144 // ----------------------------------------------------------------------------
145 
146 /*!
147  * @mfn Difference
148  * @headerfile <seqan/basic.h>
149  * @brief Difference type.
150  *
151  * @signature Difference<T>::Type;
152  *
153  * @tparam Type for which the difference type is determined.
154  *
155  * @returns Type Difference type of <tt>T</tt>.
156  */
157 
158 template <typename T>
159 struct Difference;
160 
161 // ----------------------------------------------------------------------------
162 // Metafunction Position
163 // ----------------------------------------------------------------------------
164 
165 /*!
166  * @mfn Position
167  * @headerfile <seqan/basic.h>
168  * @brief Position type.
169  *
170  * @signature Position<T>::Type;
171  *
172  * @tparam Type for which the position type is determined.
173  *
174  * @returns Type position type of <tt>T</tt>.
175  */
176 
177 template <typename T>
178 struct Position;
179 
180 // ----------------------------------------------------------------------------
181 // Metafunction Spec
182 // ----------------------------------------------------------------------------
183 
184 
185 /*!
186  * @mfn Spec
187  * @headerfile <seqan/basic.h>
188  * @brief The spec of a class.
189  *
190  * @signature Spec<T>::Type;
191  *
192  * @tparam T Type for which the spec type is determined.
193  *
194  * @returns Type Spec type of <tt>T</tt>.
195  */
196 
197 // Default case for types without Spec<>::Type specialization.
198 
199 template <typename T>
200 struct Spec
201 {
202     typedef void Type;
203 };
204 
205 // Case for variable number of template arguments.
206 // Note, that a spec by default should be the last template argument in SeqAn.
207 // This helper recursively reduces the template argument list to the last template argument.
208 template <size_t REMAINING, typename T1, typename ...TRemainingTypes>
209 struct GetSpecHelper_ : GetSpecHelper_<sizeof...(TRemainingTypes), TRemainingTypes...>
210 {};
211 
212 // Recursion anchor.
213 template <typename T1>
214 struct GetSpecHelper_<1, T1>
215 {
216     using Type = T1;
217 };
218 
219 template <template <typename ...> class T, typename ...TArgs>
220 struct Spec<T<TArgs...> >
221 {
222     using Type = typename GetSpecHelper_<sizeof...(TArgs), TArgs...>::Type;
223 };
224 
225 template <typename T>
226 struct Spec<T const> : Spec<T>
227 {};
228 
229 // ----------------------------------------------------------------------------
230 // Metafunction DeepestSpec
231 // ----------------------------------------------------------------------------
232 
233 /*!
234  * @mfn DeepestSpec
235  * @headerfile <seqan/basic.h>
236  * @brief The deepest spec of a class with nested template arguments.
237  *
238  * @signature DeepestSpec<T>::Type;
239  *
240  * @tparam T Type for which the deepest spec type is determined.
241  *
242  * @returns Type Size type of <tt>T</tt>.
243  */
244 
245 // Default case if not specialized for T.
246 
247 template <typename T>
248 struct DeepestSpec
249 {
250     typedef T Type;
251 };
252 
253 // Default case mapping "T const" to T.
254 
255 template <typename T>
256 struct DeepestSpec<T const> : DeepestSpec<T>
257 {};
258 
259 // TODO(holtgrew): This can be simplified once we have variadic templates.
260 
261 // Recursion for 1 argument.
262 
263 template <template <typename> class T,
264           typename T1>
265 struct DeepestSpec<T<T1> >
266 {
267     typedef typename
268         IfC<IsSameType<T1, void>::VALUE,                                  // is T1 void?
269             T<T1>,                                                        // yes, end of recursion
270             typename DeepestSpec<typename Spec<T<T1> >::Type >::Type      // no,  recurse
271         >::Type Type;
272 };
273 
274 // Recursion for 2 arguments.
275 
276 template <template <typename, typename> class T,
277           typename T1, typename T2>
278 struct DeepestSpec<T<T1, T2> > : DeepestSpec<typename Spec<T<T1,T2> >::Type>
279 {};
280 
281 // Recursion for 3 arguments.
282 
283 template <template <typename, typename, typename> class T,
284           typename T1, typename T2, typename T3>
285 struct DeepestSpec<T<T1, T2, T3> >:
286     DeepestSpec<typename Spec<T<T1, T2, T3> >::Type> {};
287 
288 // Recursion for 4 arguments.
289 
290 template <template <typename, typename, typename, typename> class T,
291           typename T1, typename T2, typename T3, typename T4>
292 struct DeepestSpec<T<T1, T2, T3, T4> >:
293     DeepestSpec<typename Spec<T<T1, T2, T3, T4> >::Type> {};
294 
295 // Recursion for 5 arguments.
296 
297 template <template <typename, typename, typename, typename, typename> class T,
298           typename T1, typename T2, typename T3, typename T4, typename T5>
299 struct DeepestSpec<T<T1, T2, T3, T4, T5> > :
300     DeepestSpec<typename Spec<T<T1, T2, T3, T4, T5> >::Type>
301 {};
302 
303 // ----------------------------------------------------------------------------
304 // Metafunction LENGTH
305 // ----------------------------------------------------------------------------
306 
307 template <typename T>
308 struct LENGTH;
309 
310 // ----------------------------------------------------------------------------
311 // Metafunction MinLength
312 // ----------------------------------------------------------------------------
313 
314 template <typename T>
315 struct MinLength
316 {
317     static const unsigned VALUE = 0;
318 };
319 
320 // ============================================================================
321 // Functions
322 // ============================================================================
323 
324 }  // namespace seqan
325 
326 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_FUNDAMENTAL_METAFUNCTIONS_H_
327