1 | // ============================================================= // |
---|
2 | // // |
---|
3 | // File : PT_rangeCheck.hxx // |
---|
4 | // Purpose : Check whether probe is inside region // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in March 2011 // |
---|
7 | // Institute of Microbiology (Technical University Munich) // |
---|
8 | // http://www.arb-home.de/ // |
---|
9 | // // |
---|
10 | // ============================================================= // |
---|
11 | |
---|
12 | #ifndef PT_RANGECHECK_HXX |
---|
13 | #define PT_RANGECHECK_HXX |
---|
14 | |
---|
15 | #ifndef PROBE_TREE_H |
---|
16 | #include "probe_tree.h" |
---|
17 | #endif |
---|
18 | #ifndef _GLIBCXX_MAP |
---|
19 | #include <map> |
---|
20 | #endif |
---|
21 | |
---|
22 | typedef std::map<int, int> apos_cache; |
---|
23 | typedef apos_cache::iterator apos_iter; |
---|
24 | |
---|
25 | class Range { |
---|
26 | int start; // -1 or minimum absolute position |
---|
27 | int end; // -1 or maximum absolute position |
---|
28 | int probe_len; // length of checked probe |
---|
29 | |
---|
30 | mutable const AbsLoc *curr_match; |
---|
31 | mutable apos_cache cache; |
---|
32 | |
---|
33 | int start_pos() const { return curr_match->get_abs_pos(); } |
---|
34 | int min_end_pos() const { return start_pos()+probe_len-1; } // min abs. probe-end-pos |
---|
35 | |
---|
36 | int calc_max_abs_pos() const; |
---|
37 | int max_abs_pos() const { |
---|
38 | apos_iter found = cache.find(curr_match->get_name()); |
---|
39 | if (found != cache.end()) return found->second; |
---|
40 | |
---|
41 | return cache[curr_match->get_name()] = calc_max_abs_pos(); |
---|
42 | } |
---|
43 | |
---|
44 | bool starts_before_start() const { return start != -1 && start_pos() < start; } |
---|
45 | bool ends_behind_end() const { |
---|
46 | return end != -1 && |
---|
47 | (min_end_pos() > end || // cheap check |
---|
48 | start > max_abs_pos()); // expensive check |
---|
49 | } |
---|
50 | |
---|
51 | public: |
---|
52 | Range(int start_, int end_, int probe_len_) |
---|
53 | : start(start_), |
---|
54 | end(end_), |
---|
55 | probe_len(probe_len_), |
---|
56 | curr_match(NULp) |
---|
57 | {} |
---|
58 | Range(const Range& other) |
---|
59 | : start(other.start), |
---|
60 | end(other.end), |
---|
61 | probe_len(other.probe_len), |
---|
62 | curr_match(other.curr_match) |
---|
63 | {} |
---|
64 | DECLARE_ASSIGNMENT_OPERATOR(Range); |
---|
65 | |
---|
66 | bool contains(const AbsLoc& match) const { |
---|
67 | // check if found 'match' of probe is inside the Range |
---|
68 | curr_match = &match; |
---|
69 | bool inside = !starts_before_start() && !ends_behind_end(); |
---|
70 | curr_match = NULp; |
---|
71 | return inside; |
---|
72 | } |
---|
73 | }; |
---|
74 | |
---|
75 | #else |
---|
76 | #error PT_rangeCheck.hxx included twice |
---|
77 | #endif // PT_RANGECHECK_HXX |
---|