1 // ========================================================================== 2 // SeqAn - The Library for Sequence Analysis 3 // ========================================================================== 4 // Copyright (c) 2006-2010, 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 33 #ifndef SEQAN_HEADER_BASIC_DEFINITION_H 34 #define SEQAN_HEADER_BASIC_DEFINITION_H 35 36 namespace SEQAN_NAMESPACE_MAIN 37 { 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 template <typename T> 42 struct Tag 43 { 44 }; 45 46 ////////////////////////////////////////////////////////////////////////////// 47 48 template <typename T> 49 struct Length; 50 51 template <> 52 struct Length<void> 53 { 54 enum { VALUE = 0 }; 55 }; 56 57 ////////////////////////////////////////////////////////////////////////////// 58 /** 59 .Tag.TagList: 60 ..summary:A structure to represent a list of tags. 61 ..signature:TagList<TTag1> 62 ..signature:TagList<TTag1, TagList<TTag2> > 63 ..signature:TagList<TTag1, TagList<TTag2, TagList<TTag3[...]> > > 64 ..param.TTag1:The first tag of the list. 65 ..param.TTag2:The second tag of the list. 66 ..param.TTag3:The third tag of the list. 67 ..include:seqan/basic.h 68 */ 69 70 template <typename TTag = void, typename TSubList = void> 71 struct TagList 72 { 73 typedef TTag Type; 74 }; 75 76 template <typename TTag> 77 struct Length< TagList<TTag, void> > { 78 enum { VALUE = 1 }; 79 }; 80 81 template <typename TTag, typename TSubList> 82 struct Length< TagList<TTag, TSubList> > { 83 enum { VALUE = Length<TSubList>::VALUE + 1 }; 84 }; 85 86 template <typename TTagList = void> 87 struct TagSelector 88 { 89 int tagId; 90 91 TagSelector() 92 { 93 tagId = 0; 94 } 95 96 inline bool operator==(TagSelector const & other) const 97 { 98 return other.tagId == tagId; 99 } 100 }; 101 102 /** 103 .Class.TagSelector: 104 ..summary:A structure to select a tag from a @Tag.TagList@. 105 ..signature:TagSelector<TTagList> 106 ..param.TTagList:A tag list. 107 ...type:Tag.TagList 108 .Memvar.TagSelector#tagId: 109 ..class:Class.TagSelector 110 ..type:nolink:int 111 ..cat:Basic 112 ..summary:Stores the index of a @Page.Glossary.Tag@ in the tag list. 113 ..include:seqan/basic.h 114 */ 115 116 /// 117 118 template <typename TTag, typename TSubList> 119 struct TagSelector< TagList<TTag, TSubList> >: 120 TagSelector<TSubList> 121 { 122 typedef TTag Type; 123 typedef TagSelector<TSubList> Base; 124 }; 125 126 ////////////////////////////////////////////////////////////////////////////// 127 /** 128 .Tag.Default: 129 ..summary:Tag that specifies default behavior. 130 ..tag.Default:Use default behavior. 131 ..include:seqan/basic.h 132 */ 133 struct Default_; 134 typedef Tag<Default_> const Default; 135 136 ////////////////////////////////////////////////////////////////////////////// 137 /** 138 .Tag.Move Switch: 139 ..summary:Switch to force move. 140 ..tag.Move:Move instead of assign. 141 ..remarks.text:The difference between move constructor and copy constructor 142 is that the source object is not copied but moved into the target object. 143 The source object can lose its content and will be empty after 144 this operation in this case. 145 A move constructor can sigificantly faster than a copy constructor. 146 ..example.code:String source("hello"); 147 String target(source, Move()); // source is moved to target 148 std::cout << source; //nothing printed since source lost content 149 std::cout << target; //"hello" 150 ..see:Function.move 151 ..include:seqan/basic.h 152 */ 153 154 struct Move_; 155 typedef Tag<Move_> const Move; 156 157 ////////////////////////////////////////////////////////////////////////////// 158 159 //Pass to c'tor of iterator to move it to the end 160 struct GoEnd_; 161 typedef Tag<GoEnd_> const GoEnd; 162 163 164 ////////////////////////////////////////////////////////////////////////////// 165 166 //construct without initializing 167 struct MinimalCtor_; 168 typedef Tag<MinimalCtor_> const MinimalCtor; 169 170 //construct with initializing 171 struct NonMinimalCtor_; 172 typedef Tag<NonMinimalCtor_> const NonMinimalCtor; 173 174 ////////////////////////////////////////////////////////////////////////////// 175 176 /** 177 .Tag.Nothing: 178 ..summary:Tag that represents an absent parameter or an absent type. 179 ..tag.Nothing:Omit parameter. 180 ..include:seqan/basic.h 181 */ 182 ///Empty Data Class. 183 struct Nothing {}; 184 185 186 187 ////////////////////////////////////////////////////////////////////////////// 188 // returns TTo const, if TFrom is const, TTo otherwise 189 190 template <typename TFrom, typename TTo> 191 struct CopyConst_ 192 { 193 typedef TTo Type; 194 }; 195 template <typename TFrom, typename TTo> 196 struct CopyConst_<TFrom const, TTo> 197 { 198 typedef TTo const Type; 199 }; 200 201 ////////////////////////////////////////////////////////////////////////////// 202 203 /** 204 .Internal.RemoveConst_: 205 ..signature:RemoveConst_<T> 206 ..returns:$t$ if $T$ is $t const$, otherwise $T$. 207 */ 208 template <typename T> 209 struct RemoveConst_ 210 { 211 typedef T Type; 212 }; 213 template <typename T> 214 struct RemoveConst_<T const>: 215 public RemoveConst_<T> {}; 216 217 template <typename T> 218 struct RemoveConst_<T &> 219 { 220 typedef typename RemoveConst_<T>::Type & Type; 221 }; 222 template <typename T> 223 struct RemoveConst_<T *> 224 { 225 typedef typename RemoveConst_<T>::Type * Type; 226 }; 227 template <typename T, size_t I> 228 struct RemoveConst_<T const [I]> 229 { 230 typedef T * Type; 231 }; 232 233 ////////////////////////////////////////////////////////////////////////////// 234 /** 235 .Internal.MakeUnsigned_: 236 ..signature:MakeUnsigned_<T> 237 ..returns:$unsigned t$ if $T$ is not $unsigned t$, otherwise $T$. 238 */ 239 template <typename T> 240 struct MakeUnsigned_ 241 { 242 typedef 243 typename If< IsSameType<T, char>::VALUE, unsigned char, 244 typename If< IsSameType<T, signed char>::VALUE, unsigned char, 245 typename If< IsSameType<T, signed short>::VALUE, unsigned short, 246 typename If< IsSameType<T, signed int>::VALUE, unsigned int, 247 typename If< IsSameType<T, signed long>::VALUE, unsigned long, 248 typename If< IsSameType<T, __int64>::VALUE, __uint64, T 249 >::Type>::Type>::Type>::Type>::Type>::Type Type; 250 }; 251 252 template <typename T> 253 struct MakeUnsigned_<T const> { 254 typedef typename MakeUnsigned_<T>::Type const Type; 255 }; 256 257 ////////////////////////////////////////////////////////////////////////////// 258 /** 259 .Internal.MakeSigned_: 260 ..signature:MakeSigned_<T> 261 ..returns:$signed t$ if $T$ is not $signed t$, otherwise $T$. 262 */ 263 template <typename T> 264 struct MakeSigned_ 265 { 266 typedef 267 typename If< IsSameType<T, char>::VALUE, signed char, 268 typename If< IsSameType<T, unsigned char>::VALUE, signed char, 269 typename If< IsSameType<T, unsigned short>::VALUE, signed short, 270 typename If< IsSameType<T, unsigned int>::VALUE, signed int, 271 typename If< IsSameType<T, unsigned long>::VALUE, signed long, 272 typename If< IsSameType<T, __uint64>::VALUE, __int64, T 273 >::Type>::Type>::Type>::Type>::Type>::Type Type; 274 }; 275 276 template <typename T> 277 struct MakeSigned_<T const> { 278 typedef typename MakeSigned_<T>::Type const Type; 279 }; 280 281 ////////////////////////////////////////////////////////////////////////////// 282 /** 283 .Internal.ClassIdentifier_: 284 ..signature:void * ClassIdentifier_<T>::getID() 285 ..returns:A void * that identifies $T$. 286 ...text:The returned values of two calls of $getID$ are equal if and only if 287 the used type $T$ was the same. 288 */ 289 template <typename T> 290 struct ClassIdentifier_ 291 { 292 static inline void * 293 getID() 294 { 295 SEQAN_CHECKPOINT 296 static bool _id_dummy; 297 return &_id_dummy; 298 } 299 }; 300 301 ////////////////////////////////////////////////////////////////////////////// 302 /** 303 .Function.log2: 304 ..cat:Miscellaneous 305 ..summary:Computes logarithm of base 2 for integer types 306 ..signature:unsigned int log2(i) 307 ..param.i:An integer type. 308 ..returns:The largest integer smaller or equal than 309 the logarithm of $i$. 310 ..include:seqan/basic.h 311 */ 312 313 template <int BITS_MAX> 314 struct Log2Impl_ 315 { 316 template <typename T> 317 static inline unsigned int 318 log2(T val, unsigned int offset) 319 { 320 unsigned int val2 = val >> (BITS_MAX / 2); 321 if (val2) 322 { 323 val = val2; 324 offset += BITS_MAX / 2; 325 } 326 return Log2Impl_<BITS_MAX / 2>::log2(val, offset); 327 } 328 }; 329 330 template <> 331 struct Log2Impl_<1> 332 { 333 template <typename T> 334 static inline unsigned int 335 log2(T /*val*/, unsigned int offset) 336 { 337 return offset; 338 } 339 }; 340 341 342 template <typename T> 343 inline unsigned int 344 log2(T val) 345 { 346 enum 347 { 348 // BITS_PER_VALUE = BitsPerValue<T>::VALUE //TODO??? 349 BITS_PER_VALUE = sizeof(T) * 8 350 }; 351 352 return Log2Impl_<BITS_PER_VALUE>::log2(val, 0); 353 } 354 355 template <typename TValue, typename TExponent> 356 inline TValue _intPow(TValue a, TExponent b) 357 { 358 SEQAN_CHECKPOINT 359 TValue ret = 1; 360 while (b != 0) 361 { 362 if (b & 1) ret *= a; 363 a *= a; 364 b >>= 1; 365 } 366 return ret; 367 } 368 369 ////////////////////////////////////////////////////////////////////////////// 370 // to avoid conflicts with non-standard macros and namespaces 371 // we define our own Min/Max functions 372 373 template<typename Tx_> inline 374 const Tx_& _min(const Tx_& _Left, const Tx_& Right_) 375 { // return smaller of _Left and Right_ 376 if (_Left < Right_) 377 return _Left; 378 else 379 return Right_; 380 } 381 382 template<typename Tx_, typename Ty_> inline 383 Tx_ _min(const Tx_& _Left, const Ty_& Right_) 384 { // return smaller of _Left and Right_ 385 return (Right_ < _Left ? Right_ : _Left); 386 } 387 388 template<typename Ty_> inline 389 const Ty_& _max(const Ty_& _Left, const Ty_& Right_) 390 { // return larger of _Left and Right_ 391 if (_Left < Right_) 392 return Right_; 393 else 394 return _Left; 395 } 396 397 template<typename Tx_, typename Ty_> inline 398 Tx_ _max(const Tx_& _Left, const Ty_& Right_) 399 { // return smaller of _Left and Right_ 400 return (Right_ < _Left ? _Left : Right_); 401 } 402 403 ////////////////////////////////////////////////////////////////////////////// 404 405 template <typename T> 406 inline 407 T _abs(T const & x) 408 { 409 if (x < static_cast<T>(0)) 410 return -x; 411 else 412 return x; 413 } 414 415 ////////////////////////////////////////////////////////////////////////////// 416 417 template <typename T1, typename T2> 418 inline bool 419 _isSameType() 420 { 421 return IsSameType<T1, T2>::VALUE; 422 } 423 424 ////////////////////////////////////////////////////////////////////////////// 425 426 } //namespace SEQAN_NAMESPACE_MAIN 427 428 #endif //#ifndef SEQAN_HEADER_... 429 430