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