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<T>::Type & or Value<T>::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<T>Type &</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