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 // Author: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de> 34 // ========================================================================== 35 // Storage-related alphabet interface part. This means both 36 // construction type (simple, non-simple) and storage size. 37 // ========================================================================== 38 39 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_STORAGE_H_ 40 #define SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_STORAGE_H_ 41 42 #include <float.h> 43 44 namespace seqan { 45 46 // ============================================================================ 47 // Forwards 48 // ============================================================================ 49 50 template <typename TValue, typename TSpec> 51 class SimpleType; 52 53 // ============================================================================ 54 // Tags, Classes, Enums 55 // ============================================================================ 56 57 // ============================================================================ 58 // Metafunctions 59 // ============================================================================ 60 61 // ---------------------------------------------------------------------------- 62 // Metafunction BitsPerValue 63 // ---------------------------------------------------------------------------- 64 65 template <typename TValue> 66 struct BitsPerValue 67 { 68 static const unsigned VALUE = sizeof(TValue) * 8; 69 typedef unsigned Type; 70 }; 71 72 template <typename TValue> 73 struct BitsPerValue<TValue const> : public BitsPerValue<TValue> 74 {}; 75 76 // template <typename TValue> 77 // const unsigned BitsPerValue<TValue>::VALUE = ; 78 79 // ---------------------------------------------------------------------------- 80 // Metafunction ValueSize 81 // ---------------------------------------------------------------------------- 82 83 // TODO(holtgrew): Enable default implementation only for integers? Move to adapt builtins? 84 85 template <typename T> 86 struct ValueSize 87 { 88 typedef uint64_t Type; 89 static const Type VALUE = (BitsPerValue<T>::VALUE < 64)? 1ull << (BitsPerValue<T>::VALUE & 63) : 0ull; 90 }; 91 92 template <typename T> 93 struct ValueSize<T const> : ValueSize<T> 94 {}; 95 96 // TODO(holtgrew): Use static assertion to make sure that ValueSize is never called on floating point numbers? Include assertion for int64_t and uint64_t? 97 98 template <> 99 struct ValueSize<int64_t> 100 { 101 typedef uint64_t Type; 102 static const Type VALUE = 0; 103 }; 104 105 template <> 106 struct ValueSize<uint64_t> 107 { 108 typedef uint64_t Type; 109 static const Type VALUE = 0; 110 }; 111 112 template <> 113 struct ValueSize<double> 114 { 115 typedef uint64_t Type; 116 static const Type VALUE = 0; 117 }; 118 119 template <> 120 struct ValueSize<float> 121 { 122 typedef uint64_t Type; 123 static const Type VALUE = 0; 124 }; 125 126 127 // The internal value size is used for alphabets with piggyback qualities, 128 // for example Dna5Q. Here, the public value size is 5 but the internal 129 // value size is 256. 130 131 template <typename TValue> 132 struct InternalValueSize_ 133 : public ValueSize<TValue> 134 {}; 135 136 // ---------------------------------------------------------------------------- 137 // Metafunction BytesPerValue 138 // ---------------------------------------------------------------------------- 139 140 /*! 141 * @mfn BytesPerValue 142 * @headerfile <seqan/basic.h> 143 * @brief Number of bytes needed to store a value. 144 * 145 * @signature BytesPerValue<T>::VALUE 146 * 147 * @tparam T The type to query. 148 * 149 * @return VALUE The number of bytes to store on T object. 150 * 151 * By default, this function returns <tt>ceil(BitsPerValue<T>::VALUE)</tt>. For built-in types, this is the same 152 * as <tt>sizeof(T)</tt>. 153 * 154 * @see FiniteOrderedAlphabetConcept#ValueSize 155 * @see AlphabetConcept#BitsPerValue 156 * @see IntegralForValue 157 */ 158 159 template <typename TValue> 160 struct BytesPerValue 161 { 162 enum { VALUE = (BitsPerValue<TValue>::VALUE + 7) / 8 }; 163 }; 164 165 // ---------------------------------------------------------------------------- 166 // Metafunction IntegralForValue 167 // ---------------------------------------------------------------------------- 168 169 /*! 170 * @mfn IntegralForValue 171 * @headerfile <seqan/basic.h> 172 * @brief Returns an itegral type that provides sufficient space to store a value. 173 * 174 * @signature IntegralForValue<T>::Type; 175 * 176 * @tparam T The type to query. 177 * 178 * @return Type An integral type. 179 * 180 * The type is the smallest unsigned integral type that has a size of at least BytesPerValue bytes. 181 * 182 * <table> 183 * <tr> 184 * <th>sizeof(T) in bytes</th> 185 * <th>integral types</th> 186 * </tr> 187 * <tr> 188 * <td>1</td> 189 * <td><tt>unsigned char</tt></td> 190 * </tr> 191 * <tr> 192 * <td>2</td> 193 * <td><tt>unsigned short</tt></td> 194 * </tr> 195 * <tr> 196 * <td>3</td> 197 * <td><tt>unsigned int</tt></td> 198 * </tr> 199 * <tr> 200 * <td>4</td> 201 * <td><tt>unsigned int</tt></td> 202 * </tr> 203 * <tr> 204 * <td>> 4</td> 205 * <td><tt>int64_t</tt></td> 206 * </tr> 207 * </table> 208 * 209 * Note that the returned integral type cannot store <tt>T</tt> values, if <tt>T</tt> takes more than 8 bytes, since 210 * there exists no integral type that provides sufficient space to store types of this size. 211 * 212 * @see FiniteOrderedAlphabetConcept#ValueSize 213 * @see AlphabetConcept#BitsPerValue 214 * @see BytesPerValue 215 */ 216 217 template <int SIZE> 218 struct IntegralForValueImpl_ 219 { 220 typedef int64_t Type; 221 }; 222 223 // TODO(holtgrew): Switch to uint8_t, uint16_t, uint32_t? 224 template <> 225 struct IntegralForValueImpl_<1> 226 { 227 typedef unsigned char Type; 228 }; 229 230 template <> 231 struct IntegralForValueImpl_<2> 232 { 233 typedef unsigned short Type; 234 }; 235 236 template <> 237 struct IntegralForValueImpl_<3> 238 { 239 typedef unsigned int Type; 240 }; 241 242 template <> 243 struct IntegralForValueImpl_<4> 244 { 245 typedef unsigned int Type; 246 }; 247 248 template <typename TValue> 249 struct IntegralForValue : IntegralForValueImpl_<BytesPerValue<TValue>::VALUE> 250 {}; 251 252 // ============================================================================ 253 // Functions 254 // ============================================================================ 255 256 // ---------------------------------------------------------------------------- 257 // Function ordValue() 258 // ---------------------------------------------------------------------------- 259 260 // TODO(holtgrew): Enable only for integers, move to adapt builtins? 261 262 template <typename TValue> 263 inline typename ValueSize<TValue>::Type 264 ordValue(TValue const & c) 265 { 266 return convert<unsigned>(static_cast<typename MakeUnsigned_<TValue>::Type const &>(c)); 267 } 268 269 // The internal ord value is used for alphabets with piggyback qualities. 270 271 template <typename TValue> 272 inline typename ValueSize<TValue>::Type 273 _internalOrdValue(TValue const & c) 274 { 275 return ordValue(c); 276 } 277 278 // ---------------------------------------------------------------------------- 279 // Function valueSize<T>() 280 // ---------------------------------------------------------------------------- 281 282 template <typename T> 283 inline typename ValueSize<T>::Type 284 valueSize() 285 { 286 return +ValueSize<T>::VALUE; 287 } 288 289 } // namespace seqan 290 291 #endif // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ALPHABET_STORAGE_H_ 292