ztsdb
interval.hpp
1 // (C) 2016-2020 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef INTERVAL_HPP
20 #define INTERVAL_HPP
21 
22 
23 
24 #include "../globals.hpp"
25 #include "zone.hpp"
26 
27 
28 namespace tz {
29 
30 
31  struct interval {
32 
33  constexpr interval()
34  : s(Global::dtime::duration::zero()), e(Global::dtime::duration::zero()), sopen(0), eopen(0) { }
35 
36  interval(Global::dtime s_p, Global::dtime e_p, uint32_t sopen_p, uint32_t eopen_p)
37  : s(s_p), e(e_p), sopen(sopen_p), eopen(eopen_p) {
38  if (s > e) {
39  throw std::range_error("interval end smaller than interval start");
40  }
41  }
42 
43  Global::dtime s;
44  Global::dtime e;
45  uint32_t sopen; // encode if the interval's lower boundary is
46  // open (true) or closed (false)
47  uint32_t eopen;
48  };
49 
50  // operators:
51 
52  inline Global::duration operator-(const interval& i1, const interval& i2) {
53  return i1.s - i2.s;
54  }
55 
56  inline bool operator==(const interval& i1, const interval& i2) {
57  return i1.s == i2.s && i1.e == i2.e && i1.sopen == i2.sopen &&
58  i1.eopen == i2.eopen;
59  }
60 
61  inline bool operator!=(const interval& i1, const interval& i2) {
62  return !(i1 == i2);
63  }
64 
65  inline bool operator<=(const interval& i1, const interval& i2) {
66  if (i1.s < i2.s) return true;
67  if (i1.s == i2.s) {
68  if (!i1.sopen && i2.sopen) return true;
69  if (i1.sopen && !i2.sopen) return false;
70  // here we know that s1.sopen == s2.sopen
71  if (i1.e < i2.e) return true;
72  if (i1.e == i2.e) {
73  if (i1.eopen == i2.eopen) return true;
74  if (i1.eopen && !i2.eopen) return true;
75  }
76  }
77  return false;
78  }
79 
80  inline bool operator<(const interval& i1, const interval& i2) {
81  if (i1.s < i2.s) return true;
82  if (i1.s == i2.s) {
83  if (!i1.sopen && i2.sopen) return true;
84  if (i1.sopen && !i2.sopen) return false;
85  // here we know that s1.sopen == s2.sopen
86  if (i1.e < i2.e) return true;
87  if (i1.e == i2.e) {
88  if (i1.eopen == i2.eopen) return false;
89  if (i1.eopen && !i2.eopen) return true;
90  }
91  }
92  return false;
93  }
94 
95  inline bool operator>(const interval& i1, const interval& i2) {
96  return !(i1 <= i2);
97  }
98 
99  inline bool operator>=(const interval& i1, const interval& i2) {
100  return !(i1 < i2);
101  }
102 
103  inline bool operator<(const Global::dtime& i1, const interval& i2) {
104  if (i1 < i2.s) return true;
105  if (i1 == i2.s) return i2.sopen;
106  return false;
107  }
108 
109  inline bool operator>(const Global::dtime& i1, const interval& i2) {
110  if (i1 > i2.e) return true;
111  if (i1 == i2.e) return i2.eopen;
112  return false;
113  }
114 
115  inline interval operator+(const interval& i, const Global::duration d) {
116  return interval(i.s + d, i.e + d, i.sopen, i.eopen);
117  }
118 
119  inline interval operator-(const interval& i, const Global::duration d) {
120  return interval(i.s - d, i.e - d, i.sopen, i.eopen);
121  }
122 
123  inline interval operator+(const Global::duration d, const interval& i) {
124  return interval(i.s + d, i.e + d, i.sopen, i.eopen);
125  }
126 
127  // interval components comparators:
128  inline bool start_lt(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
129  if (s1 < s2) return true;
130  if (s1 > s2) return false;
131  return !sopen1 && sopen2;
132  }
133  inline bool start_gt(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
134  if (s1 > s2) return true;
135  if (s1 < s2) return false;
136  return sopen1 && !sopen2;
137  }
138  inline bool start_le(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
139  return !start_gt(s1, sopen1, s2, sopen2);
140  }
141  inline bool start_ge(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
142  return !start_lt(s1, sopen1, s2, sopen2);
143  }
144  inline bool end_lt(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
145  if (e1 < e2) return true;
146  if (e1 > e2) return false;
147  return eopen1 && !eopen2;
148  }
149  inline bool end_gt(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
150  if (e1 > e2) return true;
151  if (e1 < e2) return false;
152  return !eopen1 && eopen2;
153  }
154  inline bool end_le(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
155  return !end_gt(e1, eopen1, e2, eopen2);
156  }
157  inline bool end_ge(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
158  return !end_lt(e1, eopen1, e2, eopen2);
159  }
160 
161  // interval comparators:
162  inline bool start_lt(const interval& i1, const interval& i2) {
163  return start_lt(i1.s, i1.sopen, i2.s, i2.sopen);
164  }
165  inline bool start_gt(const interval& i1, const interval& i2) {
166  return start_gt(i1.s, i1.sopen, i2.s, i2.sopen);
167  }
168  inline bool start_le(const interval& i1, const interval& i2) {
169  return !start_gt(i1,i2);
170  }
171  inline bool start_ge(const interval& i1, const interval& i2) {
172  return !start_lt(i1,i2);
173  }
174  inline bool end_lt(const interval& i1, const interval& i2) {
175  return end_lt(i1.e, i1.eopen, i2.e, i2.eopen);
176  }
177  inline bool end_gt(const interval& i1, const interval& i2) {
178  return end_gt(i1.e, i1.eopen, i2.e, i2.eopen);
179  }
180  inline bool end_le(const interval& i1, const interval& i2) {
181  return !end_gt(i1,i2);
182  }
183  inline bool end_ge(const interval& i1, const interval& i2) {
184  return !end_lt(i1,i2);
185  }
186 
189  inline bool end_lt_start(const interval& i1, const interval& i2) {
190  return end_lt(i1.e, i1.eopen, i2.s, i2.sopen);
191  }
192  inline bool end_gt_start(const interval& i1, const interval& i2) {
193  return end_gt(i1.e, i1.eopen, i2.s, i2.sopen);
194  }
198  inline bool end_ge_start(const interval& i1, const interval& i2) {
199  return !end_lt_start(i1, i2);
200  }
201  inline bool end_le_start(const interval& i1, const interval& i2) {
202  return !end_gt_start(i1, i2);
203  }
204 
205 
206  // Unions --------------------------------------------------------
209  // interval components comparators:
210  inline bool union_start_lt(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
211  if (s1 < s2) return true;
212  if (s1 > s2) return false;
213  return sopen1 || sopen2;
214  }
215  inline bool union_start_gt(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
216  if (s1 > s2) return true;
217  if (s1 < s2) return false;
218  return sopen1 || sopen2;
219  }
220  inline bool union_start_le(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
221  return !union_start_gt(s1, sopen1, s2, sopen2);
222  }
223  inline bool union_start_ge(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2) {
224  return !union_start_lt(s1, sopen1, s2, sopen2);
225  }
226  inline bool union_end_lt(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
227  if (e1 < e2) return true;
228  if (e1 > e2) return false;
229  return eopen1 && eopen2;
230  }
231  inline bool union_end_gt(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
232  if (e1 > e2) return true;
233  if (e1 < e2) return false;
234  return eopen1 && eopen2;
235  }
236  inline bool union_end_le(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
237  return !union_end_gt(e1, eopen1, e2, eopen2);
238  }
239  inline bool union_end_ge(Global::dtime e1, bool eopen1, Global::dtime e2, bool eopen2) {
240  return !union_end_lt(e1, eopen1, e2, eopen2);
241  }
242 
243  // interval comparators:
244  inline bool union_start_lt(const interval& i1, const interval& i2) {
245  return union_start_lt(i1.s, i1.sopen, i2.s, i2.sopen);
246  }
247  inline bool union_start_gt(const interval& i1, const interval& i2) {
248  return union_start_gt(i1.s, i1.sopen, i2.s, i2.sopen);
249  }
250  inline bool union_start_le(const interval& i1, const interval& i2) {
251  return !union_start_gt(i1,i2);
252  }
253  inline bool union_start_ge(const interval& i1, const interval& i2) {
254  return !union_start_lt(i1,i2);
255  }
256  inline bool union_end_lt(const interval& i1, const interval& i2) {
257  return union_end_lt(i1.e, i1.eopen, i2.e, i2.eopen);
258  }
259  inline bool union_end_gt(const interval& i1, const interval& i2) {
260  return union_end_gt(i1.e, i1.eopen, i2.e, i2.eopen);
261  }
262  inline bool union_end_le(const interval& i1, const interval& i2) {
263  return !union_end_gt(i1,i2);
264  }
265  inline bool union_end_ge(const interval& i1, const interval& i2) {
266  return !union_end_lt(i1,i2);
267  }
268 
271  inline bool union_end_lt_start(const interval& i1, const interval& i2) {
272  return union_end_lt(i1.e, i1.eopen, i2.s, i2.sopen);
273  }
274  inline bool union_end_gt_start(const interval& i1, const interval& i2) {
275  return union_end_gt(i1.e, i1.eopen, i2.s, i2.sopen);
276  }
280  inline bool union_end_ge_start(const interval& i1, const interval& i2) {
281  return !union_end_lt_start(i1, i2);
282  }
283  inline bool union_end_le_start(const interval& i1, const interval& i2) {
284  return !union_end_gt_start(i1, i2);
285  }
286 
287 }
288 
289 #endif
tz::operator<
bool operator<(const period &p1, const period &p2)
Definition: period.hpp:79
tz
Timezone handling and temporal types and functions depending on timezones.
Definition: period.hpp:28
tz::union_start_lt
bool union_start_lt(Global::dtime s1, bool sopen1, Global::dtime s2, bool sopen2)
Definition: interval.hpp:210
tz::end_lt_start
bool end_lt_start(const interval &i1, const interval &i2)
Definition: interval.hpp:189
tz::interval
Definition: interval.hpp:31
tz::union_end_lt_start
bool union_end_lt_start(const interval &i1, const interval &i2)
Definition: interval.hpp:271
tz::end_ge_start
bool end_ge_start(const interval &i1, const interval &i2)
Definition: interval.hpp:198
tz::union_end_ge_start
bool union_end_ge_start(const interval &i1, const interval &i2)
Definition: interval.hpp:280