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 // Pair 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_PAIR_BASE_H_ 40 #define SEQAN_INCLUDE_SEQAN_BASIC_PAIR_BASE_H_ 41 42 namespace seqan { 43 44 // ============================================================================ 45 // Forwards 46 // ============================================================================ 47 48 template <typename TObject, typename TDirection> 49 struct DirectionIterator; 50 51 struct Output_; 52 typedef Tag<Output_> Output; 53 54 // ============================================================================ 55 // Tags, Classes, Enums 56 // ============================================================================ 57 58 /*! 59 * @class Pair 60 * @implements ComparableConcept 61 * @headerfile <seqan/basic.h> 62 * @brief Store two arbitrary objects. 63 * 64 * @signature template <typename T1, typename T2, typename TSpec> 65 * class Pair; 66 * 67 * @tparam T1 The type of the first member. 68 * @tparam T2 The type of the second member. 69 * @tparam TSpec Tag used for the specialization. 70 */ 71 72 /*! 73 * @fn Pair#Pair 74 * @brief Default and copy construction and construction for two values. 75 * 76 * @signature Pair::Pair(); 77 * @signature Pair::Pair(other); 78 * @signature Pair::Pair(x1, x2); 79 * 80 * @param[in] other The other Pair object to copy from. 81 * @param[in] x1 Copied to first member. 82 * @param[in] x2 Copied to second member 83 */ 84 85 /*! 86 * @var T1 Pair::i1 87 * @brief First member 88 */ 89 90 /*! 91 * @var T2 Pair::i2 92 * @brief Second member 93 */ 94 95 // TODO(holtgrew): Should default specs be specialized with void or Default? 96 // TODO(holtgrew): Move construction, will be a bit tricky, either with enable_if or with 4 base classes and all constructors are forwarded there. 97 98 template <typename T1, typename T2 = T1, typename TSpec = void> 99 struct Pair 100 { 101 // ------------------------------------------------------------------------ 102 // Members 103 // ------------------------------------------------------------------------ 104 105 T1 i1; 106 T2 i2; 107 108 // ------------------------------------------------------------------------ 109 // Constructors 110 // ------------------------------------------------------------------------ 111 112 PairPair113 Pair() : i1(T1()), i2(T2()) {} 114 115 template <typename T1_, typename T2_> 116 PairPair117 Pair(Pair<T1_, T2_> const & _p) : i1(_p.i1), i2(_p.i2) {} 118 119 PairPair120 Pair(T1 const & _i1, T2 const & _i2) : i1(_i1), i2(_i2) {} 121 122 template <typename T1_, typename T2_, typename TSpec__> 123 // TODO(holtgrew): explicit? 124 PairPair125 Pair(Pair<T1_, T2_, TSpec__> const &_p) : 126 i1(getValueI1(_p)), i2(getValueI2(_p)) 127 {} 128 }; 129 130 // ============================================================================ 131 // Metafunctions 132 // ============================================================================ 133 134 // ----------------------------------------------------------------------- 135 // Metafunction LENGTH 136 // ----------------------------------------------------------------------- 137 138 /*! 139 * @mfn Pair#LENGTH 140 * @brief Return number of members in a Pair (2). 141 * 142 * @signature LENGTH<TPair>::VALUE; 143 * 144 * @tparam TPair The Pair specialization. 145 * 146 * @return VALUE The number of element in a Pair (2). 147 */ 148 149 template <typename T1, typename T2, typename TSpec> 150 struct LENGTH<Pair<T1, T2, TSpec> > 151 { 152 enum { VALUE = 2 }; 153 }; 154 155 // Const variant is mapped to non-const by default implementation. 156 157 // ---------------------------------------------------------------------------- 158 // Metafunction Value 159 // ---------------------------------------------------------------------------- 160 161 /*! 162 * @mfn Pair#Value 163 * @brief Return type of the i-th value. 164 * 165 * @signature Value<TTuple, I>::Type; 166 * 167 * @tparam TTuple Tuple specialization to get the type of. 168 * @tparam I The index of the member to get (1 or 2). 169 * 170 * @return Type Result type. 171 */ 172 173 template <typename T1, typename T2, typename TSpec> 174 struct Value<Pair<T1, T2, TSpec>, 1> 175 { 176 typedef T1 Type; 177 }; 178 179 template <typename T1, typename T2, typename TSpec> 180 struct Value<Pair<T1, T2, TSpec>, 2> 181 { 182 typedef T2 Type; 183 }; 184 185 // ---------------------------------------------------------------------------- 186 // Metafunction Spec 187 // ---------------------------------------------------------------------------- 188 189 /*! 190 * @mfn Pair#Spec 191 * @brief Return specialization tag. 192 * 193 * @signature Spec<TPair>::Type; 194 * 195 * @tparam TPair The Pair specialization. 196 * 197 * @return Type The resulting type. 198 */ 199 200 template <typename T1, typename T2, typename TSpec> 201 struct Spec<Pair<T1, T2, TSpec> > 202 { 203 typedef TSpec Type; 204 }; 205 206 // ============================================================================ 207 // Functions 208 // ============================================================================ 209 210 // ---------------------------------------------------------------------------- 211 // Function set(). 212 // ---------------------------------------------------------------------------- 213 214 template <typename T1, typename T2, typename TSpec> 215 inline void 216 set(Pair<T1, T2, TSpec> & p1, Pair<T1, T2, TSpec> & p2) 217 { 218 set(p1.i1, p2.i1); 219 set(p1.i2, p2.i2); 220 } 221 222 // ---------------------------------------------------------------------------- 223 // Function move(). 224 // ---------------------------------------------------------------------------- 225 226 template <typename T1, typename T2, typename TSpec> 227 inline void 228 move(Pair<T1, T2, TSpec> & p1, Pair<T1, T2, TSpec> & p2) 229 { 230 move(p1.i1, p2.i1); 231 move(p1.i2, p2.i2); 232 } 233 234 // ---------------------------------------------------------------------------- 235 // Function operator<<(); Stream Output. 236 // ---------------------------------------------------------------------------- 237 238 template <typename TTarget, typename T1, typename T2, typename TSpec> 239 inline void 240 write(TTarget &target, Pair<T1, T2, TSpec> const & p) 241 { 242 write(target, "< "); 243 write(target, getValueI1(p)); 244 write(target, " , "); 245 write(target, getValueI2(p)); 246 write(target, " >"); 247 } 248 249 template <typename TStream, typename T1, typename T2, typename TSpec> 250 inline TStream & 251 operator<<(TStream & target, 252 Pair<T1, T2, TSpec> const & source) 253 { 254 typename DirectionIterator<TStream, Output>::Type it = directionIterator(target, Output()); 255 write(it, source); 256 return target; 257 } 258 259 // ----------------------------------------------------------------------- 260 // Function getValueIX() 261 // ----------------------------------------------------------------------- 262 263 /*! 264 * @fn Pair#getValueI1 265 * @brief The get-value of the Pair's first entry. 266 * 267 * @signature T1 getValueI1(pair); 268 * 269 * @param[in] pair The pair to get entry from. 270 * 271 * @return T1 The first entry of the Pair. 272 */ 273 274 // There can be no getValue with index since T1 can be != T2. 275 276 template <typename T1, typename T2, typename TSpec> 277 inline 278 T1 getValueI1(Pair<T1, T2, TSpec> const & pair) 279 { 280 return pair.i1; 281 } 282 283 /*! 284 * @fn Pair#getValueI2 285 * @brief The get-value of the Pair's second entry. 286 * 287 * @signature T2 getValueI2(pair); 288 * 289 * @param[in] pair The pair to get entry from. 290 * 291 * @return T2 The second entry of the Pair. 292 */ 293 294 template <typename T1, typename T2, typename TSpec> 295 inline 296 T2 getValueI2(Pair<T1, T2, TSpec> const & pair) 297 { 298 return pair.i2; 299 } 300 301 // ----------------------------------------------------------------------- 302 // Function assignValueIX() 303 // ----------------------------------------------------------------------- 304 305 /*! 306 * @fn Pair#assignValueI1 307 * @brief Set first entry of a pair. 308 * 309 * @signature void assignValueI1(pair, val); 310 * 311 * @param[in] pair The pair to get entry from. 312 * @param[in] val Set the value of the Pair's first entry. 313 */ 314 315 // Cannot be assignValue with index since T1 can be != T2. 316 317 template <typename T1, typename T2, typename TSpec, typename T> 318 inline void assignValueI1(Pair<T1, T2, TSpec> & pair, T const & _i) 319 { 320 pair.i1 = _i; 321 } 322 323 /*! 324 * @fn Pair#assignValueI2 325 * @brief Set second entry of a pair. 326 * 327 * @signature void assignValueI2(pair, val); 328 * 329 * @param[in] pair The pair to get entry from. 330 * @param[in] val Set the value of the Pair's second entry. 331 */ 332 333 template <typename T1, typename T2, typename TSpec, typename T> 334 inline void assignValueI2(Pair<T1, T2, TSpec> & pair, T const & _i) 335 { 336 pair.i2 = _i; 337 } 338 339 // ----------------------------------------------------------------------- 340 // Function setValueIX() 341 // ----------------------------------------------------------------------- 342 343 /*! 344 * @fn Pair#setValueI1 345 * @brief Set first entry of a pair. 346 * 347 * @signature void setValueI1(pair, val); 348 * 349 * @param[in] pair The pair to get entry from. 350 * @param[in] val Set the value of the Pair's first entry. 351 */ 352 353 // Cannot be setValue with index since T1 can be != T2. 354 355 template <typename T1, typename T2, typename TSpec, typename T> 356 inline void setValueI1(Pair<T1, T2, TSpec> & pair, T const & _i) 357 { 358 set(pair.i1, _i); 359 } 360 361 /*! 362 * @fn Pair#setValueI2 363 * @brief Set second entry of a pair. 364 * 365 * @signature void setValueI2(pair, val); 366 * 367 * @param[in] pair The pair to get entry from. 368 * @param[in] val Set the value of the Pair's second entry. 369 */ 370 371 template <typename T1, typename T2, typename TSpec, typename T> 372 inline void setValueI2(Pair<T1, T2, TSpec> & pair, T const & _i) 373 { 374 set(pair.i2, _i); 375 } 376 377 // ----------------------------------------------------------------------- 378 // Function moveValueIX() 379 // ----------------------------------------------------------------------- 380 381 // Cannot be moveValue with index since T1 can be != T2. 382 383 template <typename T1, typename T2, typename TSpec, typename T> 384 inline void moveValueI1(Pair<T1, T2, TSpec> & pair, T & _i) 385 { 386 move(pair.i1, _i); 387 } 388 389 template <typename T1, typename T2, typename TSpec, typename T> 390 inline void moveValueI2(Pair<T1, T2, TSpec> & pair, T & _i) 391 { 392 move(pair.i2, _i); 393 } 394 395 // ----------------------------------------------------------------------- 396 // Function operator<() 397 // ----------------------------------------------------------------------- 398 399 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 400 inline bool 401 operator<(Pair<L1, L2, LPack> const & _left, 402 Pair<R1, R2, RPack> const & _right) 403 { 404 return (_left.i1 < _right.i1) || (_left.i1 == _right.i1 && _left.i2 < _right.i2); 405 } 406 407 // ----------------------------------------------------------------------- 408 // Function operator>() 409 // ----------------------------------------------------------------------- 410 411 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 412 inline bool 413 operator>(Pair<L1, L2, LPack> const & _left, 414 Pair<R1, R2, RPack> const & _right) 415 { 416 return (_left.i1 > _right.i1) || (_left.i1 == _right.i1 && _left.i2 > _right.i2); 417 } 418 419 // ----------------------------------------------------------------------- 420 // Function operator==() 421 // ----------------------------------------------------------------------- 422 423 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 424 inline bool 425 operator==(Pair<L1, L2, LPack> const & _left, 426 Pair<R1, R2, RPack> const & _right) 427 { 428 return _left.i1 == _right.i1 && _left.i2 == _right.i2; 429 } 430 431 // ----------------------------------------------------------------------- 432 // Function operator<=() 433 // ----------------------------------------------------------------------- 434 435 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 436 inline bool 437 operator<=(Pair<L1, L2, LPack> const & _left, 438 Pair<R1, R2, RPack> const & _right) 439 { 440 return !operator>(_left, _right); 441 } 442 443 // ----------------------------------------------------------------------- 444 // Function operator>=() 445 // ----------------------------------------------------------------------- 446 447 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 448 inline bool 449 operator>=(Pair<L1, L2, LPack> const & _left, 450 Pair<R1, R2, RPack> const & _right) 451 { 452 return !operator<(_left, _right); 453 } 454 455 // ----------------------------------------------------------------------- 456 // Function operator!=() 457 // ----------------------------------------------------------------------- 458 459 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 460 inline bool 461 operator!=(Pair<L1, L2, LPack> const & _left, 462 Pair<R1, R2, RPack> const & _right) 463 { 464 return !operator==(_left, _right); 465 } 466 467 // ---------------------------------------------------------------------------- 468 // Function std::swap() 469 // ---------------------------------------------------------------------------- 470 471 template <typename L1, typename L2, typename LPack, typename R1, typename R2, typename RPack> 472 inline void 473 swap(Pair<L1, L2, LPack> const & a, 474 Pair<R1, R2, RPack> const & b) 475 { 476 swap(a.i1, b.i1); 477 swap(a.i2, b.i2); 478 } 479 480 } // namespace seqan 481 482 #endif // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_PAIR_BASE_H_ 483