Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/date_time/period.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 #ifndef DATE_TIME_PERIOD_HPP___ | |
2 #define DATE_TIME_PERIOD_HPP___ | |
3 | |
4 /* Copyright (c) 2002,2003 CrystalClear Software, Inc. | |
5 * Use, modification and distribution is subject to the | |
6 * Boost Software License, Version 1.0. (See accompanying | |
7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
8 * Author: Jeff Garland, Bart Garst | |
9 * $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $ | |
10 */ | |
11 | |
12 /*! \file period.hpp | |
13 This file contain the implementation of the period abstraction. This is | |
14 basically the same idea as a range. Although this class is intended for | |
15 use in the time library, it is pretty close to general enough for other | |
16 numeric uses. | |
17 | |
18 */ | |
19 | |
20 #include "boost/operators.hpp" | |
21 | |
22 | |
23 namespace boost { | |
24 namespace date_time { | |
25 //!Provides generalized period type useful in date-time systems | |
26 /*!This template uses a class to represent a time point within the period | |
27 and another class to represent a duration. As a result, this class is | |
28 not appropriate for use when the number and duration representation | |
29 are the same (eg: in the regular number domain). | |
30 | |
31 A period can be specified by providing either the begining point and | |
32 a duration or the begining point and the end point( end is NOT part | |
33 of the period but 1 unit past it. A period will be "invalid" if either | |
34 end_point <= begin_point or the given duration is <= 0. Any valid period | |
35 will return false for is_null(). | |
36 | |
37 Zero length periods are also considered invalid. Zero length periods are | |
38 periods where the begining and end points are the same, or, the given | |
39 duration is zero. For a zero length period, the last point will be one | |
40 unit less than the begining point. | |
41 | |
42 In the case that the begin and last are the same, the period has a | |
43 length of one unit. | |
44 | |
45 The best way to handle periods is usually to provide a begining point and | |
46 a duration. So, day1 + 7 days is a week period which includes all of the | |
47 first day and 6 more days (eg: Sun to Sat). | |
48 | |
49 */ | |
50 template<class point_rep, class duration_rep> | |
51 class period : private | |
52 boost::less_than_comparable<period<point_rep, duration_rep> | |
53 , boost::equality_comparable< period<point_rep, duration_rep> | |
54 > > | |
55 { | |
56 public: | |
57 typedef point_rep point_type; | |
58 typedef duration_rep duration_type; | |
59 | |
60 period(point_rep first_point, point_rep end_point); | |
61 period(point_rep first_point, duration_rep len); | |
62 point_rep begin() const; | |
63 point_rep end() const; | |
64 point_rep last() const; | |
65 duration_rep length() const; | |
66 bool is_null() const; | |
67 bool operator==(const period& rhs) const; | |
68 bool operator<(const period& rhs) const; | |
69 void shift(const duration_rep& d); | |
70 void expand(const duration_rep& d); | |
71 bool contains(const point_rep& point) const; | |
72 bool contains(const period& other) const; | |
73 bool intersects(const period& other) const; | |
74 bool is_adjacent(const period& other) const; | |
75 bool is_before(const point_rep& point) const; | |
76 bool is_after(const point_rep& point) const; | |
77 period intersection(const period& other) const; | |
78 period merge(const period& other) const; | |
79 period span(const period& other) const; | |
80 private: | |
81 point_rep begin_; | |
82 point_rep last_; | |
83 }; | |
84 | |
85 //! create a period from begin to last eg: [begin,end) | |
86 /*! If end <= begin then the period will be invalid | |
87 */ | |
88 template<class point_rep, class duration_rep> | |
89 inline | |
90 period<point_rep,duration_rep>::period(point_rep first_point, | |
91 point_rep end_point) : | |
92 begin_(first_point), | |
93 last_(end_point - duration_rep::unit()) | |
94 {} | |
95 | |
96 //! create a period as [begin, begin+len) | |
97 /*! If len is <= 0 then the period will be invalid | |
98 */ | |
99 template<class point_rep, class duration_rep> | |
100 inline | |
101 period<point_rep,duration_rep>::period(point_rep first_point, duration_rep len) : | |
102 begin_(first_point), | |
103 last_(first_point + len-duration_rep::unit()) | |
104 { } | |
105 | |
106 | |
107 //! Return the first element in the period | |
108 template<class point_rep, class duration_rep> | |
109 inline | |
110 point_rep period<point_rep,duration_rep>::begin() const | |
111 { | |
112 return begin_; | |
113 } | |
114 | |
115 //! Return one past the last element | |
116 template<class point_rep, class duration_rep> | |
117 inline | |
118 point_rep period<point_rep,duration_rep>::end() const | |
119 { | |
120 return last_ + duration_rep::unit(); | |
121 } | |
122 | |
123 //! Return the last item in the period | |
124 template<class point_rep, class duration_rep> | |
125 inline | |
126 point_rep period<point_rep,duration_rep>::last() const | |
127 { | |
128 return last_; | |
129 } | |
130 | |
131 //! True if period is ill formed (length is zero or less) | |
132 template<class point_rep, class duration_rep> | |
133 inline | |
134 bool period<point_rep,duration_rep>::is_null() const | |
135 { | |
136 return end() <= begin_; | |
137 } | |
138 | |
139 //! Return the length of the period | |
140 template<class point_rep, class duration_rep> | |
141 inline | |
142 duration_rep period<point_rep,duration_rep>::length() const | |
143 { | |
144 if(last_ < begin_){ // invalid period | |
145 return last_+duration_rep::unit() - begin_; | |
146 } | |
147 else{ | |
148 return end() - begin_; // normal case | |
149 } | |
150 } | |
151 | |
152 //! Equality operator | |
153 template<class point_rep, class duration_rep> | |
154 inline | |
155 bool period<point_rep,duration_rep>::operator==(const period& rhs) const | |
156 { | |
157 return ((begin_ == rhs.begin_) && | |
158 (last_ == rhs.last_)); | |
159 } | |
160 | |
161 //! Strict as defined by rhs.last <= lhs.last | |
162 template<class point_rep, class duration_rep> | |
163 inline | |
164 bool period<point_rep,duration_rep>::operator<(const period& rhs) const | |
165 { | |
166 return (last_ < rhs.begin_); | |
167 } | |
168 | |
169 | |
170 //! Shift the start and end by the specified amount | |
171 template<class point_rep, class duration_rep> | |
172 inline | |
173 void period<point_rep,duration_rep>::shift(const duration_rep& d) | |
174 { | |
175 begin_ = begin_ + d; | |
176 last_ = last_ + d; | |
177 } | |
178 | |
179 /** Expands the size of the period by the duration on both ends. | |
180 * | |
181 *So before expand | |
182 *@code | |
183 * | |
184 * [-------] | |
185 * ^ ^ ^ ^ ^ ^ ^ | |
186 * 1 2 3 4 5 6 7 | |
187 * | |
188 *@endcode | |
189 * After expand(2) | |
190 *@code | |
191 * | |
192 * [----------------------] | |
193 * ^ ^ ^ ^ ^ ^ ^ | |
194 * 1 2 3 4 5 6 7 | |
195 * | |
196 *@endcode | |
197 */ | |
198 template<class point_rep, class duration_rep> | |
199 inline | |
200 void period<point_rep,duration_rep>::expand(const duration_rep& d) | |
201 { | |
202 begin_ = begin_ - d; | |
203 last_ = last_ + d; | |
204 } | |
205 | |
206 //! True if the point is inside the period, zero length periods contain no points | |
207 template<class point_rep, class duration_rep> | |
208 inline | |
209 bool period<point_rep,duration_rep>::contains(const point_rep& point) const | |
210 { | |
211 return ((point >= begin_) && | |
212 (point <= last_)); | |
213 } | |
214 | |
215 | |
216 //! True if this period fully contains (or equals) the other period | |
217 template<class point_rep, class duration_rep> | |
218 inline | |
219 bool period<point_rep,duration_rep>::contains(const period<point_rep,duration_rep>& other) const | |
220 { | |
221 return ((begin_ <= other.begin_) && (last_ >= other.last_)); | |
222 } | |
223 | |
224 | |
225 //! True if periods are next to each other without a gap. | |
226 /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent | |
227 * with either of p1 or p2. | |
228 *@code | |
229 * [-p1-) | |
230 * [-p2-) | |
231 * [-p3-) | |
232 *@endcode | |
233 */ | |
234 template<class point_rep, class duration_rep> | |
235 inline | |
236 bool | |
237 period<point_rep,duration_rep>::is_adjacent(const period<point_rep,duration_rep>& other) const | |
238 { | |
239 return (other.begin() == end() || | |
240 begin_ == other.end()); | |
241 } | |
242 | |
243 | |
244 //! True if all of the period is prior or t < start | |
245 /* In the example below only point 1 would evaluate to true. | |
246 *@code | |
247 * [---------]) | |
248 * ^ ^ ^ ^ ^ | |
249 * 1 2 3 4 5 | |
250 * | |
251 *@endcode | |
252 */ | |
253 template<class point_rep, class duration_rep> | |
254 inline | |
255 bool | |
256 period<point_rep,duration_rep>::is_after(const point_rep& t) const | |
257 { | |
258 if (is_null()) | |
259 { | |
260 return false; //null period isn't after | |
261 } | |
262 | |
263 return t < begin_; | |
264 } | |
265 | |
266 //! True if all of the period is prior to the passed point or end <= t | |
267 /* In the example below points 4 and 5 return true. | |
268 *@code | |
269 * [---------]) | |
270 * ^ ^ ^ ^ ^ | |
271 * 1 2 3 4 5 | |
272 * | |
273 *@endcode | |
274 */ | |
275 template<class point_rep, class duration_rep> | |
276 inline | |
277 bool | |
278 period<point_rep,duration_rep>::is_before(const point_rep& t) const | |
279 { | |
280 if (is_null()) | |
281 { | |
282 return false; //null period isn't before anything | |
283 } | |
284 | |
285 return last_ < t; | |
286 } | |
287 | |
288 | |
289 //! True if the periods overlap in any way | |
290 /* In the example below p1 intersects with p2, p4, and p6. | |
291 *@code | |
292 * [---p1---) | |
293 * [---p2---) | |
294 * [---p3---) | |
295 * [---p4---) | |
296 * [-p5-) | |
297 * [-p6-) | |
298 *@endcode | |
299 */ | |
300 template<class point_rep, class duration_rep> | |
301 inline | |
302 bool period<point_rep,duration_rep>::intersects(const period<point_rep,duration_rep>& other) const | |
303 { | |
304 return ( contains(other.begin_) || | |
305 other.contains(begin_) || | |
306 ((other.begin_ < begin_) && (other.last_ >= begin_))); | |
307 } | |
308 | |
309 //! Returns the period of intersection or invalid range no intersection | |
310 template<class point_rep, class duration_rep> | |
311 inline | |
312 period<point_rep,duration_rep> | |
313 period<point_rep,duration_rep>::intersection(const period<point_rep,duration_rep>& other) const | |
314 { | |
315 if (begin_ > other.begin_) { | |
316 if (last_ <= other.last_) { //case2 | |
317 return *this; | |
318 } | |
319 //case 1 | |
320 return period<point_rep,duration_rep>(begin_, other.end()); | |
321 } | |
322 else { | |
323 if (last_ <= other.last_) { //case3 | |
324 return period<point_rep,duration_rep>(other.begin_, this->end()); | |
325 } | |
326 //case4 | |
327 return other; | |
328 } | |
329 //unreachable | |
330 } | |
331 | |
332 //! Returns the union of intersecting periods -- or null period | |
333 /*! | |
334 */ | |
335 template<class point_rep, class duration_rep> | |
336 inline | |
337 period<point_rep,duration_rep> | |
338 period<point_rep,duration_rep>::merge(const period<point_rep,duration_rep>& other) const | |
339 { | |
340 if (this->intersects(other)) { | |
341 if (begin_ < other.begin_) { | |
342 return period<point_rep,duration_rep>(begin_, last_ > other.last_ ? this->end() : other.end()); | |
343 } | |
344 | |
345 return period<point_rep,duration_rep>(other.begin_, last_ > other.last_ ? this->end() : other.end()); | |
346 | |
347 } | |
348 return period<point_rep,duration_rep>(begin_,begin_); // no intersect return null | |
349 } | |
350 | |
351 //! Combine two periods with earliest start and latest end. | |
352 /*! Combines two periods and any gap between them such that | |
353 * start = min(p1.start, p2.start) | |
354 * end = max(p1.end , p2.end) | |
355 *@code | |
356 * [---p1---) | |
357 * [---p2---) | |
358 * result: | |
359 * [-----------p3----------) | |
360 *@endcode | |
361 */ | |
362 template<class point_rep, class duration_rep> | |
363 inline | |
364 period<point_rep,duration_rep> | |
365 period<point_rep,duration_rep>::span(const period<point_rep,duration_rep>& other) const | |
366 { | |
367 point_rep start((begin_ < other.begin_) ? begin() : other.begin()); | |
368 point_rep newend((last_ < other.last_) ? other.end() : this->end()); | |
369 return period<point_rep,duration_rep>(start, newend); | |
370 } | |
371 | |
372 | |
373 } } //namespace date_time | |
374 | |
375 | |
376 | |
377 #endif |