source: branches/help/CORE/pos_range.h

Last change on this file was 17877, checked in by westram, 6 years ago
File size: 5.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : pos_range.h                                       //
4//   Purpose   : range of positions (e.g. part of seq)             //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in October 2011   //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#ifndef POS_RANGE_H
13#define POS_RANGE_H
14
15#ifndef ARB_ASSERT_H
16#include <arb_assert.h>
17#endif
18#ifndef ATTRIBUTES_H
19#include <attributes.h>
20#endif
21#ifndef _GLIBCXX_ALGORITHM
22#include <algorithm>
23#endif
24#ifndef ARBTOOLS_H
25#include <arbtools.h>
26#endif
27
28class PosRange { // this is a value-class (i.e. all methods apart from ctors have to be const)
29    int start_pos;
30    int end_pos;
31
32public:
33    PosRange() : start_pos(-1), end_pos(-2) {} // default is empty range
34    PosRange(int From, int to)
35        : start_pos(From<0 ? 0 : From)
36    {
37        if (to<0) end_pos = -2;
38        else {
39            if (start_pos>to) { // empty range
40                start_pos = -1;
41                end_pos = -2;
42            }
43            else {
44                end_pos = to;
45                arb_assert(start_pos <= end_pos);
46            }
47        }
48    }
49
50    // factory functions
51    static PosRange empty() { return PosRange(); }
52    static PosRange whole() { return from(0); }
53
54    static PosRange from(int pos) { return PosRange(pos, -1); } static PosRange after(int pos) { return from(pos+1); }
55    static PosRange till(int pos) { return PosRange(0, pos); }  static PosRange prior(int pos) { return till(pos-1); }
56
57    int start() const {
58        arb_assert(!is_empty());
59        return start_pos;
60    }
61    int end() const {
62        arb_assert(has_end());
63        return end_pos;
64    }
65
66    int size() const { return end_pos-start_pos+1; }
67
68    bool is_whole() const { return start_pos == 0 && end_pos<0; }
69    bool is_empty() const { return size() == 0; }
70    bool is_part() const { return !(is_empty() || is_whole()); }
71
72    bool has_end() const { return size() > 0; }
73
74    bool is_limited() const { return is_empty() || has_end(); }
75    bool is_unlimited() const { return !is_limited(); }
76
77    bool operator == (const PosRange& other) const { return start_pos == other.start_pos && end_pos == other.end_pos; }
78    bool operator != (const PosRange& other) const { return !(*this == other); }
79
80    void copy_corresponding_part(char *dest, const char *source, size_t source_len) const;
81    char *dup_corresponding_part(const char *source, size_t source_len) const;
82
83    bool contains(int pos) const {
84        return !is_empty() && pos >= start_pos && (pos <= end_pos || is_unlimited());
85    }
86    bool contains(const PosRange& other) const;
87
88    PosRange after() const { return has_end() ? after(end()) : empty(); }
89    PosRange prior() const { return !is_empty() && start() ? prior(start()) : empty(); }
90
91#if defined(DEBUG)
92    void dump(FILE *out) const {
93        fprintf(out, "[%i..%i]", start_pos, end_pos);
94    }
95#endif
96};
97
98inline PosRange intersection(PosRange r1, PosRange r2) {
99    if (r1.is_empty()) return r1;
100    if (r2.is_empty()) return r2;
101
102    int start = std::max(r1.start(), r2.start());
103    if (r1.is_limited()) {
104        if (r2.is_limited()) return PosRange(start, std::min(r1.end(), r2.end()));
105        return PosRange(start, r1.end());
106    }
107    if (r2.is_limited()) return PosRange(start, r2.end());
108    return PosRange::from(start);
109}
110
111inline bool PosRange::contains(const PosRange& other) const {
112    return !other.is_empty() && intersection(*this, other) == other;
113}
114
115
116class ExplicitRange : public PosRange {
117
118    // this ctor is private to avoid making ranges repeatedly explicit (if REALLY needed, convert range to PosRange before)
119    ExplicitRange(const ExplicitRange& range, int maxlen);
120
121    bool is_limited() const { // always true -> private to avoid usage
122        arb_assert(PosRange::is_limited());
123        return true;
124    }
125
126public:
127    ExplicitRange(const ExplicitRange& limRange) : PosRange(limRange) {}
128    explicit ExplicitRange(const PosRange& limRange) : PosRange(limRange) { arb_assert(is_limited()); }
129
130    ExplicitRange(const PosRange& range, int maxlen)
131        : PosRange(range.is_empty() || maxlen <= 0
132                   ? PosRange::empty()
133                   : PosRange(range.start(), range.is_limited() ? std::min(range.end(), maxlen-1) : maxlen-1))
134    { arb_assert(is_limited()); }
135
136    ExplicitRange(int start_, int end_)
137        : PosRange(start_, end_)
138    { arb_assert(is_limited()); }
139
140    explicit ExplicitRange(int len)
141        : PosRange(0, len-1)
142    { arb_assert(is_limited()); }
143
144    DECLARE_ASSIGNMENT_OPERATOR(ExplicitRange);
145};
146
147inline ExplicitRange intersection(ExplicitRange r1, ExplicitRange r2) {
148    if (r1.is_empty()) return r1;
149    if (r2.is_empty()) return r2;
150
151    return ExplicitRange(std::max(r1.start(), r2.start()),
152                         std::min(r1.end(), r2.end()));
153}
154
155inline ExplicitRange intersection(ExplicitRange e1, PosRange r2) {
156    return intersection(e1, ExplicitRange(r2, e1.end()+1));
157}
158inline ExplicitRange intersection(PosRange r1, ExplicitRange e2) {
159    return intersection(ExplicitRange(r1, e2.end()+1), e2);
160}
161
162#else
163#error pos_range.h included twice
164#endif // POS_RANGE_H
Note: See TracBrowser for help on using the repository browser.