annotate DEPENDENCIES/generic/include/boost/date_time/period.hpp @ 125:34e428693f5d vext

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