source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/date_time/period.hpp @ 44

Last change on this file since 44 was 44, checked in by cholod, 12 years ago

Load NEMO_TMP into vendor/nemo/current.

File size: 10.8 KB
Line 
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 15:00:24 -0500 (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
23namespace boost {
24namespace 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
Note: See TracBrowser for help on using the repository browser.