period.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 364 行
HPP
364 行
#ifndef DATE_TIME_PERIOD_HPP___#define DATE_TIME_PERIOD_HPP___/* Copyright (c) 2002,2003 CrystalClear Software, Inc. * Use, modification and distribution is subject to the * Boost Software License, Version 1.0. (See accompanying * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0) * Author: Jeff Garland, Bart Garst * $Date: 2004/11/20 10:36:28 $ *//*! \file period.hpp This file contain the implementation of the period abstraction. This is basically the same idea as a range. Although this class is intended for use in the time library, it is pretty close to general enough for other numeric uses.*/#include "boost/operators.hpp"namespace boost {namespace date_time { //!Provides generalized period type useful in date-time systems /*!This template uses a class to represent a time point within the period and another class to represent a duration. As a result, this class is not appropriate for use when the number and duration representation are the same (eg: in the regular number domain). A period can be specified by providing either the starting point and a duration or the starting point and the end point( end is NOT part of the period but 1 unit past it. A period will be "invalid" if either start_point >= end_point or the given duration is < 0. Any valid period will return false for is_null(). Zero length periods are considered valid. In this case the start point is exactly 1 unit less than the end point, in other words start is equal to last. In the case that the begin and last are the same, the period has a length of zero units. For example, suppose this is a period of days. That is, each time-point represents a single day. If the start and the last is the same day then the period is zero length. The best way to handle periods is usually to provide a start point and a duration. So, day1 + 7 days is a week period which includes all of the first day and 6 more days (eg: Sun to Sat). */ template<class point_rep, class duration_rep> class period : private boost::less_than_comparable<period<point_rep, duration_rep> , boost::equality_comparable< period<point_rep, duration_rep> > > { public: typedef point_rep point_type; typedef duration_rep duration_type; period(point_rep first_point, point_rep end_point); period(point_rep first_point, duration_rep len); point_rep begin() const; point_rep end() const; point_rep last() const; duration_rep length() const; bool is_null() const; bool operator==(const period& rhs) const; bool operator<(const period& rhs) const; void shift(const duration_rep& d); bool contains(const point_rep& point) const; bool contains(const period& other) const; bool intersects(const period& other) const; bool is_adjacent(const period& other) const; bool is_before(const point_rep& point) const; bool is_after(const point_rep& point) const; period intersection(const period& other) const; period merge(const period& other) const; period span(const period& other) const; private: point_rep begin_; point_rep last_; }; //! create a period from begin to last eg: [begin,end) /*! If end <= begin then the period will be invalid */ template<class point_rep, class duration_rep> inline period<point_rep,duration_rep>::period(point_rep first_point, point_rep end_point) : begin_(first_point), last_(end_point - duration_rep::unit()) {} //! create a period as [begin, begin+len) /*! If len is < 0 then the period will be invalid */ template<class point_rep, class duration_rep> inline period<point_rep,duration_rep>::period(point_rep first_point, duration_rep len) : begin_(first_point), last_(first_point + len-duration_rep::unit()) { if(len.get_rep() > 0){ // stick with initializer list } else if(len.get_rep() == 0){ last_ = first_point; } else if(len.get_rep() < 0){ last_ = begin_ + len; } } //! Return the first element in the period template<class point_rep, class duration_rep> inline point_rep period<point_rep,duration_rep>::begin() const { return begin_; } //! Return one past the last element template<class point_rep, class duration_rep> inline point_rep period<point_rep,duration_rep>::end() const { return last_ + duration_rep::unit(); } //! Return the last item in the period template<class point_rep, class duration_rep> inline point_rep period<point_rep,duration_rep>::last() const { return last_; } //! True if period is ill formed (length less than zero) template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::is_null() const { return end() <= begin_; } //! Return the length of the period template<class point_rep, class duration_rep> inline duration_rep period<point_rep,duration_rep>::length() const { if(begin_ == last_){ // zero_length return begin_ - last_; } else if(is_null()){ // invalid period return last_ - begin_; } else{ return end() - begin_; // normal case } } //! Equality operator template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::operator==(const period& rhs) const { return ((begin_ == rhs.begin_) && (last_ == rhs.last_)); } //! Strict as defined by rhs.last <= lhs.last template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::operator<(const period& rhs) const { return (last_ < rhs.begin_); } //! Shift the start and end by the specified amount template<class point_rep, class duration_rep> inline void period<point_rep,duration_rep>::shift(const duration_rep& d) { begin_ = begin_ + d; last_ = last_ + d; } //! True if the point is inside the period template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::contains(const point_rep& point) const { return ((point >= begin_) && (point <= last_)); } //! True if this period fully contains (or equals) the other period template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::contains(const period<point_rep,duration_rep>& other) const { return ((begin_ <= other.begin_) && (last_ >= other.last_)); } //! True if periods are next to each other without a gap. /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent * with either of p1 or p2. *@code * [-p1-) * [-p2-) * [-p3-) *@endcode */ template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::is_adjacent(const period<point_rep,duration_rep>& other) const { return (other.begin() == end() || begin_ == other.end()); } //! True if all of the period is prior or t < start /* In the example below only point 1 would evaluate to true. *@code * [---------]) * ^ ^ ^ ^ ^ * 1 2 3 4 5 * *@endcode */ template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::is_after(const point_rep& t) const { if (is_null()) { return false; //null period isn't after } return t < begin_; } //! True if all of the period is prior to the passed point or end <= t /* In the example below points 4 and 5 return true. *@code * [---------]) * ^ ^ ^ ^ ^ * 1 2 3 4 5 * *@endcode */ template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::is_before(const point_rep& t) const { if (is_null()) { return false; //null period isn't before anything } return last_ < t; } //! True if the periods overlap in any way /* In the example below p1 intersects with p2, p4, and p6. *@code * [---p1---) * [---p2---) * [---p3---) * [---p4---) * [-p5-) * [-p6-) *@endcode */ template<class point_rep, class duration_rep> inline bool period<point_rep,duration_rep>::intersects(const period<point_rep,duration_rep>& other) const { return ( contains(other.begin_) || other.contains(begin_) || ((other.begin_ < begin_) && (other.last_ >= begin_))); } //! Returns the period of intersection or invalid range no intersection template<class point_rep, class duration_rep> inline period<point_rep,duration_rep> period<point_rep,duration_rep>::intersection(const period<point_rep,duration_rep>& other) const { if (begin_ > other.begin_) { if (last_ <= other.last_) { //case2 return *this; } //case 1 return period<point_rep,duration_rep>(begin_, other.end()); } else { if (last_ <= other.last_) { //case3 return period<point_rep,duration_rep>(other.begin_, this->end()); } //case4 return other; } //unreachable } //! Returns the union of intersecting periods -- or null period /*! */ template<class point_rep, class duration_rep> inline period<point_rep,duration_rep> period<point_rep,duration_rep>::merge(const period<point_rep,duration_rep>& other) const { if (this->intersects(other)) { if (begin_ < other.begin_) { return period<point_rep,duration_rep>(begin_, last_ > other.last_ ? this->end() : other.end()); } return period<point_rep,duration_rep>(other.begin_, last_ > other.last_ ? this->end() : other.end()); } return period<point_rep,duration_rep>(begin_,begin_); // no intersect return null } //! Combine two periods with earliest start and latest end. /*! Combines two periods and any gap between them such that * start = min(p1.start, p2.start) * end = max(p1.end , p2.end) *@code * [---p1---) * [---p2---) * result: * [-----------p3----------) *@endcode */ template<class point_rep, class duration_rep> inline period<point_rep,duration_rep> period<point_rep,duration_rep>::span(const period<point_rep,duration_rep>& other) const { point_rep start((begin_ < other.begin_) ? begin() : other.begin()); point_rep newend((last_ < other.last_) ? other.end() : this->end()); return period<point_rep,duration_rep>(start, newend); }} } //namespace date_time#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?