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: Enrico Siragusa <enrico.siragusa@fu-berlin.de> 33 // ========================================================================== 34 // Counting iterator implementation. 35 // ========================================================================== 36 37 #ifndef SEQAN_BASIC_ITERATOR_COUNTING_H_ 38 #define SEQAN_BASIC_ITERATOR_COUNTING_H_ 39 40 namespace seqan { 41 42 // ============================================================================ 43 // Tags 44 // ============================================================================ 45 46 template <typename TSpec = void> 47 struct CountingIteratorImpl_; 48 49 typedef CountingIteratorImpl_<void> CountingIterator; 50 51 // ============================================================================ 52 // Classes 53 // ============================================================================ 54 55 template <typename TSpec, typename TIncrementable> 56 class Iter<TIncrementable, CountingIteratorImpl_<TSpec> > 57 { 58 public: 59 TIncrementable data_position; 60 61 // ------------------------------------------------------------------------ 62 // Constructors 63 // ------------------------------------------------------------------------ 64 65 Iter(TIncrementable position = 0) : data_position(position)66 data_position(position) 67 {} 68 69 template <typename TOther> Iter(TOther position)70 Iter(TOther position) : 71 data_position(position) 72 {} 73 Iter(Iter const & other)74 Iter(Iter const & other) : 75 data_position(other.data_position) 76 {} 77 }; 78 79 // ============================================================================ 80 // Metafunctions 81 // ============================================================================ 82 83 template <typename TSpec, typename TIncrementable> 84 struct Size<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 85 { 86 typedef TIncrementable Type; 87 }; 88 89 template <typename TSpec, typename TIncrementable> 90 struct Position<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 91 { 92 typedef TIncrementable Type; 93 }; 94 95 template <typename TSpec, typename TIncrementable> 96 struct Difference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 97 { 98 typedef typename MakeSigned<TIncrementable>::Type Type; 99 }; 100 101 template <typename TSpec, typename TIncrementable> 102 struct Value<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 103 { 104 typedef TIncrementable Type; 105 }; 106 107 template <typename TSpec, typename TIncrementable> 108 struct GetValue<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 109 { 110 typedef TIncrementable Type; 111 }; 112 113 template <typename TSpec, typename TIncrementable> 114 struct Reference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > > 115 { 116 typedef TIncrementable Type; 117 }; 118 119 template <typename TSpec, typename TIncrementable> 120 struct Reference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const> 121 { 122 typedef TIncrementable const Type; 123 }; 124 125 // ============================================================================ 126 // Functions 127 // ============================================================================ 128 129 // ---------------------------------------------------------------------------- 130 // Function position() 131 // ---------------------------------------------------------------------------- 132 133 template <typename TSpec, typename TIncrementable> 134 inline typename Position<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > >::Type 135 position(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me) 136 { 137 return me.data_position; 138 } 139 140 template <typename TSpec, typename TIncrementable> 141 inline typename Position<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const>::Type 142 position(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & me) 143 { 144 return me.data_position; 145 } 146 147 // ---------------------------------------------------------------------------- 148 // Function setPosition() 149 // ---------------------------------------------------------------------------- 150 151 template <typename TIncrementable, typename TSpec, typename TPosition> 152 inline void 153 setPosition(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me, TPosition position_) 154 { 155 me.data_position = position_; 156 } 157 158 // ---------------------------------------------------------------------------- 159 // Function value() 160 // ---------------------------------------------------------------------------- 161 162 template <typename TSpec, typename TIncrementable> 163 inline typename Reference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > >::Type 164 value(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me) 165 { 166 return position(me); 167 } 168 169 template <typename TSpec, typename TIncrementable> 170 inline typename Reference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const>::Type 171 value(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & me) 172 { 173 return position(me); 174 } 175 176 // ---------------------------------------------------------------------------- 177 // Function assignValue() 178 // ---------------------------------------------------------------------------- 179 180 template <typename TIncrementable, typename TSpec, typename TValue> 181 inline void 182 assignValue(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me, TValue _value) 183 { 184 setPosition(me, _value); 185 } 186 187 // ---------------------------------------------------------------------------- 188 // Function operator==() 189 // ---------------------------------------------------------------------------- 190 191 //NOTE(h-2): the other operators should get a similar const-container-tolerant interface 192 template <typename TSpec, typename TIncrementable, typename TIncrementable2> 193 inline SEQAN_FUNC_ENABLE_IF(IsSameType<TIncrementable const &, TIncrementable2 const &>, bool) 194 operator==(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 195 Iter<TIncrementable2, CountingIteratorImpl_<TSpec> > const & right) 196 { 197 return position(left) == position(right); 198 } 199 200 // ---------------------------------------------------------------------------- 201 // Function operator!=() 202 // ---------------------------------------------------------------------------- 203 204 template <typename TSpec, typename TIncrementable> 205 inline bool 206 operator!=(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 207 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 208 { 209 return position(left) != position(right); 210 } 211 212 // ---------------------------------------------------------------------------- 213 // Function operator<() 214 // ---------------------------------------------------------------------------- 215 216 template <typename TSpec, typename TIncrementable> 217 inline bool 218 operator<(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 219 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 220 { 221 return position(left) < position(right); 222 } 223 224 template <typename TSpec, typename TIncrementable> 225 inline bool 226 operator>(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 227 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 228 { 229 return position(left) > position(right); 230 } 231 232 // ---------------------------------------------------------------------------- 233 // Function operator<=() 234 // ---------------------------------------------------------------------------- 235 236 template <typename TSpec, typename TIncrementable> 237 inline bool 238 operator<=(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 239 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 240 { 241 return position(left) <= position(right); 242 } 243 244 // ---------------------------------------------------------------------------- 245 // Function operator>=() 246 // ---------------------------------------------------------------------------- 247 248 template <typename TSpec, typename TIncrementable> 249 inline bool 250 operator>=(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 251 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 252 { 253 return position(left) >= position(right); 254 } 255 256 // ---------------------------------------------------------------------------- 257 // Function goNext() 258 // ---------------------------------------------------------------------------- 259 260 template <typename TSpec, typename TIncrementable> 261 inline void 262 goNext(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me) 263 { 264 setPosition(me, position(me) + 1); 265 } 266 267 // ---------------------------------------------------------------------------- 268 // Function goPrevious() 269 // ---------------------------------------------------------------------------- 270 271 template <typename TSpec, typename TIncrementable> 272 inline void 273 goPrevious(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & me) 274 { 275 setPosition(me, position(me) - 1); 276 } 277 278 // ---------------------------------------------------------------------------- 279 // Function operator+() 280 // ---------------------------------------------------------------------------- 281 282 template <typename TIncrementable, typename TSpec, typename TIntegral> 283 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TIntegral> >, Iter<TIncrementable, CountingIteratorImpl_<TSpec> >) 284 operator+(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, TIntegral right) 285 { 286 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > tmp(left); 287 setPosition(tmp, position(left) + right); 288 return tmp; 289 } 290 291 template <typename TIncrementable, typename TSpec, typename TIntegral> 292 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TIntegral> >, Iter<TIncrementable, CountingIteratorImpl_<TSpec> >) 293 operator+(TIntegral left, Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 294 { 295 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > tmp(right); 296 setPosition(tmp, position(right) + left); 297 return tmp; 298 } 299 300 // ---------------------------------------------------------------------------- 301 // Function operator+=() 302 // ---------------------------------------------------------------------------- 303 304 template <typename TIncrementable, typename TSpec, typename TIntegral> 305 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TIntegral> >, Iter<TIncrementable, CountingIteratorImpl_<TSpec> > &) 306 operator+=(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & left, TIntegral right) 307 { 308 setPosition(left, position(left) + right); 309 return left; 310 } 311 312 // ---------------------------------------------------------------------------- 313 // Function operator-() 314 // ---------------------------------------------------------------------------- 315 316 template <typename TIncrementable, typename TSpec, typename TIntegral> 317 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TIntegral> >, Iter<TIncrementable, CountingIteratorImpl_<TSpec> >) 318 operator-(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, TIntegral right) 319 { 320 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > tmp(left); 321 setPosition(tmp, position(left) - right); 322 return tmp; 323 } 324 325 template <typename TSpec, typename TIncrementable> 326 inline typename Difference<Iter<TIncrementable, CountingIteratorImpl_<TSpec> > >::Type 327 operator-(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & left, 328 Iter<TIncrementable, CountingIteratorImpl_<TSpec> > const & right) 329 { 330 return position(left) - position(right); 331 } 332 333 // ---------------------------------------------------------------------------- 334 // Function operator-=() 335 // ---------------------------------------------------------------------------- 336 337 template <typename TIncrementable, typename TSpec, typename TIntegral> 338 inline SEQAN_FUNC_ENABLE_IF(Is<IntegerConcept<TIntegral> >, Iter<TIncrementable, CountingIteratorImpl_<TSpec> > &) 339 operator-=(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & left, TIntegral right) 340 { 341 setPosition(left, position(left) - right); 342 return left; 343 } 344 345 // ---------------------------------------------------------------------------- 346 // Function assign() 347 // ---------------------------------------------------------------------------- 348 349 // Conversion assignment. 350 template <typename TIncrementable, typename TSpec, typename TSource> 351 inline void 352 assign(Iter<TIncrementable, CountingIteratorImpl_<TSpec> > & target, TSource const & source) 353 { 354 setPosition(target, position(source)); 355 } 356 357 } // namespace seqan 358 359 #endif // #ifndef SEQAN_BASIC_ITERATOR_COUNTING_H_ 360