1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2015, 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: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
33 // ==========================================================================
34 // A wrapper for an iterator that dereferences the wrapped iterator twice
35 // on dereferentiation.
36 // ==========================================================================
37 
38 #ifndef SEQAN_SEEDS_BASIC_ITER_INDIRECT_H_
39 #define SEQAN_SEEDS_BASIC_ITER_INDIRECT_H_
40 
41 namespace seqan {
42 
43 // ===========================================================================
44 // Enums, Tags, Classes, Specializations
45 // ===========================================================================
46 
47 template <typename TWrappedIter>
48 struct Indirect {};
49 
50 // TODO(holtgrew): Make this an Iter specialization?
51 //
52 // Iterator that dereferences twice on derefentiation.
53 template <typename TContainer, typename TWrappedIter>
54 class Iter<TContainer, Indirect<TWrappedIter> >
55 {
56 public:
57     TWrappedIter _wrappedIter;
58 
Iter()59     Iter() : _wrappedIter(0)
60     {}
61 
Iter(Iter const & other)62     Iter(Iter const & other) : _wrappedIter(other._wrappedIter)
63     {}
64 
Iter(TWrappedIter const & wrappedIter)65     Iter(TWrappedIter const & wrappedIter) : _wrappedIter(wrappedIter)
66     {}
67 };
68 
69 // ===========================================================================
70 // Metafunctions
71 // ===========================================================================
72 
73 template <typename TContainer, typename TWrappedIter>
74 struct Reference<Iter<TContainer, Indirect<TWrappedIter> > >
75 {
76     typedef typename Reference<TContainer>::Type Type;
77 };
78 
79 // ===========================================================================
80 // Functions
81 // ===========================================================================
82 
83 template <typename TContainer, typename TWrappedIter>
84 inline bool
85 operator==(Iter<TContainer, Indirect<TWrappedIter> > const & a, Iter<TContainer, Indirect<TWrappedIter> > const & b)
86 {
87     SEQAN_CHECKPOINT;
88     return a._wrappedIter == b._wrappedIter;
89 }
90 
91 
92 template <typename TContainer, typename TWrappedIter>
93 inline bool
94 operator!=(Iter<TContainer, Indirect<TWrappedIter> > const & a, Iter<TContainer, Indirect<TWrappedIter> > const & b)
95 {
96     SEQAN_CHECKPOINT;
97     return a._wrappedIter != b._wrappedIter;
98 }
99 
100 template <typename TContainer, typename TWrappedIter, typename TDiff>
101 Iter<TContainer, Indirect<TWrappedIter> >
102 operator+(Iter<TContainer, Indirect<TWrappedIter> > const & it, TDiff const diff)
103 {
104     SEQAN_CHECKPOINT;
105     typedef Iter<TContainer, Indirect<TWrappedIter> > TIter;
106     return TIter(it._wrappedIter + diff);
107 }
108 
109 
110 template <typename TContainer, typename TWrappedIter>
111 inline Iter<TContainer, Indirect<TWrappedIter> > &
112 operator++(Iter<TContainer, Indirect<TWrappedIter> > & iter)
113 {
114     SEQAN_CHECKPOINT;
115     ++iter._wrappedIter;
116     return iter;
117 }
118 
119 
120 template <typename TContainer, typename TWrappedIter>
121 inline Iter<TContainer, Indirect<TWrappedIter> >
122 operator++(Iter<TContainer, Indirect<TWrappedIter> > & iter, int /*postfix*/)
123 {
124     SEQAN_CHECKPOINT;
125     typedef Iter<TContainer, Indirect<TWrappedIter> > TIter;
126     TIter tmp(iter);
127     ++iter;
128     return tmp;
129 }
130 
131 
132 template <typename TContainer, typename TWrappedIter>
133 inline Iter<TContainer, Indirect<TWrappedIter> > &
134 operator--(Iter<TContainer, Indirect<TWrappedIter> > & iter)
135 {
136     SEQAN_CHECKPOINT;
137     --iter._wrappedIter;
138     return iter;
139 }
140 
141 
142 template <typename TContainer, typename TWrappedIter>
143 inline Iter<TContainer, Indirect<TWrappedIter> >
144 operator--(Iter<TContainer, Indirect<TWrappedIter> > & iter, int /*postfix*/)
145 {
146     SEQAN_CHECKPOINT;
147     typedef Iter<TContainer, Indirect<TWrappedIter> > TIter;
148     TIter tmp(iter);
149     --iter;
150     return tmp;
151 }
152 
153 
154 template <typename TContainer, typename TWrappedIter>
155 inline typename Value<TWrappedIter>::Type &
156 operator*(Iter<TContainer, Indirect<TWrappedIter> > & iter)
157 {
158     SEQAN_CHECKPOINT;
159     return **iter._wrappedIter;
160 }
161 
162 
163 template <typename TContainer, typename TWrappedIter>
164 inline typename Value<TWrappedIter>::Type &
165 operator*(Iter<TContainer, Indirect<TWrappedIter> > const & iter)
166 {
167     SEQAN_CHECKPOINT;
168     return **iter._wrappedIter;
169 }
170 
171 
172 template <typename TContainer, typename TWrappedIter>
173 inline typename Reference<Iter<TContainer, Indirect<TWrappedIter> > >::Type
174 value(Iter<TContainer, Indirect<TWrappedIter> > & iter)
175 {
176     SEQAN_CHECKPOINT;
177     return **iter._wrappedIter;
178 }
179 
180 
181 template <typename TContainer, typename TWrappedIter>
182 inline typename Reference<Iter<TContainer, Indirect<TWrappedIter> > >::Type
183 value(Iter<TContainer, Indirect<TWrappedIter> > const & iter)
184 {
185     SEQAN_CHECKPOINT;
186     return **iter._wrappedIter;
187 }
188 
189 }  // namespace seqan
190 
191 #endif  // #ifndef SEQAN_SEEDS_BASIC_ITER_INDIRECT_H_
192