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