source: branches/profile/PROBE/PT_prefixIter.h

Last change on this file was 11060, checked in by westram, 10 years ago
File size: 3.5 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : PT_prefixIter.h                                    //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in November 2012   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#ifndef PT_PREFIXITER_H
13#define PT_PREFIXITER_H
14
15class PrefixIterator {
16    // iterates over prefixes of length given to ctor.
17    //
18    // PT_QU will only occur at end of prefix,
19    // i.e. prefixes will be shorter than given length if PT_QU occurs
20
21    PT_base low, high;
22    int      len;
23
24    char *part;
25    int   plen;
26
27    char END() const { return high+1; }
28    size_t base_span() const { return high-low+1; }
29
30    void inc() {
31        if (plen) {
32            do {
33                part[plen-1]++;
34                if (part[plen-1] == END()) {
35                    --plen;
36                }
37                else {
38                    for (int l = plen; l<len; ++l) {
39                        part[l] = low;
40                        plen    = l+1;
41                        if (low == PT_QU) break;
42                    }
43                    break;
44                }
45            }
46            while (plen);
47        }
48        else {
49            part[0] = END();
50        }
51    }
52
53public:
54
55    void reset() {
56        if (len) {
57            for (int l = 0; l<len; ++l) part[l] = low;
58        }
59        else {
60            part[0] = 0;
61        }
62
63        plen = (low == PT_QU && len) ? 1 : len;
64    }
65
66    PrefixIterator(PT_base low_, PT_base high_, int len_)
67        : low(low_),
68          high(high_),
69          len(len_),
70          part((char*)malloc(len ? len : 1))
71    {
72        reset();
73    }
74    PrefixIterator(const PrefixIterator& other)
75        : low(other.low),
76          high(other.high),
77          len(other.len),
78          part((char*)malloc(len ? len : 1)),
79          plen(other.plen)
80    {
81        memcpy(part, other.part, plen);
82    }
83    DECLARE_ASSIGNMENT_OPERATOR(PrefixIterator);
84    ~PrefixIterator() {
85        free(part);
86    }
87
88    const char *prefix() const { return part; }
89    size_t length() const { return plen; }
90    size_t max_length() const { return len; }
91
92    char *copy() const {
93        pt_assert(!done());
94        char *result = (char*)malloc(plen+1);
95        memcpy(result, part, plen);
96        result[plen] = 0;
97        return result;
98    }
99
100    bool done() const { return part[0] == END(); }
101
102    const PrefixIterator& operator++() { // ++PrefixIterator
103        pt_assert(!done());
104        inc();
105        return *this;
106    }
107
108    size_t steps() const {
109        size_t count = 1;
110        size_t bases = base_span();
111        for (int l = 0; l<len; ++l) {
112            if (low == PT_QU) {
113                // PT_QU branches end instantly
114                count = 1+(bases-1)*count;
115            }
116            else {
117                count *= bases;
118            }
119        }
120        return count;
121    }
122
123    bool matches_at(const char *probe) const {
124        for (int p = 0; p<plen; ++p) {
125            if (probe[p] != part[p]) {
126                return false;
127            }
128        }
129        return true;
130    }
131};
132
133#else
134#error PT_prefixIter.h included twice
135#endif // PT_PREFIXITER_H
Note: See TracBrowser for help on using the repository browser.