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 // Triple base class. 35 // ========================================================================== 36 37 // TODO(holtgrew): What about move construction? Useful for pairs of strings and such. Tricky to implement since ints have no move constructor, for example. 38 39 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_TRIPLE_BASE_H_ 40 #define SEQAN_INCLUDE_SEQAN_BASIC_TRIPLE_BASE_H_ 41 42 namespace seqan { 43 44 // ============================================================================ 45 // Forwards 46 // ============================================================================ 47 48 // ============================================================================ 49 // Tags, Classes, Enums 50 // ============================================================================ 51 52 /*! 53 * @class Triple 54 * @implements ComparableConcept 55 * @implements LessThanComparableConcept 56 * @headerfile <seqan/basic.h> 57 * @brief Store three arbitrary object. 58 * 59 * @signature template <typename T1, typename T3, typename T3[, typename TSpec]> 60 * class Triple; 61 * 62 * @tparam T1 Type of first object. 63 * @tparam T2 Type of second object. 64 * @tparam T3 Type of third object. 65 * @tparam TSpec Tag for specialization (Default: <tt>void</tt>). 66 */ 67 68 /*! 69 * @fn Triple::Triple 70 * @brief Default and copy construction and construction with three objects. 71 * 72 * @signature Triple::Triple() 73 * @signature Triple::Triple(other) 74 * @signature Triple::Triple(x1, x2, x3) 75 * 76 * @param[in] other Other Triple object to copy from. 77 * @param[in] x1 First object. 78 * @param[in] x2 Second object. 79 * @param[in] x3 Third object. 80 * 81 * <tt>x1</tt> must be convertible to T1, <tt>x2</tt> to T2, <tt>x3</tt> to T3. For example, a Triple of three 82 * <tt>int</tt> values can be constructed with three <tt>double</tt> values. 83 */ 84 85 /*! 86 * @var T1 Triple::i1 87 * @brief First value of triple. 88 * 89 * signature T1 Triple::i1; 90 */ 91 92 /*! 93 * @var T2 Triple::i2 94 * @brief Second value of triple. 95 * 96 * signature T2 Triple::i2; 97 */ 98 99 /*! 100 * @var T3 Triple::i3 101 * @brief Third value of triple. 102 * 103 * signature T3 Triple::i3; 104 */ 105 106 template <typename T1, typename T2 = T1, typename T3 = T1, typename TSpec = void> 107 struct Triple 108 { 109 // ------------------------------------------------------------------------ 110 // Members 111 // ------------------------------------------------------------------------ 112 113 T1 i1; 114 T2 i2; 115 T3 i3; 116 117 // ------------------------------------------------------------------------ 118 // Constructors 119 // ------------------------------------------------------------------------ 120 TripleTriple121 inline Triple() : i1(T1()), i2(T2()), i3(T3()) {} 122 TripleTriple123 inline Triple(Triple const & _p) 124 : i1(_p.i1), i2(_p.i2), i3(_p.i3) {} 125 TripleTriple126 inline Triple(T1 const & _i1, T2 const & _i2, T3 const & _i3) 127 : i1(_i1), i2(_i2), i3(_i3) {} 128 129 template <typename T1_, typename T2_, typename T3_, typename TSpec__> TripleTriple130 inline Triple(Triple<T1_, T2_, T3_, TSpec__> const & _p) 131 : i1(getValueI1(_p)), i2(getValueI2(_p)), i3(getValueI3(_p)) {} 132 133 // TODO(holtgrew): Move comparison operators to global functions? 134 inline bool 135 operator==(Triple const & other) const 136 { 137 return i1 == other.i1 && i2 == other.i2 && i3 == other.i3; 138 } 139 140 inline bool 141 operator<(Triple const & other) const 142 { 143 if (i1 < other.i1) 144 return true; 145 if (i1 == other.i1 && i2 < other.i2) 146 return true; 147 if (i1 == other.i1 && i2 == other.i2 && i3 < other.i3) 148 return true; 149 return false; 150 } 151 }; 152 153 // ============================================================================ 154 // Metafunctions 155 // ============================================================================ 156 157 // ----------------------------------------------------------------------- 158 // Metafunction LENGTH 159 // ----------------------------------------------------------------------- 160 161 /*! 162 * @mfn Triple#LENGTH 163 * @brief Return (only type-depending) length of a triple: 3. 164 * 165 * @signature LENGTH<TTriple>::VALUE 166 * 167 * @tparam TTriple The Triple specialization to get the length of. 168 * 169 * @return VALUE Length of the triple (always 3). 170 */ 171 172 template <typename T1, typename T2, typename T3, typename TSpec> 173 struct LENGTH<Triple<T1, T2, T3, TSpec> > 174 { 175 enum { VALUE = 3 }; 176 }; 177 178 // Const variant is mapped to non-const. 179 180 // ----------------------------------------------------------------------- 181 // Metafunction Value 182 // ----------------------------------------------------------------------- 183 184 /*! 185 * @mfn Triple#Value 186 * @brief Return i<sup>th</sup> type of the triple. 187 * 188 * @signature Value<TTriple, I>::Type; 189 * 190 * @tparam TTriple The Triple to return the <tt>I</tt>-th value of. 191 * @tparam I The index of the value to return, one of 1, 2, or 3. 192 */ 193 194 template <typename T1, typename T2, typename T3, typename TSpec> 195 struct Value<Triple<T1, T2, T3, TSpec>, 1> 196 { 197 typedef T1 Type; 198 }; 199 200 template <typename T1, typename T2, typename T3, typename TSpec> 201 struct Value<Triple<T1, T2, T3, TSpec>, 2> 202 { 203 typedef T2 Type; 204 }; 205 206 template <typename T1, typename T2, typename T3, typename TSpec> 207 struct Value<Triple<T1, T2, T3, TSpec>, 3 > 208 { 209 typedef T3 Type; 210 }; 211 212 // ----------------------------------------------------------------------- 213 // Metafunction Spec 214 // ----------------------------------------------------------------------- 215 216 /*! 217 * @mfn Triple#Spec 218 * @brief Return specialization tag. 219 * 220 * @signature Spec<TTriple>::Type; 221 * 222 * @tparam TTriple The Triple specialization to query for the specialization tag. 223 * 224 * @return Type The specialization type. 225 */ 226 227 template <typename T1, typename T2, typename T3, typename TSpec> 228 struct Spec<Triple<T1, T2, T3, TSpec> > 229 { 230 typedef TSpec Type; 231 }; 232 233 // ============================================================================ 234 // Functions 235 // ============================================================================ 236 237 // ----------------------------------------------------------------------- 238 // Function operator<<(); Stream Output. 239 // ----------------------------------------------------------------------- 240 241 template <typename TTarget, typename T1, typename T2, typename T3, typename TSpec> 242 inline void 243 write(TTarget &target, Triple<T1, T2, T3, TSpec> const & p) 244 { 245 write(target, "< "); 246 write(target, getValueI1(p)); 247 write(target, " , "); 248 write(target, getValueI2(p)); 249 write(target, " , "); 250 write(target, getValueI3(p)); 251 write(target, " >"); 252 } 253 254 template <typename TStream, typename T1, typename T2, typename T3, typename TSpec> 255 inline TStream & 256 operator<<(TStream & target, 257 Triple<T1, T2, T3, TSpec> const & source) 258 { 259 typename DirectionIterator<TStream, Output>::Type it = directionIterator(target, Output()); 260 write(it, source); 261 return target; 262 } 263 264 // ----------------------------------------------------------------------- 265 // Function getValueIX() 266 // ----------------------------------------------------------------------- 267 268 /*! 269 * @fn Triple#getValueI1 270 * @brief The get-value of the Triple's first entry. 271 * 272 * @signature T1 getValue(triple); 273 * 274 * @param[in] triple The triple to get entry from. 275 * 276 * @return T1 The first entry of the Triple. 277 */ 278 279 template <typename T1, typename T2, typename T3, typename TSpec> 280 inline T1 281 getValueI1(Triple<T1, T2, T3, TSpec> const & triple) 282 { 283 return triple.i1; 284 } 285 286 /*! 287 * @fn Triple#getValueI2 288 * @brief The get-value of the Triple's second entry. 289 * 290 * @signature T2 getValue(triple); 291 * 292 * @param[in] triple The triple to get entry from. 293 * 294 * @return T2 The second entry of the Triple. 295 */ 296 297 template <typename T1, typename T2, typename T3, typename TSpec> 298 inline T2 299 getValueI2(Triple<T1, T2, T3, TSpec> const & triple) 300 { 301 return triple.i2; 302 } 303 304 /*! 305 * @fn Triple#getValueI3 306 * @brief The get-value of the Triple's third entry. 307 * 308 * @signature T3 getValue(triple); 309 * 310 * @param[in] triple The triple to get entry from. 311 * 312 * @return T3 The third entry of the Triple. 313 */ 314 315 template <typename T1, typename T2, typename T3, typename TSpec> 316 inline T3 317 getValueI3(Triple<T1, T2, T3, TSpec> const & triple) 318 { 319 return triple.i3; 320 } 321 322 // ----------------------------------------------------------------------- 323 // Function assignValueIX() 324 // ----------------------------------------------------------------------- 325 326 /*! 327 * @fn Triple#assignValueI1 328 * @brief Set first entry of a triple. 329 * 330 * @signature void assignValueI1(triple, val); 331 * 332 * @param[in] triple The triple to get entry from. 333 * @param[in] val Set the value of the Triple's first entry. 334 */ 335 336 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 337 inline void assignValueI1(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 338 { 339 triple.i1 = _i; 340 } 341 342 /*! 343 * @fn Triple#assignValueI2 344 * @brief Set second entry of a triple. 345 * 346 * @signature void assignValueI2(triple, val); 347 * 348 * @param[in] triple The triple to get entry from. 349 * @param[in] val Set the value of the Triple's second entry. 350 */ 351 352 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 353 inline void assignValueI2(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 354 { 355 triple.i2 = _i; 356 } 357 358 /*! 359 * @fn Triple#assignValueI3 360 * @brief Set third entry of a triple. 361 * 362 * @signature void assignValueI3(triple, val); 363 * 364 * @param[in] triple The triple to get entry from. 365 * @param[in] val Set the value of the Triple's third entry. 366 */ 367 368 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 369 inline void assignValueI3(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 370 { 371 triple.i3 = _i; 372 } 373 374 // ----------------------------------------------------------------------- 375 // Function setValueIX() 376 // ----------------------------------------------------------------------- 377 378 /*! 379 * @fn Triple#setValueI1 380 * @brief Set first entry of a triple. 381 * 382 * @signature void setValueI1(triple, val); 383 * 384 * @param[in] triple The triple to get entry from. 385 * @param[in] val Set the value of the Triple's first entry. 386 */ 387 388 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 389 inline void setValueI1(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 390 { 391 set(triple.i1, _i); 392 } 393 394 /*! 395 * @fn Triple#setValueI2 396 * @brief Set second entry of a triple. 397 * 398 * @signature void setValueI2(triple, val); 399 * 400 * @param[in] triple The triple to get entry from. 401 * @param[in] val Set the value of the Triple's second entry. 402 */ 403 404 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 405 inline void setValueI2(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 406 { 407 set(triple.i2, _i); 408 } 409 410 /*! 411 * @fn Triple#setValueI3 412 * @brief Set third entry of a triple. 413 * 414 * @signature void setValueI3(triple, val); 415 * 416 * @param[in] triple The triple to get entry from. 417 * @param[in] val Set the value of the Triple's third entry. 418 */ 419 420 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 421 inline void setValueI3(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 422 { 423 set(triple.i3, _i); 424 } 425 426 // ----------------------------------------------------------------------- 427 // Function moveValueIX() 428 // ----------------------------------------------------------------------- 429 430 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 431 inline void moveValueI1(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 432 { 433 move(triple.i1, _i); 434 } 435 436 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 437 inline void moveValueI2(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 438 { 439 move(triple.i2, _i); 440 } 441 442 template <typename T1, typename T2, typename T3, typename TSpec, typename T> 443 inline void moveValueI3(Triple<T1, T2, T3, TSpec> & triple, T const & _i) 444 { 445 move(triple.i3, _i); 446 } 447 448 // ----------------------------------------------------------------------- 449 // Function operator<() 450 // ----------------------------------------------------------------------- 451 452 template < 453 typename L1, typename L2, typename L3, typename LPack, 454 typename R1, typename R2, typename R3, typename RPack> 455 inline bool 456 operator<(Triple<L1, L2, L3, LPack> const & _left, 457 Triple<R1, R2, R3, RPack> const & _right) 458 { 459 return _left.i1 < _right.i1 || (_left.i1 == _right.i1 && _left.i2 < _right.i2) || (_left.i1 == _right.i1 && _left.i2 == _right.i2 && _left.i3 < _right.i3); 460 } 461 462 // ----------------------------------------------------------------------- 463 // Function operator>() 464 // ----------------------------------------------------------------------- 465 466 template < 467 typename L1, typename L2, typename L3, typename LPack, 468 typename R1, typename R2, typename R3, typename RPack> 469 inline bool 470 operator>(Triple<L1, L2, L3, LPack> const & _left, 471 Triple<R1, R2, R3, RPack> const & _right) 472 { 473 return _left.i1 > _right.i1 || (_left.i1 == _right.i1 && _left.i2 > _right.i2) || (_left.i1 == _right.i1 && _left.i2 == _right.i2 && _left.i3 > _right.i3); 474 } 475 476 // ----------------------------------------------------------------------- 477 // Function operator<=() 478 // ----------------------------------------------------------------------- 479 480 template < 481 typename L1, typename L2, typename L3, typename LPack, 482 typename R1, typename R2, typename R3, typename RPack> 483 inline bool 484 operator<=(Triple<L1, L2, L3, LPack> const & _left, 485 Triple<R1, R2, R3, RPack> const & _right) 486 { 487 return !operator>(_left, _right); 488 } 489 490 // ----------------------------------------------------------------------- 491 // Function operator==() 492 // ----------------------------------------------------------------------- 493 494 template < 495 typename L1, typename L2, typename L3, typename LPack, 496 typename R1, typename R2, typename R3, typename RPack> 497 inline bool 498 operator==(Triple<L1, L2, L3, LPack> const & _left, 499 Triple<R1, R2, R3, RPack> const & _right) 500 { 501 return _left.i1 == _right.i1 && _left.i2 == _right.i2 && _left.i3 == _right.i3; 502 } 503 504 // ----------------------------------------------------------------------- 505 // Function operator>() 506 // ----------------------------------------------------------------------- 507 508 template < 509 typename L1, typename L2, typename L3, typename LPack, 510 typename R1, typename R2, typename R3, typename RPack> 511 inline bool 512 operator>=(Triple<L1, L2, L3, LPack> const & _left, 513 Triple<R1, R2, R3, RPack> const & _right) 514 { 515 return !operator<(_left, _right); 516 } 517 518 // ----------------------------------------------------------------------- 519 // Function operator!=() 520 // ----------------------------------------------------------------------- 521 522 template < 523 typename L1, typename L2, typename L3, typename LPack, 524 typename R1, typename R2, typename R3, typename RPack> 525 inline bool 526 operator!=(Triple<L1, L2, L3, LPack> const & _left, 527 Triple<R1, R2, R3, RPack> const & _right) 528 { 529 return !operator==(_left, _right); 530 } 531 } // namespace seqan 532 533 #endif // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_TRIPLE_BASE_H_ 534