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