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: Andreas Gogol-Döring <andreas.doering@mdc-berlin.de>
33 // ==========================================================================
34 // Basic declarations for the Iter class and generic implementations.
35 // ==========================================================================
36 
37 // TODO(holtgrew): I think the interface is not completely specified here. Also, we could maybe have more generic implementations for operators?
38 
39 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ITERATOR_BASE_H_
40 #define SEQAN_INCLUDE_SEQAN_BASIC_ITERATOR_BASE_H_
41 
42 namespace seqan {
43 
44 // ============================================================================
45 // Forwards
46 // ============================================================================
47 
48 // ============================================================================
49 // Tags, Classes, Enums
50 // ============================================================================
51 
52 /*!
53  * @class Iter
54  * @implements IteratorAssociatedTypesConcept
55  * @headerfile <seqan/basic.h>
56  * @brief Base class for iterators to traverse containers.
57  *
58  * @signature template <typename TContainer, typename TSpec>
59  *            class Iter;
60  *
61  * @tparam TContainer The type of the container to iterate.
62  * @tparam TSpec      Type to use for specializing the <tt>Iter</tt> class.
63  */
64 
65 template <typename TContainer, typename TSpec>
66 class Iter;
67 
68 // ============================================================================
69 // Metafunctions
70 // ============================================================================
71 
72 // ----------------------------------------------------------------------------
73 // Metafunction IterComplementConst
74 // ----------------------------------------------------------------------------
75 
76 /*!
77  * @mfn Iter#IterComplementConst
78  * @brief Metafunction that complements the const-ness of the container of an iterator.
79  *
80  * @signature IterComplementConst<TIter>::Type
81  *
82  * @tparam TIter The @link Iter @endlink to complement the container constness of.
83  *
84  * @return Type The type of the iterator that is the same as <tt>TIter</tt> except that the const-ness of the
85  *              container is complemented.
86  */
87 
88 template <typename TIterator>
89 struct IterComplementConst;
90 
91 template <typename TContainer, typename TSpec>
92 struct IterComplementConst<Iter<TContainer, TSpec> >
93 {
94     typedef Iter<
95         typename IfC<
96             IsSameType<typename RemoveConst_<TContainer>::Type, TContainer>::VALUE,
97             TContainer const,
98             typename RemoveConst_<TContainer>::Type>::Type,
99         TSpec> Type;
100 };
101 
102 template <typename TContainer, typename TSpec>
103 struct IterComplementConst<Iter<TContainer, TSpec> const>
104         : IterComplementConst<Iter<TContainer, TSpec> > {};
105 
106 // ----------------------------------------------------------------------------
107 // Metafunction IterMakeConst
108 // ----------------------------------------------------------------------------
109 
110 /*!
111  * @mfn Iter#IterMakeConst
112  * @brief Metafunction to make enforce const-ness of the container of an iterator.
113  *
114  * @signature IterMakeConst<TIter>::Type
115  *
116  * @tparam TIter The iterator type to make the container const of.
117  *
118  * @return Type The resulting Iter type with a const container.
119  */
120 
121 template <typename TIterator>
122 struct IterMakeConst;
123 
124 template <typename TContainer, typename TSpec>
125 struct IterMakeConst<Iter<TContainer, TSpec> >
126 {
127     typedef Iter<typename RemoveConst_<TContainer>::Type const, TSpec> Type;
128 };
129 
130 template <typename TContainer, typename TSpec>
131 struct IterMakeConst<Iter<TContainer, TSpec> const>
132         : IterMakeConst<Iter<TContainer, TSpec> > {};
133 
134 // ----------------------------------------------------------------------------
135 // Metafunction Spec
136 // ----------------------------------------------------------------------------
137 
138 /*!
139  * @mfn Iter#Spec
140  * @brief Return specialization tag of the <tt>Iter</tt> specialization.
141  *
142  * @signature Spec<TIter>::Type
143  *
144  * @tparam TIter The <tt>Iter</tt> class to get specialization tag of.
145  *
146  * @return Type The specialization tag used for the <tt>Iter</tt>.
147  */
148 
149 template <typename TContainer, typename TSpec>
150 struct Spec<Iter<TContainer, TSpec> >
151 {
152     typedef TSpec Type;
153 };
154 
155 template <typename TContainer, typename TSpec>
156 struct Spec<Iter<TContainer, TSpec> const>
157 {
158     typedef TSpec Type;
159 };
160 
161 // ----------------------------------------------------------------------------
162 // Metafunction Value
163 // ----------------------------------------------------------------------------
164 
165 template <typename TContainer, typename TSpec>
166 struct Value<Iter<TContainer, TSpec> >:
167     Value<TContainer>
168 {
169 };
170 
171 template <typename TContainer, typename TSpec>
172 struct Value<Iter<TContainer, TSpec> const>:
173     Value<TContainer>
174 {
175 };
176 
177 // ----------------------------------------------------------------------------
178 // Metafunction GetValue
179 // ----------------------------------------------------------------------------
180 
181 template <typename TContainer, typename TSpec>
182 struct GetValue<Iter<TContainer, TSpec> >:
183     GetValue<TContainer>
184 {
185 };
186 
187 template <typename TContainer, typename TSpec>
188 struct GetValue<Iter<TContainer, TSpec> const>:
189     GetValue<TContainer>
190 {
191 };
192 
193 // ----------------------------------------------------------------------------
194 // Metafunction Reference
195 // ----------------------------------------------------------------------------
196 
197 template <typename TContainer, typename TSpec>
198 struct Reference<Iter<TContainer, TSpec> >:
199     Reference<TContainer>
200 {
201 };
202 
203 template <typename TContainer, typename TSpec>
204 struct Reference<Iter<TContainer, TSpec> const>:
205     Reference<TContainer>
206 {
207 };
208 
209 // ----------------------------------------------------------------------------
210 // Metafunction Container
211 // ----------------------------------------------------------------------------
212 
213 /*!
214  * @mfn Iter#Container
215  * @brief The container type of the iterator.
216  *
217  * @signature Container<TIter>::Type
218  *
219  * @tparam TIter The <tt>TIter</tt> class to query for its container type.
220  *
221  * @return Type The container type of <tt>TIter</tt>
222  */
223 
224 template <typename T> struct Container;
225 
226 template <typename TContainer, typename TSpec>
227 struct Container<Iter<TContainer, TSpec> >
228 {
229     typedef TContainer Type;
230 };
231 
232 template <typename TContainer, typename TSpec>
233 struct Container<Iter<TContainer, TSpec> const>
234 {
235     typedef TContainer Type;
236 };
237 
238 // ============================================================================
239 // Functions
240 // ============================================================================
241 
242 // ----------------------------------------------------------------------------
243 // Function operator*()
244 // ----------------------------------------------------------------------------
245 
246 template <typename TContainer, typename TSpec>
247 inline typename Reference<Iter<TContainer, TSpec> >::Type
248 operator*(Iter<TContainer, TSpec> & me)
249 {
250     return value(me);
251 }
252 
253 template <typename TContainer, typename TSpec>
254 inline typename Reference<Iter<TContainer, TSpec> const>::Type
255 operator*(Iter<TContainer, TSpec> const & me)
256 {
257     return value(me);
258 }
259 
260 // ----------------------------------------------------------------------------
261 // Function operator++()
262 // ----------------------------------------------------------------------------
263 
264 template <typename TContainer, typename TSpec>
265 inline Iter<TContainer, TSpec> const &
266 operator++(Iter<TContainer, TSpec> & me)
267 {
268     goNext(me);
269     return me;
270 }
271 
272 template <typename TContainer, typename TSpec>
273 inline Iter<TContainer, TSpec>
274 operator++(Iter<TContainer, TSpec> & me, int)
275 {
276     Iter<TContainer, TSpec> temp_(me);
277     goNext(me);
278     return temp_;
279 }
280 
281 // ----------------------------------------------------------------------------
282 // Function operator--()
283 // ----------------------------------------------------------------------------
284 
285 template <typename TContainer, typename TSpec>
286 inline Iter<TContainer, TSpec> const &
287 operator--(Iter<TContainer, TSpec> & me)
288 {
289     goPrevious(me);
290     return me;
291 }
292 
293 template <typename TContainer, typename TSpec>
294 inline Iter<TContainer, TSpec>
295 operator--(Iter<TContainer, TSpec> & me, int)
296 {
297     Iter<TContainer, TSpec> temp_(me);
298     goPrevious(me);
299     return temp_;
300 }
301 
302 // ----------------------------------------------------------------------------
303 // Function operator+()
304 // ----------------------------------------------------------------------------
305 
306 template <typename TContainer, typename TSpec, typename TSize>
307 inline Iter<TContainer, TSpec>
308 operator+(Iter<TContainer, TSpec> const & me, TSize size)
309 {
310     Iter<TContainer, TSpec> temp_(me);
311     goFurther(temp_, size);
312     return temp_;
313 }
314 
315 // ----------------------------------------------------------------------------
316 // Function operator+=()
317 // ----------------------------------------------------------------------------
318 
319 template <typename TContainer, typename TSpec, typename TSize>
320 inline Iter<TContainer, TSpec> const &
321 operator+=(Iter<TContainer, TSpec> & me, TSize size)
322 {
323     goFurther(me, size);
324     return me;
325 }
326 
327 // ----------------------------------------------------------------------------
328 // Function operator-=()
329 // ----------------------------------------------------------------------------
330 
331 /*
332 // TODO(doering): collides with Iter-Iter
333 // TODO(holtgrew): Try to reproduce error.
334 template <typename TContainer, typename TSpec, typename TSize>
335 inline Iter<TContainer, TSpec>
336 operator - (Iter<TContainer, TSpec> & me, TSize size)
337 {
338     Iter<TContainer, TSpec> temp_(me);
339     goFurther(temp_, -size);
340     return temp_;
341 }
342 
343 template <typename TContainer, typename TSpec, typename TSize>
344 inline Iter<TContainer, TSpec>
345 operator - (Iter<TContainer, TSpec> const & me, TSize size)
346 {
347     Iter<TContainer, TSpec> temp_(me);
348     goFurther(temp_, -size);
349     return temp_;
350 }
351 
352 template <typename TContainer, typename TSpec, typename TSize>
353 inline Iter<TContainer, TSpec> const &
354 operator -= (Iter<TContainer, TSpec> & me, TSize size)
355 {
356     goFurther(me, -size);
357     return me;
358 }
359 */
360 
361 // ----------------------------------------------------------------------------
362 // Function position()
363 // ----------------------------------------------------------------------------
364 
365 template <typename TContainer, typename TSpec, typename TContainer2>
366 inline typename Position<Iter<TContainer, TSpec> const>::Type
367 position(Iter<TContainer, TSpec> const & me,
368          TContainer2 const &)
369 {
370     return position(me);
371 }
372 
373 }  // namespace seqan
374 
375 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_ITERATOR_BASE_H_
376