source: branches/properties/CORE/pos_range.h

Last change on this file was 19167, checked in by westram, 3 years ago
File size: 5.5 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); }
55    static PosRange till(int pos) { return pos<0 ? empty() : PosRange(0, pos); }
56
57    static PosRange after(int pos) { return from(pos+1); }
58    static PosRange prior(int pos) { return till(pos-1); }
59
60    int start() const {
61        arb_assert(!is_empty());
62        return start_pos;
63    }
64    int end() const {
65        arb_assert(has_end());
66        return end_pos;
67    }
68
69    int size() const { return end_pos-start_pos+1; }
70
71    bool is_whole() const { return start_pos == 0 && end_pos<0; }
72    bool is_empty() const { return size() == 0; }
73    bool is_part() const { return !(is_empty() || is_whole()); }
74
75    bool has_end() const { return size() > 0; }
76
77    bool is_limited() const { return is_empty() || has_end(); }
78    bool is_unlimited() const { return !is_limited(); }
79
80    bool operator == (const PosRange& other) const { return start_pos == other.start_pos && end_pos == other.end_pos; }
81    bool operator != (const PosRange& other) const { return !(*this == other); }
82
83    void copy_corresponding_part(char *dest, const char *source, size_t source_len) const;
84    char *dup_corresponding_part(const char *source, size_t source_len) const;
85
86    bool contains(int pos) const {
87        return !is_empty() && pos >= start_pos && (pos <= end_pos || is_unlimited());
88    }
89    bool contains(const PosRange& other) const;
90
91    PosRange after() const { return has_end() ? after(end()) : empty(); }
92    PosRange prior() const { return !is_empty() && start() ? prior(start()) : empty(); }
93
94#if defined(DEBUG)
95    void dump(FILE *out) const {
96        fprintf(out, "[%i..%i]", start_pos, end_pos);
97    }
98#endif
99};
100
101inline PosRange intersection(PosRange r1, PosRange r2) {
102    if (r1.is_empty()) return r1;
103    if (r2.is_empty()) return r2;
104
105    int start = std::max(r1.start(), r2.start());
106    if (r1.is_limited()) {
107        if (r2.is_limited()) return PosRange(start, std::min(r1.end(), r2.end()));
108        return PosRange(start, r1.end());
109    }
110    if (r2.is_limited()) return PosRange(start, r2.end());
111    return PosRange::from(start);
112}
113
114inline bool PosRange::contains(const PosRange& other) const {
115    return !other.is_empty() && intersection(*this, other) == other;
116}
117
118
119class ExplicitRange : public PosRange {
120
121    // this ctor is private to avoid making ranges repeatedly explicit (if REALLY needed, convert range to PosRange before)
122    ExplicitRange(const ExplicitRange& range, int maxlen);
123
124    bool is_limited() const { // always true -> private to avoid usage
125        arb_assert(PosRange::is_limited());
126        return true;
127    }
128
129public:
130    ExplicitRange(const ExplicitRange& limRange) : PosRange(limRange) {}
131    explicit ExplicitRange(const PosRange& limRange) : PosRange(limRange) { arb_assert(is_limited()); }
132
133    ExplicitRange(const PosRange& range, int maxlen)
134        : PosRange(range.is_empty() || maxlen <= 0
135                   ? PosRange::empty()
136                   : PosRange(range.start(), range.is_limited() ? std::min(range.end(), maxlen-1) : maxlen-1))
137    { arb_assert(is_limited()); }
138
139    ExplicitRange(int start_, int end_)
140        : PosRange(start_, end_)
141    { arb_assert(is_limited()); }
142
143    explicit ExplicitRange(int len)
144        : PosRange(0, len-1)
145    { arb_assert(is_limited()); }
146
147    DECLARE_ASSIGNMENT_OPERATOR(ExplicitRange);
148};
149
150inline ExplicitRange intersection(ExplicitRange r1, ExplicitRange r2) {
151    if (r1.is_empty()) return r1;
152    if (r2.is_empty()) return r2;
153
154    return ExplicitRange(std::max(r1.start(), r2.start()),
155                         std::min(r1.end(), r2.end()));
156}
157
158inline ExplicitRange intersection(ExplicitRange e1, PosRange r2) {
159    if (e1.is_empty()) return e1;
160    return intersection(e1, ExplicitRange(r2, e1.end()+1));
161}
162inline ExplicitRange intersection(PosRange r1, ExplicitRange e2) {
163    if (e2.is_empty()) return e2;
164    return intersection(ExplicitRange(r1, e2.end()+1), e2);
165}
166
167#else
168#error pos_range.h included twice
169#endif // POS_RANGE_H
Note: See TracBrowser for help on using the repository browser.