source: trunk/yat/utility/CigarIterator.h @ 3751

Last change on this file since 3751 was 3751, checked in by Peter, 5 years ago

adjust license text to be same as in other files

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.9 KB
Line 
1#ifndef theplu_yat_utility_cigar_iterator
2#define theplu_yat_utility_cigar_iterator
3
4// $Id: CigarIterator.h 3751 2018-10-17 01:49:41Z peter $
5
6/*
7  Copyright (C) 2014, 2015, 2016 Peter Johansson
8
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "Cigar.h"
26
27#include <boost/concept_check.hpp>
28#include <boost/cstdint.hpp>
29#include <boost/iterator/iterator_facade.hpp>
30#include <boost/iterator/iterator_categories.hpp>
31#include <boost/iterator/iterator_concepts.hpp>
32
33#include <cstddef> // for size_t
34
35namespace theplu {
36namespace yat {
37namespace utility {
38
39  /**
40     \brief Iterator over a CIGAR
41
42     A CIGAR string is typically represented as a compact array, i.e.,
43     an array \c MMMMMMDDMMMM is represented as \c 6M2D4M. This class
44     is a proxy that allows iterating over a CIGAR as though the array
45     was \c MMMMMMDDMMMM.
46
47     CigarIterator is a \readable_iterator (not mutable) and
48     models a \bidirectional_traversal_iterator. Its value_type is \c
49     uint8_t. Since no \c uint8_t is stored in CIGAR, the dereference
50     operator calculates the CIGAR element to return and returns by
51     value. CigarIterator is therefore an \input_iterator.
52
53     Type Requirement:
54     - \c BASE is a \readable_iterator
55     - \c BASE is a \bidirectional_traversal_iterator
56
57     \since New in yat 0.13
58   */
59  template<typename BASE>
60  class CigarIterator
61    : public boost::iterator_facade<
62    CigarIterator<BASE>, uint8_t
63    , boost::bidirectional_traversal_tag, const uint8_t>
64  {
65  public:
66    /**
67       \brief Default constructor
68     */
69    CigarIterator(void);
70
71    /**
72       Construct an iterator that points to element offset in \a p. If
73       \a p corresponds to \c 5M and offset is 2, the iterator points to
74       the third \c M.
75     */
76    explicit CigarIterator(BASE p, size_t offset=0);
77
78    /**
79       \return underlying iterator
80     */
81    BASE base(void) const;
82  private:
83    friend class boost::iterator_core_access;
84
85    BASE base_;
86    size_t index_;
87
88    void decrement(void);
89    uint8_t dereference(void) const;
90    bool equal(const CigarIterator& other) const;
91    void increment(void);
92
93    // using compiler generated copy
94    //CigarIterator(const CigarIterator& other);
95    //CigarIterator& operator=(const CigarIterator&);
96  };
97
98
99  //// implementation  /////////////
100
101  template<typename BASE>
102  CigarIterator<BASE>::CigarIterator(void)
103  {
104    BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<BASE>));
105    BOOST_CONCEPT_ASSERT((boost_concepts::BidirectionalTraversal<BASE>));
106  }
107
108
109  template<typename BASE>
110  CigarIterator<BASE>::CigarIterator(BASE b, size_t x)
111    : base_(b), index_(x)
112  {
113    BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<BASE>));
114    BOOST_CONCEPT_ASSERT((boost_concepts::BidirectionalTraversal<BASE>));
115  }
116
117
118  template<typename BASE>
119  BASE CigarIterator<BASE>::base(void) const
120  {
121    return base_;
122  }
123
124
125  template<typename BASE>
126  void CigarIterator<BASE>::decrement(void)
127  {
128    if (index_)
129      --index_;
130    else {
131      --base_;
132      index_ = bam_cigar_oplen(*base_)-1;
133    }
134  }
135
136
137  template<typename BASE>
138  uint8_t CigarIterator<BASE>::dereference(void) const
139  {
140    return bam_cigar_op(*base_);
141  }
142
143
144  template<typename BASE>
145  bool CigarIterator<BASE>::equal(const CigarIterator& other) const
146  {
147    return base_==other.base_ && index_==other.index_;
148  }
149
150
151  template<typename BASE>
152  void CigarIterator<BASE>::increment(void)
153  {
154    if (++index_ == bam_cigar_oplen(*base_)) {
155      index_=0;
156      ++base_;
157    }
158  }
159
160}}}
161#endif
Note: See TracBrowser for help on using the repository browser.