| // Written in the D programming language |
| |
| /++ |
| $(SCRIPT inhibitQuickIndex = 1;) |
| $(DIVC quickindex, |
| $(BOOKTABLE, |
| $(TR $(TH Category) $(TH Functions)) |
| $(TR $(TD Main types) $(TD |
| $(LREF Interval) |
| $(LREF Direction) |
| )) |
| $(TR $(TD Special intervals) $(TD |
| $(LREF everyDayOfWeek) |
| $(LREF everyMonth) |
| $(LREF everyDuration) |
| )) |
| $(TR $(TD Special intervals) $(TD |
| $(LREF NegInfInterval) |
| $(LREF PosInfInterval) |
| )) |
| $(TR $(TD Underlying ranges) $(TD |
| $(LREF IntervalRange) |
| $(LREF NegInfIntervalRange) |
| $(LREF PosInfIntervalRange) |
| )) |
| $(TR $(TD Flags) $(TD |
| $(LREF PopFirst) |
| )) |
| )) |
| |
| License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). |
| Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) |
| Source: $(PHOBOSSRC std/datetime/interval.d) |
| +/ |
| module std.datetime.interval; |
| |
| import core.time : Duration, dur; |
| import std.datetime.date : AllowDayOverflow, DateTimeException, daysToDayOfWeek, |
| DayOfWeek, isTimePoint, Month; |
| import std.exception : enforce; |
| import std.range.primitives : isOutputRange; |
| import std.traits : isIntegral; |
| import std.typecons : Flag; |
| |
| version (StdUnittest) import std.exception : assertThrown; |
| |
| |
| /++ |
| Indicates a direction in time. One example of its use is $(LREF Interval)'s |
| $(LREF expand) function which uses it to indicate whether the interval |
| should be expanded backwards (into the past), forwards (into the future), or |
| both. |
| +/ |
| enum Direction |
| { |
| /// Backward. |
| bwd, |
| |
| /// Forward. |
| fwd, |
| |
| /// Both backward and forward. |
| both |
| } |
| |
| |
| /++ |
| Used to indicate whether `popFront` should be called immediately upon |
| creating a range. The idea is that for some functions used to generate a |
| range for an interval, `front` is not necessarily a time point which |
| would ever be generated by the range (e.g. if the range were every Sunday |
| within an interval, but the interval started on a Monday), so there needs |
| to be a way to deal with that. To get the first time point in the range to |
| match what the function generates, then use `PopFirst.yes` to indicate |
| that the range should have `popFront` called on it before the range is |
| returned so that `front` is a time point which the function would |
| generate. To let the first time point not match the generator function, |
| use `PopFront.no`. |
| |
| For instance, if the function used to generate a range of time points |
| generated successive Easters (i.e. you're iterating over all of the Easters |
| within the interval), the initial date probably isn't an Easter. Using |
| `PopFirst.yes` would tell the function which returned the range that |
| `popFront` was to be called so that front would then be an Easter - the |
| next one generated by the function (which when iterating forward would be |
| the Easter following the original `front`, while when iterating backward, |
| it would be the Easter prior to the original `front`). If |
| `PopFirst.no` were used, then `front` would remain the original time |
| point and it would not necessarily be a time point which would be generated |
| by the range-generating function (which in many cases is exactly what is |
| desired - e.g. if iterating over every day starting at the beginning of the |
| interval). |
| |
| If set to `PopFirst.no`, then popFront is not called before returning |
| the range. |
| |
| Otherwise, if set to `PopFirst.yes`, then popFront is called before |
| returning the range. |
| +/ |
| alias PopFirst = Flag!"popFirst"; |
| |
| |
| /++ |
| Represents an interval of time. |
| |
| An `Interval` has a starting point and an end point. The interval of time |
| is therefore the time starting at the starting point up to, but not |
| including, the end point. e.g. |
| |
| $(BOOKTABLE, |
| $(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN))) |
| $(TR $(TD [05:00:30 - 12:00:00$(RPAREN))) |
| $(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN))) |
| ) |
| |
| A range can be obtained from an `Interval`, allowing iteration over |
| that interval, with the exact time points which are iterated over depending |
| on the function which generates the range. |
| +/ |
| struct Interval(TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| begin = The time point which begins the interval. |
| end = The time point which ends (but is not included in) the |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D_PARAM end) is |
| before $(D_PARAM begin). |
| |
| Example: |
| -------------------- |
| Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| -------------------- |
| +/ |
| this(U)(scope const TP begin, scope const U end) pure |
| if (is(immutable TP == immutable U)) |
| { |
| if (!_valid(begin, end)) |
| throw new DateTimeException("Arguments would result in an invalid Interval."); |
| _begin = cast(TP) begin; |
| _end = cast(TP) end; |
| } |
| |
| |
| /++ |
| Params: |
| begin = The time point which begins the interval. |
| duration = The duration from the starting point to the end point. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the resulting |
| `end` is before `begin`. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == |
| Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); |
| -------------------- |
| +/ |
| this(D)(scope const TP begin, scope const D duration) pure |
| if (__traits(compiles, begin + duration)) |
| { |
| _begin = cast(TP) begin; |
| _end = begin + duration; |
| if (!_valid(_begin, _end)) |
| throw new DateTimeException("Arguments would result in an invalid Interval."); |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The $(LREF Interval) to assign to this one. |
| +/ |
| ref Interval opAssign(const ref Interval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| _end = cast(TP) rhs._end; |
| return this; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The $(LREF Interval) to assign to this one. |
| +/ |
| ref Interval opAssign(Interval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| _end = cast(TP) rhs._end; |
| return this; |
| } |
| |
| |
| /++ |
| The starting point of the interval. It is included in the interval. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == |
| Date(1996, 1, 2)); |
| -------------------- |
| +/ |
| @property TP begin() const pure nothrow |
| { |
| return cast(TP) _begin; |
| } |
| |
| |
| /++ |
| The starting point of the interval. It is included in the interval. |
| |
| Params: |
| timePoint = The time point to set `begin` to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the resulting |
| interval would be invalid. |
| +/ |
| @property void begin(TP timePoint) pure |
| { |
| if (!_valid(timePoint, _end)) |
| throw new DateTimeException("Arguments would result in an invalid Interval."); |
| _begin = timePoint; |
| } |
| |
| |
| /++ |
| The end point of the interval. It is excluded from the interval. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == |
| Date(2012, 3, 1)); |
| -------------------- |
| +/ |
| @property TP end() const pure nothrow |
| { |
| return cast(TP) _end; |
| } |
| |
| |
| /++ |
| The end point of the interval. It is excluded from the interval. |
| |
| Params: |
| timePoint = The time point to set end to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the resulting |
| interval would be invalid. |
| +/ |
| @property void end(TP timePoint) pure |
| { |
| if (!_valid(_begin, timePoint)) |
| throw new DateTimeException("Arguments would result in an invalid Interval."); |
| _end = timePoint; |
| } |
| |
| |
| /++ |
| Returns the duration between `begin` and `end`. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == |
| dur!"days"(5903)); |
| -------------------- |
| +/ |
| @property auto length() const pure nothrow |
| { |
| return _end - _begin; |
| } |
| |
| |
| /++ |
| Whether the interval's length is 0, that is, whether $(D begin == end). |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); |
| -------------------- |
| +/ |
| @property bool empty() const pure nothrow |
| { |
| return _begin == _end; |
| } |
| |
| |
| /++ |
| Whether the given time point is within this interval. |
| |
| Params: |
| timePoint = The time point to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Date(1994, 12, 24))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Date(2000, 1, 5))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool contains(scope const TP timePoint) const pure |
| { |
| _enforceNotEmpty(); |
| return timePoint >= _begin && timePoint < _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| -------------------- |
| +/ |
| bool contains(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| return interval._begin >= _begin && |
| interval._begin < _end && |
| interval._end <= _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Always returns false (unless this interval is empty), because an |
| interval going to positive infinity can never be contained in a finite |
| interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool contains(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Always returns false (unless this interval is empty), because an |
| interval beginning at negative infinity can never be contained in a |
| finite interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool contains(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is before |
| it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Date(1994, 12, 24))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Date(2000, 1, 5))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool isBefore(scope const TP timePoint) const pure |
| { |
| _enforceNotEmpty(); |
| return _end <= timePoint; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect with it. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| return _end <= interval._begin; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect with it. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| PosInfInterval!Date(Date(2013, 3, 7)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _end <= interval._begin; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect with it. |
| |
| Always returns false (unless this interval is empty) because a finite |
| interval can never be before an interval beginning at negative infinity. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is after |
| it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Date(1994, 12, 24))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Date(2000, 1, 5))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool isAfter(scope const TP timePoint) const pure |
| { |
| _enforceNotEmpty(); |
| return timePoint < _begin; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Always returns false (unless this interval is empty) because a finite |
| interval can never be after an interval going to positive infinity. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool intersects(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| return interval._begin < _end && interval._end > _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool intersects(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _end > interval._begin; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| NegInfInterval!Date(Date(2000, 1, 2)))); |
| -------------------- |
| +/ |
| bool intersects(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _begin < interval._end; |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if either interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); |
| -------------------- |
| +/ |
| Interval intersection(scope const Interval interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| auto begin = _begin > interval._begin ? _begin : interval._begin; |
| auto end = _end < interval._end ? _end : interval._end; |
| |
| return Interval(begin, end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if this interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| Interval intersection(scope const PosInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| return Interval(_begin > interval._begin ? _begin : interval._begin, _end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if this interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| Interval intersection(scope const NegInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| return Interval(_begin, _end < interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| return _begin == interval._end || _end == interval._begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _end == interval._begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| NegInfInterval!Date(Date(2000, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return _begin == interval._end; |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if either interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); |
| -------------------- |
| +/ |
| Interval merge(scope const Interval interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.isAdjacent(interval) || this.intersects(interval), |
| new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); |
| |
| auto begin = _begin < interval._begin ? _begin : interval._begin; |
| auto end = _end > interval._end ? _end : interval._end; |
| |
| return Interval(begin, end); |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if this interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| PosInfInterval!Date(Date(2012, 3, 1))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval!TP merge(scope const PosInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.isAdjacent(interval) || this.intersects(interval), |
| new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); |
| |
| return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if this interval is empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| NegInfInterval!Date(Date(1996, 1, 2))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| -------------------- |
| +/ |
| NegInfInterval!TP merge(scope const NegInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.isAdjacent(interval) || this.intersects(interval), |
| new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); |
| |
| return NegInfInterval!TP(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if either interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); |
| -------------------- |
| +/ |
| Interval span(scope const Interval interval) const pure |
| { |
| _enforceNotEmpty(); |
| interval._enforceNotEmpty(); |
| |
| auto begin = _begin < interval._begin ? _begin : interval._begin; |
| auto end = _end > interval._end ? _end : interval._end; |
| |
| return Interval(begin, end); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| PosInfInterval!Date(Date(2050, 1, 1))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval!TP span(scope const PosInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Example: |
| -------------------- |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| NegInfInterval!Date(Date(1602, 5, 21))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| -------------------- |
| +/ |
| NegInfInterval!TP span(scope const NegInfInterval!TP interval) const pure |
| { |
| _enforceNotEmpty(); |
| return NegInfInterval!TP(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Shifts the interval forward or backwards in time by the given duration |
| (a positive duration shifts the interval forward; a negative duration |
| shifts it backward). Effectively, it does $(D begin += duration) and |
| $(D end += duration). |
| |
| Params: |
| duration = The duration to shift the interval by. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) this interval is empty |
| or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); |
| -------------------- |
| +/ |
| void shift(D)(D duration) pure |
| if (__traits(compiles, begin + duration)) |
| { |
| _enforceNotEmpty(); |
| |
| auto begin = _begin + duration; |
| auto end = _end + duration; |
| |
| if (!_valid(begin, end)) |
| throw new DateTimeException("Argument would result in an invalid Interval."); |
| |
| _begin = begin; |
| _end = end; |
| } |
| |
| |
| static if (__traits(compiles, begin.add!"months"(1)) && |
| __traits(compiles, begin.add!"years"(1))) |
| { |
| /++ |
| Shifts the interval forward or backwards in time by the given number |
| of years and/or months (a positive number of years and months shifts |
| the interval forward; a negative number shifts it backward). |
| It adds the years the given years and months to both begin and end. |
| It effectively calls `add!"years"()` and then `add!"months"()` |
| on begin and end with the given number of years and months. |
| |
| Params: |
| years = The number of years to shift the interval by. |
| months = The number of months to shift the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `begin` and `end`, causing their month |
| to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.shift(2); |
| assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); |
| |
| interval2.shift(-2); |
| assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); |
| -------------------- |
| +/ |
| void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| _enforceNotEmpty(); |
| |
| auto begin = _begin; |
| auto end = _end; |
| |
| begin.add!"years"(years, allowOverflow); |
| begin.add!"months"(months, allowOverflow); |
| end.add!"years"(years, allowOverflow); |
| end.add!"months"(months, allowOverflow); |
| |
| enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); |
| |
| _begin = begin; |
| _end = end; |
| } |
| } |
| |
| |
| /++ |
| Expands the interval forwards and/or backwards in time. Effectively, |
| it does $(D begin -= duration) and/or $(D end += duration). Whether |
| it expands forwards and/or backwards in time is determined by |
| $(D_PARAM dir). |
| |
| Params: |
| duration = The duration to expand the interval by. |
| dir = The direction in time to expand the interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) this interval is empty |
| or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.expand(2); |
| assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); |
| |
| interval2.expand(-2); |
| assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); |
| -------------------- |
| +/ |
| void expand(D)(D duration, Direction dir = Direction.both) pure |
| if (__traits(compiles, begin + duration)) |
| { |
| _enforceNotEmpty(); |
| |
| switch (dir) |
| { |
| case Direction.both: |
| { |
| auto begin = _begin - duration; |
| auto end = _end + duration; |
| |
| if (!_valid(begin, end)) |
| throw new DateTimeException("Argument would result in an invalid Interval."); |
| |
| _begin = begin; |
| _end = end; |
| |
| return; |
| } |
| case Direction.fwd: |
| { |
| auto end = _end + duration; |
| |
| if (!_valid(_begin, end)) |
| throw new DateTimeException("Argument would result in an invalid Interval."); |
| _end = end; |
| |
| return; |
| } |
| case Direction.bwd: |
| { |
| auto begin = _begin - duration; |
| |
| if (!_valid(begin, _end)) |
| throw new DateTimeException("Argument would result in an invalid Interval."); |
| _begin = begin; |
| |
| return; |
| } |
| default: |
| assert(0, "Invalid Direction."); |
| } |
| } |
| |
| static if (__traits(compiles, begin.add!"months"(1)) && |
| __traits(compiles, begin.add!"years"(1))) |
| { |
| /++ |
| Expands the interval forwards and/or backwards in time. Effectively, |
| it subtracts the given number of months/years from `begin` and |
| adds them to `end`. Whether it expands forwards and/or backwards |
| in time is determined by $(D_PARAM dir). |
| |
| Params: |
| years = The number of years to expand the interval by. |
| months = The number of months to expand the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `begin` and `end`, causing their month |
| to increment. |
| dir = The direction in time to expand the interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.expand(2); |
| assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); |
| |
| interval2.expand(-2); |
| assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); |
| -------------------- |
| +/ |
| void expand(T)(T years, |
| T months = 0, |
| AllowDayOverflow allowOverflow = AllowDayOverflow.yes, |
| Direction dir = Direction.both) |
| if (isIntegral!T) |
| { |
| _enforceNotEmpty(); |
| |
| switch (dir) |
| { |
| case Direction.both: |
| { |
| auto begin = _begin; |
| auto end = _end; |
| |
| begin.add!"years"(-years, allowOverflow); |
| begin.add!"months"(-months, allowOverflow); |
| end.add!"years"(years, allowOverflow); |
| end.add!"months"(months, allowOverflow); |
| |
| enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval.")); |
| _begin = begin; |
| _end = end; |
| |
| return; |
| } |
| case Direction.fwd: |
| { |
| auto end = _end; |
| |
| end.add!"years"(years, allowOverflow); |
| end.add!"months"(months, allowOverflow); |
| |
| enforce(_valid(_begin, end), |
| new DateTimeException("Argument would result in an invalid Interval.")); |
| _end = end; |
| |
| return; |
| } |
| case Direction.bwd: |
| { |
| auto begin = _begin; |
| |
| begin.add!"years"(-years, allowOverflow); |
| begin.add!"months"(-months, allowOverflow); |
| |
| enforce(_valid(begin, _end), |
| new DateTimeException("Argument would result in an invalid Interval.")); |
| _begin = begin; |
| |
| return; |
| } |
| default: |
| assert(0, "Invalid Direction."); |
| } |
| } |
| } |
| |
| |
| /++ |
| Returns a range which iterates forward over the interval, starting |
| at `begin`, using $(D_PARAM func) to generate each successive time |
| point. |
| |
| The range's `front` is the interval's `begin`. $(D_PARAM func) is |
| used to generate the next `front` when `popFront` is called. If |
| $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called |
| before the range is returned (so that `front` is a time point which |
| $(D_PARAM func) would generate). |
| |
| If $(D_PARAM func) ever generates a time point less than or equal to the |
| current `front` of the range, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. The range |
| will be empty and iteration complete when $(D_PARAM func) generates a |
| time point equal to or beyond the `end` of the interval. |
| |
| There are helper functions in this module which generate common |
| delegates to pass to `fwdRange`. Their documentation starts with |
| "Range-generating function," making them easily searchable. |
| |
| Params: |
| func = The function used to generate the time points of the |
| range over the interval. |
| popFirst = Whether `popFront` should be called on the range |
| before returning it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Warning: |
| $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) |
| would be a function pointer to a pure function, but forcing |
| $(D_PARAM func) to be pure is far too restrictive to be useful, and |
| in order to have the ease of use of having functions which generate |
| functions to pass to `fwdRange`, $(D_PARAM func) must be a |
| delegate. |
| |
| If $(D_PARAM func) retains state which changes as it is called, then |
| some algorithms will not work correctly, because the range's |
| `save` will have failed to have really saved the range's state. |
| To avoid such bugs, don't pass a delegate which is |
| not logically pure to `fwdRange`. If $(D_PARAM func) is given the |
| same time point with two different calls, it must return the same |
| result both times. |
| |
| Of course, none of the functions in this module have this problem, |
| so it's only relevant if when creating a custom delegate. |
| |
| Example: |
| -------------------- |
| auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) // For iterating over even-numbered days. |
| { |
| if ((date.day & 1) == 0) |
| return date + dur!"days"(2); |
| |
| return date + dur!"days"(1); |
| }; |
| auto range = interval.fwdRange(func); |
| |
| // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). |
| assert(range.front == Date(2010, 9, 1)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.empty); |
| -------------------- |
| +/ |
| IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const |
| { |
| _enforceNotEmpty(); |
| |
| auto range = IntervalRange!(TP, Direction.fwd)(this, func); |
| |
| if (popFirst == PopFirst.yes) |
| range.popFront(); |
| |
| return range; |
| } |
| |
| |
| /++ |
| Returns a range which iterates backwards over the interval, starting |
| at `end`, using $(D_PARAM func) to generate each successive time |
| point. |
| |
| The range's `front` is the interval's `end`. $(D_PARAM func) is |
| used to generate the next `front` when `popFront` is called. If |
| $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called |
| before the range is returned (so that `front` is a time point which |
| $(D_PARAM func) would generate). |
| |
| If $(D_PARAM func) ever generates a time point greater than or equal to |
| the current `front` of the range, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. The range |
| will be empty and iteration complete when $(D_PARAM func) generates a |
| time point equal to or less than the `begin` of the interval. |
| |
| There are helper functions in this module which generate common |
| delegates to pass to `bwdRange`. Their documentation starts with |
| "Range-generating function," making them easily searchable. |
| |
| Params: |
| func = The function used to generate the time points of the |
| range over the interval. |
| popFirst = Whether `popFront` should be called on the range |
| before returning it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Warning: |
| $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) |
| would be a function pointer to a pure function, but forcing |
| $(D_PARAM func) to be pure is far too restrictive to be useful, and |
| in order to have the ease of use of having functions which generate |
| functions to pass to `fwdRange`, $(D_PARAM func) must be a |
| delegate. |
| |
| If $(D_PARAM func) retains state which changes as it is called, then |
| some algorithms will not work correctly, because the range's |
| `save` will have failed to have really saved the range's state. |
| To avoid such bugs, don't pass a delegate which is |
| not logically pure to `fwdRange`. If $(D_PARAM func) is given the |
| same time point with two different calls, it must return the same |
| result both times. |
| |
| Of course, none of the functions in this module have this problem, |
| so it's only relevant for custom delegates. |
| |
| Example: |
| -------------------- |
| auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) // For iterating over even-numbered days. |
| { |
| if ((date.day & 1) == 0) |
| return date - dur!"days"(2); |
| |
| return date - dur!"days"(1); |
| }; |
| auto range = interval.bwdRange(func); |
| |
| // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). |
| assert(range.front == Date(2010, 9, 9)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.empty); |
| -------------------- |
| +/ |
| IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const |
| { |
| _enforceNotEmpty(); |
| |
| auto range = IntervalRange!(TP, Direction.bwd)(this, func); |
| |
| if (popFirst == PopFirst.yes) |
| range.popFront(); |
| |
| return range; |
| } |
| |
| /++ |
| Converts this interval to a string. |
| Params: |
| w = A `char` accepting |
| $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) |
| Returns: |
| A `string` when not using an output range; `void` otherwise. |
| +/ |
| string toString() const @safe nothrow |
| { |
| import std.array : appender; |
| auto app = appender!string(); |
| try |
| toString(app); |
| catch (Exception e) |
| assert(0, "toString() threw."); |
| return app.data; |
| } |
| |
| /// ditto |
| void toString(Writer)(ref Writer w) const |
| if (isOutputRange!(Writer, char)) |
| { |
| import std.range.primitives : put; |
| put(w, '['); |
| _begin.toString(w); |
| put(w, " - "); |
| _end.toString(w); |
| put(w, ')'); |
| } |
| |
| private: |
| /+ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| +/ |
| void _enforceNotEmpty(size_t line = __LINE__) const pure |
| { |
| if (empty) |
| throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line); |
| } |
| |
| |
| /+ |
| Whether the given values form a valid time interval. |
| |
| Params: |
| begin = The starting point of the interval. |
| end = The end point of the interval. |
| +/ |
| static bool _valid(scope const TP begin, scope const TP end) pure nothrow @trusted |
| { |
| return begin <= end; |
| } |
| |
| |
| pure invariant() |
| { |
| assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end."); |
| } |
| |
| |
| TP _begin; |
| TP _end; |
| } |
| |
| // Test Interval's constructors. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1))); |
| |
| Interval!Date(Date.init, Date.init); |
| Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init); |
| Interval!DateTime(DateTime.init, DateTime.init); |
| Interval!SysTime(SysTime(0), SysTime(0)); |
| |
| Interval!DateTime(DateTime.init, dur!"days"(7)); |
| |
| // Verify Examples. |
| Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23))); |
| assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5))); |
| assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == |
| Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0))); |
| assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == |
| Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0))); |
| assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == |
| Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); |
| assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == |
| Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3))); |
| } |
| |
| // Test Interval's begin. |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin == Date(1, 1, 1)); |
| assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin == Date(2010, 1, 1)); |
| assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin == Date(1997, 12, 31)); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(cInterval.begin == Date(2010, 7, 4)); |
| assert(iInterval.begin == Date(2010, 7, 4)); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2)); |
| } |
| |
| // Test Interval's end. |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); |
| assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end == Date(2010, 1, 1)); |
| assert(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end == Date(1998, 1, 1)); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(cInterval.end == Date(2012, 1, 7)); |
| assert(iInterval.end == Date(2012, 1, 7)); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1)); |
| } |
| |
| // Test Interval's length. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length == dur!"days"(0)); |
| assert(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length == dur!"days"(90)); |
| assert(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length == dur!"seconds"(42_727)); |
| assert(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length == |
| dur!"seconds"(129_127)); |
| assert(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)),SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length == |
| dur!"seconds"(129_127)); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(cInterval.length != Duration.zero); |
| assert(iInterval.length != Duration.zero); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903)); |
| } |
| |
| // Test Interval's empty. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty); |
| assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty); |
| assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty); |
| assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty); |
| assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!cInterval.empty); |
| assert(!iInterval.empty); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty); |
| } |
| |
| // Test Interval's contains(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4))); |
| |
| assert(!interval.contains(Date(2009, 7, 4))); |
| assert(!interval.contains(Date(2010, 7, 3))); |
| assert(interval.contains(Date(2010, 7, 4))); |
| assert(interval.contains(Date(2010, 7, 5))); |
| assert(interval.contains(Date(2011, 7, 1))); |
| assert(interval.contains(Date(2012, 1, 6))); |
| assert(!interval.contains(Date(2012, 1, 7))); |
| assert(!interval.contains(Date(2012, 1, 8))); |
| assert(!interval.contains(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(interval.contains(cdate)); |
| assert(cInterval.contains(cdate)); |
| assert(iInterval.contains(cdate)); |
| |
| // Verify Examples. |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1))); |
| } |
| |
| // Test Interval's contains(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4),dur!"days"(0)).contains( |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(interval.contains(interval)); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval)); |
| assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval)); |
| assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval)); |
| assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval)); |
| |
| assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(interval.contains(interval)); |
| assert(interval.contains(cInterval)); |
| assert(interval.contains(iInterval)); |
| assert(!interval.contains(posInfInterval)); |
| assert(!interval.contains(cPosInfInterval)); |
| assert(!interval.contains(iPosInfInterval)); |
| assert(!interval.contains(negInfInterval)); |
| assert(!interval.contains(cNegInfInterval)); |
| assert(!interval.contains(iNegInfInterval)); |
| assert(cInterval.contains(interval)); |
| assert(cInterval.contains(cInterval)); |
| assert(cInterval.contains(iInterval)); |
| assert(!cInterval.contains(posInfInterval)); |
| assert(!cInterval.contains(cPosInfInterval)); |
| assert(!cInterval.contains(iPosInfInterval)); |
| assert(!cInterval.contains(negInfInterval)); |
| assert(!cInterval.contains(cNegInfInterval)); |
| assert(!cInterval.contains(iNegInfInterval)); |
| assert(iInterval.contains(interval)); |
| assert(iInterval.contains(cInterval)); |
| assert(iInterval.contains(iInterval)); |
| assert(!iInterval.contains(posInfInterval)); |
| assert(!iInterval.contains(cPosInfInterval)); |
| assert(!iInterval.contains(iPosInfInterval)); |
| assert(!iInterval.contains(negInfInterval)); |
| assert(!iInterval.contains(cNegInfInterval)); |
| assert(!iInterval.contains(iNegInfInterval)); |
| |
| // Verify Examples. |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); |
| } |
| |
| // Test Interval's isBefore(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4))); |
| |
| assert(!interval.isBefore(Date(2009, 7, 3))); |
| assert(!interval.isBefore(Date(2010, 7, 3))); |
| assert(!interval.isBefore(Date(2010, 7, 4))); |
| assert(!interval.isBefore(Date(2010, 7, 5))); |
| assert(!interval.isBefore(Date(2011, 7, 1))); |
| assert(!interval.isBefore(Date(2012, 1, 6))); |
| assert(interval.isBefore(Date(2012, 1, 7))); |
| assert(interval.isBefore(Date(2012, 1, 8))); |
| assert(interval.isBefore(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!interval.isBefore(cdate)); |
| assert(!cInterval.isBefore(cdate)); |
| assert(!iInterval.isBefore(cdate)); |
| |
| // Verify Examples. |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); |
| } |
| |
| // Test Interval's isBefore(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore( |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!interval.isBefore(interval)); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval)); |
| assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval)); |
| assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval)); |
| |
| assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.isBefore(interval)); |
| assert(!interval.isBefore(cInterval)); |
| assert(!interval.isBefore(iInterval)); |
| assert(!interval.isBefore(posInfInterval)); |
| assert(!interval.isBefore(cPosInfInterval)); |
| assert(!interval.isBefore(iPosInfInterval)); |
| assert(!interval.isBefore(negInfInterval)); |
| assert(!interval.isBefore(cNegInfInterval)); |
| assert(!interval.isBefore(iNegInfInterval)); |
| assert(!cInterval.isBefore(interval)); |
| assert(!cInterval.isBefore(cInterval)); |
| assert(!cInterval.isBefore(iInterval)); |
| assert(!cInterval.isBefore(posInfInterval)); |
| assert(!cInterval.isBefore(cPosInfInterval)); |
| assert(!cInterval.isBefore(iPosInfInterval)); |
| assert(!cInterval.isBefore(negInfInterval)); |
| assert(!cInterval.isBefore(cNegInfInterval)); |
| assert(!cInterval.isBefore(iNegInfInterval)); |
| assert(!iInterval.isBefore(interval)); |
| assert(!iInterval.isBefore(cInterval)); |
| assert(!iInterval.isBefore(iInterval)); |
| assert(!iInterval.isBefore(posInfInterval)); |
| assert(!iInterval.isBefore(cPosInfInterval)); |
| assert(!iInterval.isBefore(iPosInfInterval)); |
| assert(!iInterval.isBefore(negInfInterval)); |
| assert(!iInterval.isBefore(cNegInfInterval)); |
| assert(!iInterval.isBefore(iNegInfInterval)); |
| |
| // Verify Examples. |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); |
| } |
| |
| // Test Interval's isAfter(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4))); |
| |
| assert(interval.isAfter(Date(2009, 7, 4))); |
| assert(interval.isAfter(Date(2010, 7, 3))); |
| assert(!interval.isAfter(Date(2010, 7, 4))); |
| assert(!interval.isAfter(Date(2010, 7, 5))); |
| assert(!interval.isAfter(Date(2011, 7, 1))); |
| assert(!interval.isAfter(Date(2012, 1, 6))); |
| assert(!interval.isAfter(Date(2012, 1, 7))); |
| assert(!interval.isAfter(Date(2012, 1, 8))); |
| assert(!interval.isAfter(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!interval.isAfter(cdate)); |
| assert(!cInterval.isAfter(cdate)); |
| assert(!iInterval.isAfter(cdate)); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); |
| } |
| |
| // Test Interval's isAfter(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter( |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!interval.isAfter(interval)); |
| assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval)); |
| assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval)); |
| assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval)); |
| |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.isAfter(interval)); |
| assert(!interval.isAfter(cInterval)); |
| assert(!interval.isAfter(iInterval)); |
| assert(!interval.isAfter(posInfInterval)); |
| assert(!interval.isAfter(cPosInfInterval)); |
| assert(!interval.isAfter(iPosInfInterval)); |
| assert(!interval.isAfter(negInfInterval)); |
| assert(!interval.isAfter(cNegInfInterval)); |
| assert(!interval.isAfter(iNegInfInterval)); |
| assert(!cInterval.isAfter(interval)); |
| assert(!cInterval.isAfter(cInterval)); |
| assert(!cInterval.isAfter(iInterval)); |
| assert(!cInterval.isAfter(posInfInterval)); |
| assert(!cInterval.isAfter(cPosInfInterval)); |
| assert(!cInterval.isAfter(iPosInfInterval)); |
| assert(!cInterval.isAfter(negInfInterval)); |
| assert(!cInterval.isAfter(cNegInfInterval)); |
| assert(!cInterval.isAfter(iNegInfInterval)); |
| assert(!iInterval.isAfter(interval)); |
| assert(!iInterval.isAfter(cInterval)); |
| assert(!iInterval.isAfter(iInterval)); |
| assert(!iInterval.isAfter(posInfInterval)); |
| assert(!iInterval.isAfter(cPosInfInterval)); |
| assert(!iInterval.isAfter(iPosInfInterval)); |
| assert(!iInterval.isAfter(negInfInterval)); |
| assert(!iInterval.isAfter(cNegInfInterval)); |
| assert(!iInterval.isAfter(iNegInfInterval)); |
| |
| // Verify Examples. |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); |
| } |
| |
| // Test Interval's intersects(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects( |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(interval.intersects(interval)); |
| assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval)); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval)); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval)); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval)); |
| assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval)); |
| assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval)); |
| |
| assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(interval.intersects(interval)); |
| assert(interval.intersects(cInterval)); |
| assert(interval.intersects(iInterval)); |
| assert(interval.intersects(posInfInterval)); |
| assert(interval.intersects(cPosInfInterval)); |
| assert(interval.intersects(iPosInfInterval)); |
| assert(interval.intersects(negInfInterval)); |
| assert(interval.intersects(cNegInfInterval)); |
| assert(interval.intersects(iNegInfInterval)); |
| assert(cInterval.intersects(interval)); |
| assert(cInterval.intersects(cInterval)); |
| assert(cInterval.intersects(iInterval)); |
| assert(cInterval.intersects(posInfInterval)); |
| assert(cInterval.intersects(cPosInfInterval)); |
| assert(cInterval.intersects(iPosInfInterval)); |
| assert(cInterval.intersects(negInfInterval)); |
| assert(cInterval.intersects(cNegInfInterval)); |
| assert(cInterval.intersects(iNegInfInterval)); |
| assert(iInterval.intersects(interval)); |
| assert(iInterval.intersects(cInterval)); |
| assert(iInterval.intersects(iInterval)); |
| assert(iInterval.intersects(posInfInterval)); |
| assert(iInterval.intersects(cPosInfInterval)); |
| assert(iInterval.intersects(iPosInfInterval)); |
| assert(iInterval.intersects(negInfInterval)); |
| assert(iInterval.intersects(cNegInfInterval)); |
| assert(iInterval.intersects(iNegInfInterval)); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2)))); |
| } |
| |
| // Test Interval's intersection(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection( |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval)); |
| assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval)); |
| |
| assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4)))); |
| |
| assert(interval.intersection(interval) == interval); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); |
| assert(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); |
| assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| assert(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| |
| assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| |
| assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); |
| assert(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| |
| assert(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); |
| assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); |
| assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.intersection(interval).empty); |
| assert(!interval.intersection(cInterval).empty); |
| assert(!interval.intersection(iInterval).empty); |
| assert(!interval.intersection(posInfInterval).empty); |
| assert(!interval.intersection(cPosInfInterval).empty); |
| assert(!interval.intersection(iPosInfInterval).empty); |
| assert(!interval.intersection(negInfInterval).empty); |
| assert(!interval.intersection(cNegInfInterval).empty); |
| assert(!interval.intersection(iNegInfInterval).empty); |
| assert(!cInterval.intersection(interval).empty); |
| assert(!cInterval.intersection(cInterval).empty); |
| assert(!cInterval.intersection(iInterval).empty); |
| assert(!cInterval.intersection(posInfInterval).empty); |
| assert(!cInterval.intersection(cPosInfInterval).empty); |
| assert(!cInterval.intersection(iPosInfInterval).empty); |
| assert(!cInterval.intersection(negInfInterval).empty); |
| assert(!cInterval.intersection(cNegInfInterval).empty); |
| assert(!cInterval.intersection(iNegInfInterval).empty); |
| assert(!iInterval.intersection(interval).empty); |
| assert(!iInterval.intersection(cInterval).empty); |
| assert(!iInterval.intersection(iInterval).empty); |
| assert(!iInterval.intersection(posInfInterval).empty); |
| assert(!iInterval.intersection(cPosInfInterval).empty); |
| assert(!iInterval.intersection(iPosInfInterval).empty); |
| assert(!iInterval.intersection(negInfInterval).empty); |
| assert(!iInterval.intersection(cNegInfInterval).empty); |
| assert(!iInterval.intersection(iNegInfInterval).empty); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1999, 1, 12),Date(2011, 9, 17))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1))); |
| } |
| |
| // Test Interval's isAdjacent(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2) |
| { |
| interval1.isAdjacent(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!interval.isAdjacent(interval)); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval)); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval)); |
| assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval)); |
| assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval)); |
| |
| assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.isAdjacent(interval)); |
| assert(!interval.isAdjacent(cInterval)); |
| assert(!interval.isAdjacent(iInterval)); |
| assert(!interval.isAdjacent(posInfInterval)); |
| assert(!interval.isAdjacent(cPosInfInterval)); |
| assert(!interval.isAdjacent(iPosInfInterval)); |
| assert(!interval.isAdjacent(negInfInterval)); |
| assert(!interval.isAdjacent(cNegInfInterval)); |
| assert(!interval.isAdjacent(iNegInfInterval)); |
| assert(!cInterval.isAdjacent(interval)); |
| assert(!cInterval.isAdjacent(cInterval)); |
| assert(!cInterval.isAdjacent(iInterval)); |
| assert(!cInterval.isAdjacent(posInfInterval)); |
| assert(!cInterval.isAdjacent(cPosInfInterval)); |
| assert(!cInterval.isAdjacent(iPosInfInterval)); |
| assert(!cInterval.isAdjacent(negInfInterval)); |
| assert(!cInterval.isAdjacent(cNegInfInterval)); |
| assert(!cInterval.isAdjacent(iNegInfInterval)); |
| assert(!iInterval.isAdjacent(interval)); |
| assert(!iInterval.isAdjacent(cInterval)); |
| assert(!iInterval.isAdjacent(iInterval)); |
| assert(!iInterval.isAdjacent(posInfInterval)); |
| assert(!iInterval.isAdjacent(cPosInfInterval)); |
| assert(!iInterval.isAdjacent(iPosInfInterval)); |
| assert(!iInterval.isAdjacent(negInfInterval)); |
| assert(!iInterval.isAdjacent(cNegInfInterval)); |
| assert(!iInterval.isAdjacent(iNegInfInterval)); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1)))); |
| |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); |
| assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)) .isAdjacent(NegInfInterval!Date(Date(2000, 1, 2)))); |
| } |
| |
| // Test Interval's merge(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| static void testInterval(I)(scope const Interval!Date interval1, scope const I interval2) |
| { |
| interval1.merge(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval)); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval)); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval)); |
| |
| assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3)))); |
| |
| assert(interval.merge(interval) == interval); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| |
| assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval) == |
| Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| |
| assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.merge(interval).empty); |
| assert(!interval.merge(cInterval).empty); |
| assert(!interval.merge(iInterval).empty); |
| assert(!interval.merge(posInfInterval).empty); |
| assert(!interval.merge(cPosInfInterval).empty); |
| assert(!interval.merge(iPosInfInterval).empty); |
| assert(!interval.merge(negInfInterval).empty); |
| assert(!interval.merge(cNegInfInterval).empty); |
| assert(!interval.merge(iNegInfInterval).empty); |
| assert(!cInterval.merge(interval).empty); |
| assert(!cInterval.merge(cInterval).empty); |
| assert(!cInterval.merge(iInterval).empty); |
| assert(!cInterval.merge(posInfInterval).empty); |
| assert(!cInterval.merge(cPosInfInterval).empty); |
| assert(!cInterval.merge(iPosInfInterval).empty); |
| assert(!cInterval.merge(negInfInterval).empty); |
| assert(!cInterval.merge(cNegInfInterval).empty); |
| assert(!cInterval.merge(iNegInfInterval).empty); |
| assert(!iInterval.merge(interval).empty); |
| assert(!iInterval.merge(cInterval).empty); |
| assert(!iInterval.merge(iInterval).empty); |
| assert(!iInterval.merge(posInfInterval).empty); |
| assert(!iInterval.merge(cPosInfInterval).empty); |
| assert(!iInterval.merge(iPosInfInterval).empty); |
| assert(!iInterval.merge(negInfInterval).empty); |
| assert(!iInterval.merge(cNegInfInterval).empty); |
| assert(!iInterval.merge(iNegInfInterval).empty); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| } |
| |
| // Test Interval's span(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| static void testInterval(scope const Interval!Date interval1, scope const Interval!Date interval2) |
| { |
| interval1.span(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)),interval)); |
| assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), |
| Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(interval.span(interval) == interval); |
| assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == |
| Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); |
| |
| assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval) == |
| Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval) == |
| Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9))); |
| |
| assert(interval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(interval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(interval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(interval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(interval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!interval.span(interval).empty); |
| assert(!interval.span(cInterval).empty); |
| assert(!interval.span(iInterval).empty); |
| assert(!interval.span(posInfInterval).empty); |
| assert(!interval.span(cPosInfInterval).empty); |
| assert(!interval.span(iPosInfInterval).empty); |
| assert(!interval.span(negInfInterval).empty); |
| assert(!interval.span(cNegInfInterval).empty); |
| assert(!interval.span(iNegInfInterval).empty); |
| assert(!cInterval.span(interval).empty); |
| assert(!cInterval.span(cInterval).empty); |
| assert(!cInterval.span(iInterval).empty); |
| assert(!cInterval.span(posInfInterval).empty); |
| assert(!cInterval.span(cPosInfInterval).empty); |
| assert(!cInterval.span(iPosInfInterval).empty); |
| assert(!cInterval.span(negInfInterval).empty); |
| assert(!cInterval.span(cNegInfInterval).empty); |
| assert(!cInterval.span(iNegInfInterval).empty); |
| assert(!iInterval.span(interval).empty); |
| assert(!iInterval.span(cInterval).empty); |
| assert(!iInterval.span(iInterval).empty); |
| assert(!iInterval.span(posInfInterval).empty); |
| assert(!iInterval.span(cPosInfInterval).empty); |
| assert(!iInterval.span(iPosInfInterval).empty); |
| assert(!iInterval.span(negInfInterval).empty); |
| assert(!iInterval.span(cNegInfInterval).empty); |
| assert(!iInterval.span(iNegInfInterval).empty); |
| |
| // Verify Examples. |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| } |
| |
| // Test Interval's shift(duration). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| static void testIntervalFail(Interval!Date interval, scope const Duration duration) |
| { |
| interval.shift(duration); |
| } |
| |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); |
| |
| static void testInterval(I)(I interval, scope const Duration duration, |
| scope const I expected, size_t line = __LINE__) |
| { |
| interval.shift(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29))); |
| testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); |
| |
| // Verify Examples. |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15))); |
| } |
| |
| // Test Interval's shift(int, int, AllowDayOverflow). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| |
| static void testIntervalFail(Interval!Date interval, int years, int months) |
| { |
| interval.shift(years, months); |
| } |
| |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.shift(years, months, allow); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); |
| |
| auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30))); |
| } |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.shift(5))); |
| static assert(!__traits(compiles, iInterval.shift(5))); |
| |
| // Verify Examples. |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.shift(2); |
| assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1))); |
| |
| interval2.shift(-2); |
| assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1))); |
| } |
| |
| // Test Interval's expand(Duration). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); |
| |
| static void testIntervalFail(I)(I interval, scope const Duration duration) |
| { |
| interval.expand(duration); |
| } |
| |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1))); |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5))); |
| |
| static void testInterval(I)(I interval, scope const Duration duration, |
| scope const I expected, size_t line = __LINE__) |
| { |
| interval.expand(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29))); |
| testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16))); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); |
| |
| // Verify Examples. |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28))); |
| } |
| |
| // Test Interval's expand(int, int, AllowDayOverflow, Direction) |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7)); |
| |
| static void testIntervalFail(Interval!Date interval, int years, int months) |
| { |
| interval.expand(years, months); |
| } |
| |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0)); |
| assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0)); |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.expand(years, months, allow, dir); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7))); |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7))); |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7))); |
| |
| auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both, |
| Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both, |
| Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both, |
| Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both, |
| Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both, |
| Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd, |
| Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd, |
| Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd, |
| Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd, |
| Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd, |
| Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd, |
| Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31))); |
| } |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.expand(5))); |
| static assert(!__traits(compiles, iInterval.expand(5))); |
| |
| // Verify Examples. |
| auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)); |
| |
| interval1.expand(2); |
| assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1))); |
| |
| interval2.expand(-2); |
| assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1))); |
| } |
| |
| // Test Interval's fwdRange. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); |
| |
| static void testInterval1(Interval!Date interval) |
| { |
| interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| } |
| |
| assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| static void testInterval2(Interval!Date interval) |
| { |
| interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); |
| } |
| |
| assertThrown!DateTimeException(testInterval2(interval)); |
| |
| assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty); |
| |
| assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == |
| Date(2010, 9, 12)); |
| |
| assert(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange( |
| everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 17)); |
| } |
| |
| // Verify Examples. |
| { |
| auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) |
| { |
| if ((date.day & 1) == 0) |
| return date + dur!"days"(2); |
| return date + dur!"days"(1); |
| }; |
| auto range = interval.fwdRange(func); |
| |
| // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). |
| assert(range.front == Date(2010, 9, 1)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| assert(!iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| } |
| |
| // Test Interval's bwdRange. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)); |
| |
| static void testInterval1(Interval!Date interval) |
| { |
| interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| } |
| |
| assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| static void testInterval2(Interval!Date interval) |
| { |
| interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); |
| } |
| |
| assertThrown!DateTimeException(testInterval2(interval)); |
| |
| assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); |
| assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty); |
| |
| assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == Date(2010, 10, 1)); |
| |
| assert(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); |
| } |
| |
| // Verify Examples. |
| { |
| auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) |
| { |
| if ((date.day & 1) == 0) |
| return date - dur!"days"(2); |
| return date - dur!"days"(1); |
| }; |
| auto range = interval.bwdRange(func); |
| |
| // An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). |
| assert(range.front == Date(2010, 9, 9)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| assert(!iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| } |
| |
| // Test Interval's toString(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString() == "[2010-Jul-04 - 2012-Jan-07)"); |
| |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(cInterval.toString()); |
| assert(iInterval.toString()); |
| } |
| |
| |
| /++ |
| Represents an interval of time which has positive infinity as its end point. |
| |
| Any ranges which iterate over a `PosInfInterval` are infinite. So, the |
| main purpose of using `PosInfInterval` is to create an infinite range |
| which starts at a fixed point in time and goes to positive infinity. |
| +/ |
| struct PosInfInterval(TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| begin = The time point which begins the interval. |
| |
| Example: |
| -------------------- |
| auto interval = PosInfInterval!Date(Date(1996, 1, 2)); |
| -------------------- |
| +/ |
| this(scope const TP begin) pure nothrow |
| { |
| _begin = cast(TP) begin; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The `PosInfInterval` to assign to this one. |
| +/ |
| ref PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| return this; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The `PosInfInterval` to assign to this one. |
| +/ |
| ref PosInfInterval opAssign(PosInfInterval rhs) pure nothrow |
| { |
| _begin = cast(TP) rhs._begin; |
| return this; |
| } |
| |
| |
| /++ |
| The starting point of the interval. It is included in the interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); |
| -------------------- |
| +/ |
| @property TP begin() const pure nothrow |
| { |
| return cast(TP)_begin; |
| } |
| |
| |
| /++ |
| The starting point of the interval. It is included in the interval. |
| |
| Params: |
| timePoint = The time point to set `begin` to. |
| +/ |
| @property void begin(TP timePoint) pure nothrow |
| { |
| _begin = timePoint; |
| } |
| |
| |
| /++ |
| Whether the interval's length is 0. Always returns false. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); |
| -------------------- |
| +/ |
| enum bool empty = false; |
| |
| |
| /++ |
| Whether the given time point is within this interval. |
| |
| Params: |
| timePoint = The time point to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool contains(TP timePoint) const pure nothrow |
| { |
| return timePoint >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| -------------------- |
| +/ |
| bool contains(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._begin >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| PosInfInterval!Date(Date(1995, 7, 2)))); |
| -------------------- |
| +/ |
| bool contains(scope const PosInfInterval interval) const pure nothrow |
| { |
| return interval._begin >= _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Always returns false because an interval going to positive infinity |
| can never contain an interval beginning at negative infinity. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool contains(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given time point. |
| |
| Always returns false because an interval going to positive infinity |
| can never be before any time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is before |
| it. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool isBefore(scope const TP timePoint) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false (unless the given interval is empty) because an |
| interval going to positive infinity can never be before any other |
| interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be before any other interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| PosInfInterval!Date(Date(1992, 5, 4)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| PosInfInterval!Date(Date(2013, 3, 7)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be before any other interval. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is after |
| it. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); |
| -------------------- |
| +/ |
| bool isAfter(scope const TP timePoint) const pure nothrow |
| { |
| return timePoint < _begin; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Always returns false because an interval going to positive infinity can |
| never be after another interval going to positive infinity. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin >= interval._end; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool intersects(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._end > _begin; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Always returns true because two intervals going to positive infinity |
| always overlap. |
| |
| Params: |
| interval = The interval to check for intersection with this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool intersects(scope const PosInfInterval interval) const pure nothrow |
| { |
| return true; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool intersects(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin < interval._end; |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if the given interval is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17))); |
| -------------------- |
| +/ |
| Interval!TP intersection(scope const Interval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| auto begin = _begin > interval._begin ? _begin : interval._begin; |
| |
| return Interval!TP(begin, interval._end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1999, 1 , 12))); |
| -------------------- |
| +/ |
| PosInfInterval intersection(scope const PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_begin < interval._begin ? interval._begin : _begin); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12))); |
| -------------------- |
| +/ |
| Interval!TP intersection(scope const NegInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| return Interval!TP(_begin, interval._end); |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return _begin == interval._end; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Always returns false because two intervals going to positive infinity |
| can never be adjacent to one another. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| PosInfInterval!Date(Date(1990, 1, 7)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| PosInfInterval!Date(Date(1996, 1, 2)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const PosInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| NegInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent( |
| NegInfInterval!Date(Date(2000, 7, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return _begin == interval._end; |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if the given interval is |
| empty. |
| |
| Note: |
| There is no overload for `merge` which takes a |
| `NegInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval merge(scope const Interval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.isAdjacent(interval) || this.intersects(interval), |
| new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); |
| |
| return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Note: |
| There is no overload for `merge` which takes a |
| `NegInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval merge(scope const PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Note: |
| There is no overload for `span` which takes a |
| `NegInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == |
| PosInfInterval!Date(Date(500, 8, 9))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval span(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this |
| interval. |
| |
| Note: |
| There is no overload for `span` which takes a |
| `NegInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7 , 6))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1 , 2))); |
| -------------------- |
| +/ |
| PosInfInterval span(scope const PosInfInterval interval) const pure nothrow |
| { |
| return PosInfInterval(_begin < interval._begin ? _begin : interval._begin); |
| } |
| |
| |
| /++ |
| Shifts the `begin` of this interval forward or backwards in time by |
| the given duration (a positive duration shifts the interval forward; a |
| negative duration shifts it backward). Effectively, it does |
| $(D begin += duration). |
| |
| Params: |
| duration = The duration to shift the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); |
| -------------------- |
| +/ |
| void shift(D)(D duration) pure nothrow |
| if (__traits(compiles, begin + duration)) |
| { |
| _begin += duration; |
| } |
| |
| |
| static if (__traits(compiles, begin.add!"months"(1)) && |
| __traits(compiles, begin.add!"years"(1))) |
| { |
| /++ |
| Shifts the `begin` of this interval forward or backwards in time |
| by the given number of years and/or months (a positive number of |
| years and months shifts the interval forward; a negative number |
| shifts it backward). It adds the years the given years and months to |
| `begin`. It effectively calls `add!"years"()` and then |
| `add!"months"()` on `begin` with the given number of years and |
| months. |
| |
| Params: |
| years = The number of years to shift the interval by. |
| months = The number of months to shift the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `begin`, causing its month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); |
| -------------------- |
| +/ |
| void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto begin = _begin; |
| |
| begin.add!"years"(years, allowOverflow); |
| begin.add!"months"(months, allowOverflow); |
| |
| _begin = begin; |
| } |
| } |
| |
| |
| /++ |
| Expands the interval backwards in time. Effectively, it does |
| $(D begin -= duration). |
| |
| Params: |
| duration = The duration to expand the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); |
| -------------------- |
| +/ |
| void expand(D)(D duration) pure nothrow |
| if (__traits(compiles, begin + duration)) |
| { |
| _begin -= duration; |
| } |
| |
| |
| static if (__traits(compiles, begin.add!"months"(1)) && |
| __traits(compiles, begin.add!"years"(1))) |
| { |
| /++ |
| Expands the interval forwards and/or backwards in time. Effectively, |
| it subtracts the given number of months/years from `begin`. |
| |
| Params: |
| years = The number of years to expand the interval by. |
| months = The number of months to expand the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `begin`, causing its month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty or if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(2); |
| assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); |
| |
| interval2.expand(-2); |
| assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); |
| -------------------- |
| +/ |
| void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto begin = _begin; |
| |
| begin.add!"years"(-years, allowOverflow); |
| begin.add!"months"(-months, allowOverflow); |
| |
| _begin = begin; |
| } |
| } |
| |
| |
| /++ |
| Returns a range which iterates forward over the interval, starting |
| at `begin`, using $(D_PARAM func) to generate each successive time |
| point. |
| |
| The range's `front` is the interval's `begin`. $(D_PARAM func) is |
| used to generate the next `front` when `popFront` is called. If |
| $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called |
| before the range is returned (so that `front` is a time point which |
| $(D_PARAM func) would generate). |
| |
| If $(D_PARAM func) ever generates a time point less than or equal to the |
| current `front` of the range, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. |
| |
| There are helper functions in this module which generate common |
| delegates to pass to `fwdRange`. Their documentation starts with |
| "Range-generating function," to make them easily searchable. |
| |
| Params: |
| func = The function used to generate the time points of the |
| range over the interval. |
| popFirst = Whether `popFront` should be called on the range |
| before returning it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Warning: |
| $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) |
| would be a function pointer to a pure function, but forcing |
| $(D_PARAM func) to be pure is far too restrictive to be useful, and |
| in order to have the ease of use of having functions which generate |
| functions to pass to `fwdRange`, $(D_PARAM func) must be a |
| delegate. |
| |
| If $(D_PARAM func) retains state which changes as it is called, then |
| some algorithms will not work correctly, because the range's |
| `save` will have failed to have really saved the range's state. |
| To avoid such bugs, don't pass a delegate which is |
| not logically pure to `fwdRange`. If $(D_PARAM func) is given the |
| same time point with two different calls, it must return the same |
| result both times. |
| |
| Of course, none of the functions in this module have this problem, |
| so it's only relevant for custom delegates. |
| |
| Example: |
| -------------------- |
| auto interval = PosInfInterval!Date(Date(2010, 9, 1)); |
| auto func = delegate (scope const Date date) //For iterating over even-numbered days. |
| { |
| if ((date.day & 1) == 0) |
| return date + dur!"days"(2); |
| |
| return date + dur!"days"(1); |
| }; |
| auto range = interval.fwdRange(func); |
| |
| //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). |
| assert(range.front == Date(2010, 9, 1)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(!range.empty); |
| -------------------- |
| +/ |
| PosInfIntervalRange!(TP) fwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const |
| { |
| auto range = PosInfIntervalRange!(TP)(this, func); |
| |
| if (popFirst == PopFirst.yes) |
| range.popFront(); |
| |
| return range; |
| } |
| |
| |
| /+ |
| Converts this interval to a string. |
| +/ |
| // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't |
| // have versions of toString() with extra modifiers, |
| // so we define one version with modifiers and one without. |
| string toString() |
| { |
| return _toStringImpl(); |
| } |
| |
| |
| /++ |
| Converts this interval to a string. |
| +/ |
| // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't |
| // have versions of toString() with extra modifiers, |
| // so we define one version with modifiers and one without. |
| string toString() const nothrow |
| { |
| return _toStringImpl(); |
| } |
| |
| private: |
| |
| /+ |
| Since we have two versions of toString(), we have _toStringImpl() |
| so that they can share implementations. |
| +/ |
| string _toStringImpl() const nothrow |
| { |
| import std.format : format; |
| try |
| return format("[%s - ∞)", _begin); |
| catch (Exception e) |
| assert(0, "format() threw."); |
| } |
| |
| |
| TP _begin; |
| } |
| |
| //Test PosInfInterval's constructor. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| PosInfInterval!Date(Date.init); |
| PosInfInterval!TimeOfDay(TimeOfDay.init); |
| PosInfInterval!DateTime(DateTime.init); |
| PosInfInterval!SysTime(SysTime(0)); |
| |
| //Verify Examples. |
| auto interval = PosInfInterval!Date(Date(1996, 1, 2)); |
| } |
| |
| //Test PosInfInterval's begin. |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(PosInfInterval!Date(Date(1, 1, 1)).begin == Date(1, 1, 1)); |
| assert(PosInfInterval!Date(Date(2010, 1, 1)).begin == Date(2010, 1, 1)); |
| assert(PosInfInterval!Date(Date(1997, 12, 31)).begin == Date(1997, 12, 31)); |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(cPosInfInterval.begin != Date.init); |
| assert(iPosInfInterval.begin != Date.init); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2)); |
| } |
| |
| //Test PosInfInterval's empty. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty); |
| assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); |
| assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); |
| assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); |
| |
| const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| assert(!cPosInfInterval.empty); |
| assert(!iPosInfInterval.empty); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty); |
| } |
| |
| //Test PosInfInterval's contains(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| assert(!posInfInterval.contains(Date(2009, 7, 4))); |
| assert(!posInfInterval.contains(Date(2010, 7, 3))); |
| assert(posInfInterval.contains(Date(2010, 7, 4))); |
| assert(posInfInterval.contains(Date(2010, 7, 5))); |
| assert(posInfInterval.contains(Date(2011, 7, 1))); |
| assert(posInfInterval.contains(Date(2012, 1, 6))); |
| assert(posInfInterval.contains(Date(2012, 1, 7))); |
| assert(posInfInterval.contains(Date(2012, 1, 8))); |
| assert(posInfInterval.contains(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(posInfInterval.contains(cdate)); |
| assert(cPosInfInterval.contains(cdate)); |
| assert(iPosInfInterval.contains(cdate)); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5))); |
| } |
| |
| //Test PosInfInterval's contains(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.contains(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(posInfInterval.contains(posInfInterval)); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval)); |
| |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(posInfInterval.contains(interval)); |
| assert(posInfInterval.contains(cInterval)); |
| assert(posInfInterval.contains(iInterval)); |
| assert(posInfInterval.contains(posInfInterval)); |
| assert(posInfInterval.contains(cPosInfInterval)); |
| assert(posInfInterval.contains(iPosInfInterval)); |
| assert(!posInfInterval.contains(negInfInterval)); |
| assert(!posInfInterval.contains(cNegInfInterval)); |
| assert(!posInfInterval.contains(iNegInfInterval)); |
| assert(cPosInfInterval.contains(interval)); |
| assert(cPosInfInterval.contains(cInterval)); |
| assert(cPosInfInterval.contains(iInterval)); |
| assert(cPosInfInterval.contains(posInfInterval)); |
| assert(cPosInfInterval.contains(cPosInfInterval)); |
| assert(cPosInfInterval.contains(iPosInfInterval)); |
| assert(!cPosInfInterval.contains(negInfInterval)); |
| assert(!cPosInfInterval.contains(cNegInfInterval)); |
| assert(!cPosInfInterval.contains(iNegInfInterval)); |
| assert(iPosInfInterval.contains(interval)); |
| assert(iPosInfInterval.contains(cInterval)); |
| assert(iPosInfInterval.contains(iInterval)); |
| assert(iPosInfInterval.contains(posInfInterval)); |
| assert(iPosInfInterval.contains(cPosInfInterval)); |
| assert(iPosInfInterval.contains(iPosInfInterval)); |
| assert(!iPosInfInterval.contains(negInfInterval)); |
| assert(!iPosInfInterval.contains(cNegInfInterval)); |
| assert(!iPosInfInterval.contains(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); |
| } |
| |
| //Test PosInfInterval's isBefore(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| assert(!posInfInterval.isBefore(Date(2009, 7, 3))); |
| assert(!posInfInterval.isBefore(Date(2010, 7, 3))); |
| assert(!posInfInterval.isBefore(Date(2010, 7, 4))); |
| assert(!posInfInterval.isBefore(Date(2010, 7, 5))); |
| assert(!posInfInterval.isBefore(Date(2011, 7, 1))); |
| assert(!posInfInterval.isBefore(Date(2012, 1, 6))); |
| assert(!posInfInterval.isBefore(Date(2012, 1, 7))); |
| assert(!posInfInterval.isBefore(Date(2012, 1, 8))); |
| assert(!posInfInterval.isBefore(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(!posInfInterval.isBefore(cdate)); |
| assert(!cPosInfInterval.isBefore(cdate)); |
| assert(!iPosInfInterval.isBefore(cdate)); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5))); |
| } |
| |
| //Test PosInfInterval's isBefore(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.isBefore(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!posInfInterval.isBefore(posInfInterval)); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval)); |
| |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.isBefore(interval)); |
| assert(!posInfInterval.isBefore(cInterval)); |
| assert(!posInfInterval.isBefore(iInterval)); |
| assert(!posInfInterval.isBefore(posInfInterval)); |
| assert(!posInfInterval.isBefore(cPosInfInterval)); |
| assert(!posInfInterval.isBefore(iPosInfInterval)); |
| assert(!posInfInterval.isBefore(negInfInterval)); |
| assert(!posInfInterval.isBefore(cNegInfInterval)); |
| assert(!posInfInterval.isBefore(iNegInfInterval)); |
| assert(!cPosInfInterval.isBefore(interval)); |
| assert(!cPosInfInterval.isBefore(cInterval)); |
| assert(!cPosInfInterval.isBefore(iInterval)); |
| assert(!cPosInfInterval.isBefore(posInfInterval)); |
| assert(!cPosInfInterval.isBefore(cPosInfInterval)); |
| assert(!cPosInfInterval.isBefore(iPosInfInterval)); |
| assert(!cPosInfInterval.isBefore(negInfInterval)); |
| assert(!cPosInfInterval.isBefore(cNegInfInterval)); |
| assert(!cPosInfInterval.isBefore(iNegInfInterval)); |
| assert(!iPosInfInterval.isBefore(interval)); |
| assert(!iPosInfInterval.isBefore(cInterval)); |
| assert(!iPosInfInterval.isBefore(iInterval)); |
| assert(!iPosInfInterval.isBefore(posInfInterval)); |
| assert(!iPosInfInterval.isBefore(cPosInfInterval)); |
| assert(!iPosInfInterval.isBefore(iPosInfInterval)); |
| assert(!iPosInfInterval.isBefore(negInfInterval)); |
| assert(!iPosInfInterval.isBefore(cNegInfInterval)); |
| assert(!iPosInfInterval.isBefore(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); |
| } |
| |
| //Test PosInfInterval's isAfter(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| assert(posInfInterval.isAfter(Date(2009, 7, 3))); |
| assert(posInfInterval.isAfter(Date(2010, 7, 3))); |
| assert(!posInfInterval.isAfter(Date(2010, 7, 4))); |
| assert(!posInfInterval.isAfter(Date(2010, 7, 5))); |
| assert(!posInfInterval.isAfter(Date(2011, 7, 1))); |
| assert(!posInfInterval.isAfter(Date(2012, 1, 6))); |
| assert(!posInfInterval.isAfter(Date(2012, 1, 7))); |
| assert(!posInfInterval.isAfter(Date(2012, 1, 8))); |
| assert(!posInfInterval.isAfter(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(!posInfInterval.isAfter(cdate)); |
| assert(!cPosInfInterval.isAfter(cdate)); |
| assert(!iPosInfInterval.isAfter(cdate)); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5))); |
| } |
| |
| //Test PosInfInterval's isAfter(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.isAfter(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!posInfInterval.isAfter(posInfInterval)); |
| assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval)); |
| |
| assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.isAfter(interval)); |
| assert(!posInfInterval.isAfter(cInterval)); |
| assert(!posInfInterval.isAfter(iInterval)); |
| assert(!posInfInterval.isAfter(posInfInterval)); |
| assert(!posInfInterval.isAfter(cPosInfInterval)); |
| assert(!posInfInterval.isAfter(iPosInfInterval)); |
| assert(!posInfInterval.isAfter(negInfInterval)); |
| assert(!posInfInterval.isAfter(cNegInfInterval)); |
| assert(!posInfInterval.isAfter(iNegInfInterval)); |
| assert(!cPosInfInterval.isAfter(interval)); |
| assert(!cPosInfInterval.isAfter(cInterval)); |
| assert(!cPosInfInterval.isAfter(iInterval)); |
| assert(!cPosInfInterval.isAfter(posInfInterval)); |
| assert(!cPosInfInterval.isAfter(cPosInfInterval)); |
| assert(!cPosInfInterval.isAfter(iPosInfInterval)); |
| assert(!cPosInfInterval.isAfter(negInfInterval)); |
| assert(!cPosInfInterval.isAfter(cNegInfInterval)); |
| assert(!cPosInfInterval.isAfter(iNegInfInterval)); |
| assert(!iPosInfInterval.isAfter(interval)); |
| assert(!iPosInfInterval.isAfter(cInterval)); |
| assert(!iPosInfInterval.isAfter(iInterval)); |
| assert(!iPosInfInterval.isAfter(posInfInterval)); |
| assert(!iPosInfInterval.isAfter(cPosInfInterval)); |
| assert(!iPosInfInterval.isAfter(iPosInfInterval)); |
| assert(!iPosInfInterval.isAfter(negInfInterval)); |
| assert(!iPosInfInterval.isAfter(cNegInfInterval)); |
| assert(!iPosInfInterval.isAfter(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1)))); |
| } |
| |
| //Test PosInfInterval's intersects(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.intersects(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(posInfInterval.intersects(posInfInterval)); |
| assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval)); |
| assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval)); |
| |
| assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(posInfInterval.intersects(interval)); |
| assert(posInfInterval.intersects(cInterval)); |
| assert(posInfInterval.intersects(iInterval)); |
| assert(posInfInterval.intersects(posInfInterval)); |
| assert(posInfInterval.intersects(cPosInfInterval)); |
| assert(posInfInterval.intersects(iPosInfInterval)); |
| assert(posInfInterval.intersects(negInfInterval)); |
| assert(posInfInterval.intersects(cNegInfInterval)); |
| assert(posInfInterval.intersects(iNegInfInterval)); |
| assert(cPosInfInterval.intersects(interval)); |
| assert(cPosInfInterval.intersects(cInterval)); |
| assert(cPosInfInterval.intersects(iInterval)); |
| assert(cPosInfInterval.intersects(posInfInterval)); |
| assert(cPosInfInterval.intersects(cPosInfInterval)); |
| assert(cPosInfInterval.intersects(iPosInfInterval)); |
| assert(cPosInfInterval.intersects(negInfInterval)); |
| assert(cPosInfInterval.intersects(cNegInfInterval)); |
| assert(cPosInfInterval.intersects(iNegInfInterval)); |
| assert(iPosInfInterval.intersects(interval)); |
| assert(iPosInfInterval.intersects(cInterval)); |
| assert(iPosInfInterval.intersects(iInterval)); |
| assert(iPosInfInterval.intersects(posInfInterval)); |
| assert(iPosInfInterval.intersects(cPosInfInterval)); |
| assert(iPosInfInterval.intersects(iPosInfInterval)); |
| assert(iPosInfInterval.intersects(negInfInterval)); |
| assert(iPosInfInterval.intersects(cNegInfInterval)); |
| assert(iPosInfInterval.intersects(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2)))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1)))); |
| } |
| |
| //Test PosInfInterval's intersection(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(I, J)(scope const I interval1, scope const J interval2) |
| { |
| interval1.intersection(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3)))); |
| assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4)))); |
| |
| assert(posInfInterval.intersection(posInfInterval) == posInfInterval); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))); |
| assert(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == |
| Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))); |
| |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 5))); |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2012, 1, 6))); |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2012, 1, 7))); |
| assert(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2012, 1, 8))); |
| |
| assert(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 5))); |
| assert(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 6))); |
| assert(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 7))); |
| assert(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval) == PosInfInterval!Date(Date(2012, 1, 8))); |
| |
| assert(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5))); |
| assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6))); |
| assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7))); |
| assert(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.intersection(interval).empty); |
| assert(!posInfInterval.intersection(cInterval).empty); |
| assert(!posInfInterval.intersection(iInterval).empty); |
| assert(!posInfInterval.intersection(posInfInterval).empty); |
| assert(!posInfInterval.intersection(cPosInfInterval).empty); |
| assert(!posInfInterval.intersection(iPosInfInterval).empty); |
| assert(!posInfInterval.intersection(negInfInterval).empty); |
| assert(!posInfInterval.intersection(cNegInfInterval).empty); |
| assert(!posInfInterval.intersection(iNegInfInterval).empty); |
| assert(!cPosInfInterval.intersection(interval).empty); |
| assert(!cPosInfInterval.intersection(cInterval).empty); |
| assert(!cPosInfInterval.intersection(iInterval).empty); |
| assert(!cPosInfInterval.intersection(posInfInterval).empty); |
| assert(!cPosInfInterval.intersection(cPosInfInterval).empty); |
| assert(!cPosInfInterval.intersection(iPosInfInterval).empty); |
| assert(!cPosInfInterval.intersection(negInfInterval).empty); |
| assert(!cPosInfInterval.intersection(cNegInfInterval).empty); |
| assert(!cPosInfInterval.intersection(iNegInfInterval).empty); |
| assert(!iPosInfInterval.intersection(interval).empty); |
| assert(!iPosInfInterval.intersection(cInterval).empty); |
| assert(!iPosInfInterval.intersection(iInterval).empty); |
| assert(!iPosInfInterval.intersection(posInfInterval).empty); |
| assert(!iPosInfInterval.intersection(cPosInfInterval).empty); |
| assert(!iPosInfInterval.intersection(iPosInfInterval).empty); |
| assert(!iPosInfInterval.intersection(negInfInterval).empty); |
| assert(!iPosInfInterval.intersection(cNegInfInterval).empty); |
| assert(!iPosInfInterval.intersection(iNegInfInterval).empty); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1996, 1, 2), Date(2000, 8, 2))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1996, 1, 2))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1999, 1, 12))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == |
| Interval!Date(Date(1996, 1, 2), Date(1999, 7, 6))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == |
| Interval!Date(Date(1996, 1, 2), Date(2013, 1, 12))); |
| } |
| |
| //Test PosInfInterval's isAdjacent(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.isAdjacent(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!posInfInterval.isAdjacent(posInfInterval)); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval)); |
| assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval)); |
| |
| assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.isAdjacent(interval)); |
| assert(!posInfInterval.isAdjacent(cInterval)); |
| assert(!posInfInterval.isAdjacent(iInterval)); |
| assert(!posInfInterval.isAdjacent(posInfInterval)); |
| assert(!posInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!posInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!posInfInterval.isAdjacent(negInfInterval)); |
| assert(!posInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!posInfInterval.isAdjacent(iNegInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(interval)); |
| assert(!cPosInfInterval.isAdjacent(cInterval)); |
| assert(!cPosInfInterval.isAdjacent(iInterval)); |
| assert(!cPosInfInterval.isAdjacent(posInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(negInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!cPosInfInterval.isAdjacent(iNegInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(interval)); |
| assert(!iPosInfInterval.isAdjacent(cInterval)); |
| assert(!iPosInfInterval.isAdjacent(iInterval)); |
| assert(!iPosInfInterval.isAdjacent(posInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(negInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!iPosInfInterval.isAdjacent(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2)))); |
| assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2)))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2)))); |
| assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1)))); |
| } |
| |
| //Test PosInfInterval's merge(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.merge(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| |
| assert(posInfInterval.merge(posInfInterval) == posInfInterval); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| PosInfInterval!Date(Date(2010, 7, 1))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))))); |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))))); |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))))); |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))))); |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))))); |
| static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.merge(interval).empty); |
| assert(!posInfInterval.merge(cInterval).empty); |
| assert(!posInfInterval.merge(iInterval).empty); |
| assert(!posInfInterval.merge(posInfInterval).empty); |
| assert(!posInfInterval.merge(cPosInfInterval).empty); |
| assert(!posInfInterval.merge(iPosInfInterval).empty); |
| static assert(!__traits(compiles, posInfInterval.merge(negInfInterval))); |
| static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval))); |
| static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval))); |
| assert(!cPosInfInterval.merge(interval).empty); |
| assert(!cPosInfInterval.merge(cInterval).empty); |
| assert(!cPosInfInterval.merge(iInterval).empty); |
| assert(!cPosInfInterval.merge(posInfInterval).empty); |
| assert(!cPosInfInterval.merge(cPosInfInterval).empty); |
| assert(!cPosInfInterval.merge(iPosInfInterval).empty); |
| static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval))); |
| static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval))); |
| static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval))); |
| assert(!iPosInfInterval.merge(interval).empty); |
| assert(!iPosInfInterval.merge(cInterval).empty); |
| assert(!iPosInfInterval.merge(iInterval).empty); |
| assert(!iPosInfInterval.merge(posInfInterval).empty); |
| assert(!iPosInfInterval.merge(cPosInfInterval).empty); |
| assert(!iPosInfInterval.merge(iPosInfInterval).empty); |
| static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval))); |
| static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval))); |
| static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval))); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7, 6))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1, 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7, 6))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1, 2))); |
| } |
| |
| //Test PosInfInterval's span(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(scope const PosInfInterval!Date posInfInterval, scope const Interval!Date interval) |
| { |
| posInfInterval.span(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(posInfInterval.span(posInfInterval) == posInfInterval); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == |
| PosInfInterval!Date(Date(2010, 7, 1))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| PosInfInterval!Date(Date(2010, 7, 1))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == |
| PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))) == PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))) == PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| assert(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 3))); |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| assert(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval) == PosInfInterval!Date(Date(2010, 7, 4))); |
| |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))))); |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))))); |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))))); |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))))); |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))))); |
| static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!posInfInterval.span(interval).empty); |
| assert(!posInfInterval.span(cInterval).empty); |
| assert(!posInfInterval.span(iInterval).empty); |
| assert(!posInfInterval.span(posInfInterval).empty); |
| assert(!posInfInterval.span(cPosInfInterval).empty); |
| assert(!posInfInterval.span(iPosInfInterval).empty); |
| static assert(!__traits(compiles, posInfInterval.span(negInfInterval))); |
| static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval))); |
| static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval))); |
| assert(!cPosInfInterval.span(interval).empty); |
| assert(!cPosInfInterval.span(cInterval).empty); |
| assert(!cPosInfInterval.span(iInterval).empty); |
| assert(!cPosInfInterval.span(posInfInterval).empty); |
| assert(!cPosInfInterval.span(cPosInfInterval).empty); |
| assert(!cPosInfInterval.span(iPosInfInterval).empty); |
| static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval))); |
| static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval))); |
| static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval))); |
| assert(!iPosInfInterval.span(interval).empty); |
| assert(!iPosInfInterval.span(cInterval).empty); |
| assert(!iPosInfInterval.span(iInterval).empty); |
| assert(!iPosInfInterval.span(posInfInterval).empty); |
| assert(!iPosInfInterval.span(cPosInfInterval).empty); |
| assert(!iPosInfInterval.span(iPosInfInterval).empty); |
| static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval))); |
| static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval))); |
| static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval))); |
| |
| //Verify Examples. |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == |
| PosInfInterval!Date(Date(500, 8, 9))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| PosInfInterval!Date(Date(1990, 7, 6))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == |
| PosInfInterval!Date(Date(1996, 1, 2))); |
| |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) == |
| PosInfInterval!Date(Date(1990, 7, 6))); |
| assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) == |
| PosInfInterval!Date(Date(1996, 1, 2))); |
| } |
| |
| //Test PosInfInterval's shift(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(I)(I interval, scope const Duration duration, |
| scope const I expected, size_t line = __LINE__) |
| { |
| interval.shift(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2010, 7, 26))); |
| testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2010, 6, 12))); |
| |
| const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); |
| |
| //Verify Examples. |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13))); |
| } |
| |
| //Test PosInfInterval's shift(int, int, AllowDayOverflow). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = PosInfInterval!Date(Date(2010, 7, 4)); |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.shift(years, months, allow); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); |
| |
| auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); |
| } |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| static assert(!__traits(compiles, cPosInfInterval.shift(1))); |
| static assert(!__traits(compiles, iPosInfInterval.shift(1))); |
| |
| //Verify Examples. |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.shift(2); |
| assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2))); |
| |
| interval2.shift(-2); |
| assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2))); |
| } |
| |
| //Test PosInfInterval's expand(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = PosInfInterval!Date(Date(2000, 7, 4)); |
| |
| static void testInterval(I)(I interval, scope const Duration duration, |
| scope const I expected, size_t line = __LINE__) |
| { |
| interval.expand(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2000, 6, 12))); |
| testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2000, 7, 26))); |
| |
| const cInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); |
| |
| //Verify Examples. |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4))); |
| } |
| |
| //Test PosInfInterval's expand(int, int, AllowDayOverflow). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = PosInfInterval!Date(Date(2000, 7, 4)); |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.expand(years, months, allow); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4))); |
| |
| auto interval2 = PosInfInterval!Date(Date(2000, 1, 29)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29))); |
| } |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| static assert(!__traits(compiles, cPosInfInterval.expand(1))); |
| static assert(!__traits(compiles, iPosInfInterval.expand(1))); |
| |
| //Verify Examples. |
| auto interval1 = PosInfInterval!Date(Date(1996, 1, 2)); |
| auto interval2 = PosInfInterval!Date(Date(1996, 1, 2)); |
| |
| interval1.expand(2); |
| assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2))); |
| |
| interval2.expand(-2); |
| assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2))); |
| } |
| |
| //Test PosInfInterval's fwdRange(). |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19)); |
| |
| static void testInterval(PosInfInterval!Date posInfInterval) |
| { |
| posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront(); |
| } |
| |
| assertThrown!DateTimeException(testInterval(posInfInterval)); |
| |
| assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front == |
| Date(2010, 9, 12)); |
| |
| assert(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front == |
| Date(2010, 9, 17)); |
| |
| //Verify Examples. |
| auto interval = PosInfInterval!Date(Date(2010, 9, 1)); |
| auto func = delegate (scope const Date date) |
| { |
| if ((date.day & 1) == 0) |
| return date + dur!"days"(2); |
| return date + dur!"days"(1); |
| }; |
| auto range = interval.fwdRange(func); |
| |
| assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2). |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(!range.empty); |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(!cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| assert(!iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty); |
| } |
| |
| //Test PosInfInterval's toString(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| assert(PosInfInterval!Date(Date(2010, 7, 4)).toString() == "[2010-Jul-04 - ∞)"); |
| |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| assert(cPosInfInterval.toString()); |
| assert(iPosInfInterval.toString()); |
| } |
| |
| |
| /++ |
| Represents an interval of time which has negative infinity as its starting |
| point. |
| |
| Any ranges which iterate over a `NegInfInterval` are infinite. So, the |
| main purpose of using `NegInfInterval` is to create an infinite range |
| which starts at negative infinity and goes to a fixed end point. |
| Iterate over it in reverse. |
| +/ |
| struct NegInfInterval(TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| end = The time point which ends the interval. |
| |
| Example: |
| -------------------- |
| auto interval = PosInfInterval!Date(Date(1996, 1, 2)); |
| -------------------- |
| +/ |
| this(scope const TP end) pure nothrow |
| { |
| _end = cast(TP) end; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The `NegInfInterval` to assign to this one. |
| +/ |
| ref NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow |
| { |
| _end = cast(TP) rhs._end; |
| return this; |
| } |
| |
| |
| /++ |
| Params: |
| rhs = The `NegInfInterval` to assign to this one. |
| +/ |
| ref NegInfInterval opAssign(NegInfInterval rhs) pure nothrow |
| { |
| _end = cast(TP) rhs._end; |
| return this; |
| } |
| |
| |
| /++ |
| The end point of the interval. It is excluded from the interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); |
| -------------------- |
| +/ |
| @property TP end() const pure nothrow |
| { |
| return cast(TP)_end; |
| } |
| |
| |
| /++ |
| The end point of the interval. It is excluded from the interval. |
| |
| Params: |
| timePoint = The time point to set end to. |
| +/ |
| @property void end(TP timePoint) pure nothrow |
| { |
| _end = timePoint; |
| } |
| |
| |
| /++ |
| Whether the interval's length is 0. Always returns false. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); |
| -------------------- |
| +/ |
| enum bool empty = false; |
| |
| |
| /++ |
| Whether the given time point is within this interval. |
| |
| Params: |
| timePoint = The time point to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool contains(TP timePoint) const pure nothrow |
| { |
| return timePoint < _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| -------------------- |
| +/ |
| bool contains(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._end <= _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Always returns false because an interval beginning at negative |
| infinity can never contain an interval going to positive infinity. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| -------------------- |
| +/ |
| bool contains(scope const PosInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether the given interval is completely within this interval. |
| |
| Params: |
| interval = The interval to check for inclusion in this interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains( |
| NegInfInterval!Date(Date(2013, 7, 9)))); |
| -------------------- |
| +/ |
| bool contains(scope const NegInfInterval interval) const pure nothrow |
| { |
| return interval._end <= _end; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is |
| before it. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool isBefore(scope const TP timePoint) const pure nothrow |
| { |
| return timePoint >= _end; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return _end <= interval._begin; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const PosInfInterval!TP interval) const pure nothrow |
| { |
| return _end <= interval._begin; |
| } |
| |
| |
| /++ |
| Whether this interval is before the given interval and does not |
| intersect it. |
| |
| Always returns false because an interval beginning at negative |
| infinity can never be before another interval beginning at negative |
| infinity. |
| |
| Params: |
| interval = The interval to check for against this interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore( |
| NegInfInterval!Date(Date(2013, 7, 9)))); |
| -------------------- |
| +/ |
| bool isBefore(scope const NegInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given time point. |
| |
| Always returns false because an interval beginning at negative infinity |
| can never be after any time point. |
| |
| Params: |
| timePoint = The time point to check whether this interval is after |
| it. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| bool isAfter(scope const TP timePoint) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not |
| intersect it. |
| |
| Always returns false (unless the given interval is empty) because an |
| interval beginning at negative infinity can never be after any other |
| interval. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Always returns false because an interval beginning at negative infinity |
| can never be after any other interval. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const PosInfInterval!TP interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether this interval is after the given interval and does not intersect |
| it. |
| |
| Always returns false because an interval beginning at negative infinity |
| can never be after any other interval. |
| |
| Params: |
| interval = The interval to check against this interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter( |
| NegInfInterval!Date(Date(2013, 7, 9)))); |
| -------------------- |
| +/ |
| bool isAfter(scope const NegInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| -------------------- |
| +/ |
| bool intersects(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._begin < _end; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Params: |
| interval = The interval to check for intersection with this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool intersects(scope const PosInfInterval!TP interval) const pure nothrow |
| { |
| return interval._begin < _end; |
| } |
| |
| |
| /++ |
| Whether the given interval overlaps this interval. |
| |
| Always returns true because two intervals beginning at negative infinity |
| always overlap. |
| |
| Params: |
| interval = The interval to check for intersection with this interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects( |
| NegInfInterval!Date(Date(2013, 7, 9)))); |
| -------------------- |
| +/ |
| bool intersects(scope const NegInfInterval!TP interval) const pure nothrow |
| { |
| return true; |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect or if the given interval is empty. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| Interval!TP intersection(scope const Interval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| auto end = _end < interval._end ? _end : interval._end; |
| |
| return Interval!TP(interval._begin, end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1990, 7, 6))) == |
| Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| PosInfInterval!Date(Date(1999, 1, 12))) == |
| Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1))); |
| -------------------- |
| +/ |
| Interval!TP intersection(scope const PosInfInterval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.intersects(interval), |
| new DateTimeException(format("%s and %s do not intersect.", this, interval))); |
| |
| return Interval!TP(interval._begin, _end); |
| } |
| |
| |
| /++ |
| Returns the intersection of two intervals |
| |
| Params: |
| interval = The interval to intersect with this interval. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(1999, 7 , 6))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| -------------------- |
| +/ |
| NegInfInterval intersection(scope const NegInfInterval interval) const nothrow |
| { |
| return NegInfInterval(_end < interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return interval._begin == _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| PosInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const PosInfInterval!TP interval) const pure nothrow |
| { |
| return interval._begin == _end; |
| } |
| |
| |
| /++ |
| Whether the given interval is adjacent to this interval. |
| |
| Always returns false because two intervals beginning at negative |
| infinity can never be adjacent to one another. |
| |
| Params: |
| interval = The interval to check whether its adjecent to this |
| interval. |
| |
| Example: |
| -------------------- |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| NegInfInterval!Date(Date(1996, 5, 4)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent( |
| NegInfInterval!Date(Date(2012, 3, 1)))); |
| -------------------- |
| +/ |
| bool isAdjacent(scope const NegInfInterval interval) const pure nothrow |
| { |
| return false; |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the two intervals do |
| not intersect and are not adjacent or if the given interval is empty. |
| |
| Note: |
| There is no overload for `merge` which takes a |
| `PosInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( |
| Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| NegInfInterval!Date(Date(2015, 9 , 2))); |
| -------------------- |
| +/ |
| NegInfInterval merge(scope const Interval!TP interval) const |
| { |
| import std.format : format; |
| |
| enforce(this.isAdjacent(interval) || this.intersects(interval), |
| new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval))); |
| |
| return NegInfInterval(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Returns the union of two intervals |
| |
| Params: |
| interval = The interval to merge with this interval. |
| |
| Note: |
| There is no overload for `merge` which takes a |
| `PosInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| -------------------- |
| +/ |
| NegInfInterval merge(scope const NegInfInterval interval) const pure nothrow |
| { |
| return NegInfInterval(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this |
| interval. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given interval |
| is empty. |
| |
| Note: |
| There is no overload for `span` which takes a |
| `PosInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span( |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span( |
| Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| NegInfInterval!Date(Date(2015, 9 , 2))); |
| |
| assert(NegInfInterval!Date(Date(1600, 1, 7)).span( |
| Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == |
| NegInfInterval!Date(Date(2017, 7 , 1))); |
| -------------------- |
| +/ |
| NegInfInterval span(scope const Interval!TP interval) const pure |
| { |
| interval._enforceNotEmpty(); |
| return NegInfInterval(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Returns an interval that covers from the earliest time point of two |
| intervals up to (but not including) the latest time point of two |
| intervals. |
| |
| Params: |
| interval = The interval to create a span together with this |
| interval. |
| |
| Note: |
| There is no overload for `span` which takes a |
| `PosInfInterval`, because an interval |
| going from negative infinity to positive infinity |
| is not possible. |
| |
| Example: |
| -------------------- |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span( |
| NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(2012, 3 , 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span( |
| NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1 , 12))); |
| -------------------- |
| +/ |
| NegInfInterval span(scope const NegInfInterval interval) const pure nothrow |
| { |
| return NegInfInterval(_end > interval._end ? _end : interval._end); |
| } |
| |
| |
| /++ |
| Shifts the `end` of this interval forward or backwards in time by the |
| given duration (a positive duration shifts the interval forward; a |
| negative duration shifts it backward). Effectively, it does |
| $(D end += duration). |
| |
| Params: |
| duration = The duration to shift the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); |
| -------------------- |
| +/ |
| void shift(D)(D duration) pure nothrow |
| if (__traits(compiles, end + duration)) |
| { |
| _end += duration; |
| } |
| |
| |
| static if (__traits(compiles, end.add!"months"(1)) && |
| __traits(compiles, end.add!"years"(1))) |
| { |
| /++ |
| Shifts the `end` of this interval forward or backwards in time by |
| the given number of years and/or months (a positive number of years |
| and months shifts the interval forward; a negative number shifts it |
| backward). It adds the years the given years and months to end. It |
| effectively calls `add!"years"()` and then `add!"months"()` |
| on end with the given number of years and months. |
| |
| Params: |
| years = The number of years to shift the interval by. |
| months = The number of months to shift the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `end`, causing its month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if empty is true or |
| if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.shift(2); |
| assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); |
| |
| interval2.shift(-2); |
| assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); |
| -------------------- |
| +/ |
| void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto end = _end; |
| |
| end.add!"years"(years, allowOverflow); |
| end.add!"months"(months, allowOverflow); |
| |
| _end = end; |
| } |
| } |
| |
| |
| /++ |
| Expands the interval forwards in time. Effectively, it does |
| $(D end += duration). |
| |
| Params: |
| duration = The duration to expand the interval by. |
| |
| Example: |
| -------------------- |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); |
| -------------------- |
| +/ |
| void expand(D)(D duration) pure nothrow |
| if (__traits(compiles, end + duration)) |
| { |
| _end += duration; |
| } |
| |
| |
| static if (__traits(compiles, end.add!"months"(1)) && |
| __traits(compiles, end.add!"years"(1))) |
| { |
| /++ |
| Expands the interval forwards and/or backwards in time. Effectively, |
| it adds the given number of months/years to end. |
| |
| Params: |
| years = The number of years to expand the interval by. |
| months = The number of months to expand the interval by. |
| allowOverflow = Whether the days should be allowed to overflow |
| on `end`, causing their month to increment. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if empty is true or |
| if the resulting interval would be invalid. |
| |
| Example: |
| -------------------- |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.expand(2); |
| assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); |
| |
| interval2.expand(-2); |
| assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); |
| -------------------- |
| +/ |
| void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) |
| if (isIntegral!T) |
| { |
| auto end = _end; |
| |
| end.add!"years"(years, allowOverflow); |
| end.add!"months"(months, allowOverflow); |
| |
| _end = end; |
| } |
| } |
| |
| |
| /++ |
| Returns a range which iterates backwards over the interval, starting |
| at `end`, using $(D_PARAM func) to generate each successive time |
| point. |
| |
| The range's `front` is the interval's `end`. $(D_PARAM func) is |
| used to generate the next `front` when `popFront` is called. If |
| $(D_PARAM popFirst) is `PopFirst.yes`, then `popFront` is called |
| before the range is returned (so that `front` is a time point which |
| $(D_PARAM func) would generate). |
| |
| If $(D_PARAM func) ever generates a time point greater than or equal to |
| the current `front` of the range, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. |
| |
| There are helper functions in this module which generate common |
| delegates to pass to `bwdRange`. Their documentation starts with |
| "Range-generating function," to make them easily searchable. |
| |
| Params: |
| func = The function used to generate the time points of the |
| range over the interval. |
| popFirst = Whether `popFront` should be called on the range |
| before returning it. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| |
| Warning: |
| $(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func) |
| would be a function pointer to a pure function, but forcing |
| $(D_PARAM func) to be pure is far too restrictive to be useful, and |
| in order to have the ease of use of having functions which generate |
| functions to pass to `fwdRange`, $(D_PARAM func) must be a |
| delegate. |
| |
| If $(D_PARAM func) retains state which changes as it is called, then |
| some algorithms will not work correctly, because the range's |
| `save` will have failed to have really saved the range's state. |
| To avoid such bugs, don't pass a delegate which is |
| not logically pure to `fwdRange`. If $(D_PARAM func) is given the |
| same time point with two different calls, it must return the same |
| result both times. |
| |
| Of course, none of the functions in this module have this problem, |
| so it's only relevant for custom delegates. |
| |
| Example: |
| -------------------- |
| auto interval = NegInfInterval!Date(Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) //For iterating over even-numbered days. |
| { |
| if ((date.day & 1) == 0) |
| return date - dur!"days"(2); |
| |
| return date - dur!"days"(1); |
| }; |
| auto range = interval.bwdRange(func); |
| |
| assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(!range.empty); |
| -------------------- |
| +/ |
| NegInfIntervalRange!(TP) bwdRange(TP delegate(scope const TP) func, PopFirst popFirst = PopFirst.no) const |
| { |
| auto range = NegInfIntervalRange!(TP)(this, func); |
| |
| if (popFirst == PopFirst.yes) |
| range.popFront(); |
| |
| return range; |
| } |
| |
| |
| /+ |
| Converts this interval to a string. |
| +/ |
| // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't |
| // have versions of toString() with extra modifiers, |
| // so we define one version with modifiers and one without. |
| string toString() |
| { |
| return _toStringImpl(); |
| } |
| |
| |
| /++ |
| Converts this interval to a string. |
| +/ |
| // Due to bug https://issues.dlang.org/show_bug.cgi?id=3715 , we can't |
| // have versions of toString() with extra modifiers, |
| // so we define one version with modifiers and one without. |
| string toString() const nothrow |
| { |
| return _toStringImpl(); |
| } |
| |
| private: |
| |
| /+ |
| Since we have two versions of toString(), we have _toStringImpl() |
| so that they can share implementations. |
| +/ |
| string _toStringImpl() const nothrow |
| { |
| import std.format : format; |
| try |
| return format("[-∞ - %s)", _end); |
| catch (Exception e) |
| assert(0, "format() threw."); |
| } |
| |
| |
| TP _end; |
| } |
| |
| //Test NegInfInterval's constructor. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| NegInfInterval!Date(Date.init); |
| NegInfInterval!TimeOfDay(TimeOfDay.init); |
| NegInfInterval!DateTime(DateTime.init); |
| NegInfInterval!SysTime(SysTime(0)); |
| } |
| |
| //Test NegInfInterval's end. |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); |
| assert(NegInfInterval!Date(Date(2010, 1, 1)).end == Date(2010, 1, 1)); |
| assert(NegInfInterval!Date(Date(1998, 1, 1)).end == Date(1998, 1, 1)); |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(cNegInfInterval.end != Date.init); |
| assert(iNegInfInterval.end != Date.init); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1)); |
| } |
| |
| //Test NegInfInterval's empty. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty); |
| assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty); |
| assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty); |
| assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty); |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!cNegInfInterval.empty); |
| assert(!iNegInfInterval.empty); |
| |
| //Verify Examples. |
| assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty); |
| } |
| |
| //Test NegInfInterval's contains(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| assert(negInfInterval.contains(Date(2009, 7, 4))); |
| assert(negInfInterval.contains(Date(2010, 7, 3))); |
| assert(negInfInterval.contains(Date(2010, 7, 4))); |
| assert(negInfInterval.contains(Date(2010, 7, 5))); |
| assert(negInfInterval.contains(Date(2011, 7, 1))); |
| assert(negInfInterval.contains(Date(2012, 1, 6))); |
| assert(!negInfInterval.contains(Date(2012, 1, 7))); |
| assert(!negInfInterval.contains(Date(2012, 1, 8))); |
| assert(!negInfInterval.contains(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(negInfInterval.contains(cdate)); |
| assert(cNegInfInterval.contains(cdate)); |
| assert(iNegInfInterval.contains(cdate)); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1))); |
| } |
| |
| //Test NegInfInterval's contains(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) |
| { |
| negInfInterval.contains(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(negInfInterval.contains(negInfInterval)); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval)); |
| |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(negInfInterval.contains(interval)); |
| assert(negInfInterval.contains(cInterval)); |
| assert(negInfInterval.contains(iInterval)); |
| assert(!negInfInterval.contains(posInfInterval)); |
| assert(!negInfInterval.contains(cPosInfInterval)); |
| assert(!negInfInterval.contains(iPosInfInterval)); |
| assert(negInfInterval.contains(negInfInterval)); |
| assert(negInfInterval.contains(cNegInfInterval)); |
| assert(negInfInterval.contains(iNegInfInterval)); |
| assert(cNegInfInterval.contains(interval)); |
| assert(cNegInfInterval.contains(cInterval)); |
| assert(cNegInfInterval.contains(iInterval)); |
| assert(!cNegInfInterval.contains(posInfInterval)); |
| assert(!cNegInfInterval.contains(cPosInfInterval)); |
| assert(!cNegInfInterval.contains(iPosInfInterval)); |
| assert(cNegInfInterval.contains(negInfInterval)); |
| assert(cNegInfInterval.contains(cNegInfInterval)); |
| assert(cNegInfInterval.contains(iNegInfInterval)); |
| assert(iNegInfInterval.contains(interval)); |
| assert(iNegInfInterval.contains(cInterval)); |
| assert(iNegInfInterval.contains(iInterval)); |
| assert(!iNegInfInterval.contains(posInfInterval)); |
| assert(!iNegInfInterval.contains(cPosInfInterval)); |
| assert(!iNegInfInterval.contains(iPosInfInterval)); |
| assert(iNegInfInterval.contains(negInfInterval)); |
| assert(iNegInfInterval.contains(cNegInfInterval)); |
| assert(iNegInfInterval.contains(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9)))); |
| } |
| |
| //Test NegInfInterval's isBefore(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| assert(!negInfInterval.isBefore(Date(2009, 7, 4))); |
| assert(!negInfInterval.isBefore(Date(2010, 7, 3))); |
| assert(!negInfInterval.isBefore(Date(2010, 7, 4))); |
| assert(!negInfInterval.isBefore(Date(2010, 7, 5))); |
| assert(!negInfInterval.isBefore(Date(2011, 7, 1))); |
| assert(!negInfInterval.isBefore(Date(2012, 1, 6))); |
| assert(negInfInterval.isBefore(Date(2012, 1, 7))); |
| assert(negInfInterval.isBefore(Date(2012, 1, 8))); |
| assert(negInfInterval.isBefore(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.isBefore(cdate)); |
| assert(!cNegInfInterval.isBefore(cdate)); |
| assert(!iNegInfInterval.isBefore(cdate)); |
| |
| //Verify Examples. |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1))); |
| } |
| |
| //Test NegInfInterval's isBefore(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) |
| { |
| negInfInterval.isBefore(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!negInfInterval.isBefore(negInfInterval)); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval)); |
| |
| assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.isBefore(interval)); |
| assert(!negInfInterval.isBefore(cInterval)); |
| assert(!negInfInterval.isBefore(iInterval)); |
| assert(!negInfInterval.isBefore(posInfInterval)); |
| assert(!negInfInterval.isBefore(cPosInfInterval)); |
| assert(!negInfInterval.isBefore(iPosInfInterval)); |
| assert(!negInfInterval.isBefore(negInfInterval)); |
| assert(!negInfInterval.isBefore(cNegInfInterval)); |
| assert(!negInfInterval.isBefore(iNegInfInterval)); |
| assert(!cNegInfInterval.isBefore(interval)); |
| assert(!cNegInfInterval.isBefore(cInterval)); |
| assert(!cNegInfInterval.isBefore(iInterval)); |
| assert(!cNegInfInterval.isBefore(posInfInterval)); |
| assert(!cNegInfInterval.isBefore(cPosInfInterval)); |
| assert(!cNegInfInterval.isBefore(iPosInfInterval)); |
| assert(!cNegInfInterval.isBefore(negInfInterval)); |
| assert(!cNegInfInterval.isBefore(cNegInfInterval)); |
| assert(!cNegInfInterval.isBefore(iNegInfInterval)); |
| assert(!iNegInfInterval.isBefore(interval)); |
| assert(!iNegInfInterval.isBefore(cInterval)); |
| assert(!iNegInfInterval.isBefore(iInterval)); |
| assert(!iNegInfInterval.isBefore(posInfInterval)); |
| assert(!iNegInfInterval.isBefore(cPosInfInterval)); |
| assert(!iNegInfInterval.isBefore(iPosInfInterval)); |
| assert(!iNegInfInterval.isBefore(negInfInterval)); |
| assert(!iNegInfInterval.isBefore(cNegInfInterval)); |
| assert(!iNegInfInterval.isBefore(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9)))); |
| } |
| |
| //Test NegInfInterval's isAfter(time point). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| assert(!negInfInterval.isAfter(Date(2009, 7, 4))); |
| assert(!negInfInterval.isAfter(Date(2010, 7, 3))); |
| assert(!negInfInterval.isAfter(Date(2010, 7, 4))); |
| assert(!negInfInterval.isAfter(Date(2010, 7, 5))); |
| assert(!negInfInterval.isAfter(Date(2011, 7, 1))); |
| assert(!negInfInterval.isAfter(Date(2012, 1, 6))); |
| assert(!negInfInterval.isAfter(Date(2012, 1, 7))); |
| assert(!negInfInterval.isAfter(Date(2012, 1, 8))); |
| assert(!negInfInterval.isAfter(Date(2013, 1, 7))); |
| |
| const cdate = Date(2010, 7, 6); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.isAfter(cdate)); |
| assert(!cNegInfInterval.isAfter(cdate)); |
| assert(!iNegInfInterval.isAfter(cdate)); |
| } |
| |
| //Test NegInfInterval's isAfter(Interval). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) |
| { |
| negInfInterval.isAfter(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!negInfInterval.isAfter(negInfInterval)); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval)); |
| |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.isAfter(interval)); |
| assert(!negInfInterval.isAfter(cInterval)); |
| assert(!negInfInterval.isAfter(iInterval)); |
| assert(!negInfInterval.isAfter(posInfInterval)); |
| assert(!negInfInterval.isAfter(cPosInfInterval)); |
| assert(!negInfInterval.isAfter(iPosInfInterval)); |
| assert(!negInfInterval.isAfter(negInfInterval)); |
| assert(!negInfInterval.isAfter(cNegInfInterval)); |
| assert(!negInfInterval.isAfter(iNegInfInterval)); |
| assert(!cNegInfInterval.isAfter(interval)); |
| assert(!cNegInfInterval.isAfter(cInterval)); |
| assert(!cNegInfInterval.isAfter(iInterval)); |
| assert(!cNegInfInterval.isAfter(posInfInterval)); |
| assert(!cNegInfInterval.isAfter(cPosInfInterval)); |
| assert(!cNegInfInterval.isAfter(iPosInfInterval)); |
| assert(!cNegInfInterval.isAfter(negInfInterval)); |
| assert(!cNegInfInterval.isAfter(cNegInfInterval)); |
| assert(!cNegInfInterval.isAfter(iNegInfInterval)); |
| assert(!iNegInfInterval.isAfter(interval)); |
| assert(!iNegInfInterval.isAfter(cInterval)); |
| assert(!iNegInfInterval.isAfter(iInterval)); |
| assert(!iNegInfInterval.isAfter(posInfInterval)); |
| assert(!iNegInfInterval.isAfter(cPosInfInterval)); |
| assert(!iNegInfInterval.isAfter(iPosInfInterval)); |
| assert(!iNegInfInterval.isAfter(negInfInterval)); |
| assert(!iNegInfInterval.isAfter(cNegInfInterval)); |
| assert(!iNegInfInterval.isAfter(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9)))); |
| } |
| |
| //Test NegInfInterval's intersects(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) |
| { |
| negInfInterval.intersects(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(negInfInterval.intersects(negInfInterval)); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval)); |
| assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval)); |
| |
| assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(negInfInterval.intersects(interval)); |
| assert(negInfInterval.intersects(cInterval)); |
| assert(negInfInterval.intersects(iInterval)); |
| assert(negInfInterval.intersects(posInfInterval)); |
| assert(negInfInterval.intersects(cPosInfInterval)); |
| assert(negInfInterval.intersects(iPosInfInterval)); |
| assert(negInfInterval.intersects(negInfInterval)); |
| assert(negInfInterval.intersects(cNegInfInterval)); |
| assert(negInfInterval.intersects(iNegInfInterval)); |
| assert(cNegInfInterval.intersects(interval)); |
| assert(cNegInfInterval.intersects(cInterval)); |
| assert(cNegInfInterval.intersects(iInterval)); |
| assert(cNegInfInterval.intersects(posInfInterval)); |
| assert(cNegInfInterval.intersects(cPosInfInterval)); |
| assert(cNegInfInterval.intersects(iPosInfInterval)); |
| assert(cNegInfInterval.intersects(negInfInterval)); |
| assert(cNegInfInterval.intersects(cNegInfInterval)); |
| assert(cNegInfInterval.intersects(iNegInfInterval)); |
| assert(iNegInfInterval.intersects(interval)); |
| assert(iNegInfInterval.intersects(cInterval)); |
| assert(iNegInfInterval.intersects(iInterval)); |
| assert(iNegInfInterval.intersects(posInfInterval)); |
| assert(iNegInfInterval.intersects(cPosInfInterval)); |
| assert(iNegInfInterval.intersects(iPosInfInterval)); |
| assert(iNegInfInterval.intersects(negInfInterval)); |
| assert(iNegInfInterval.intersects(cNegInfInterval)); |
| assert(iNegInfInterval.intersects(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9)))); |
| } |
| |
| //Test NegInfInterval's intersection(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I, J)(scope const I interval1, scope const J interval2) |
| { |
| interval1.intersection(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7)))); |
| assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(negInfInterval.intersection(negInfInterval) == negInfInterval); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == |
| Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))); |
| |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2010, 7, 3))); |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2010, 7, 4))); |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2010, 7, 5))); |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 6))); |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| |
| assert(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 3))); |
| assert(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 4))); |
| assert(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval) == NegInfInterval!Date(Date(2010, 7, 5))); |
| assert(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 6))); |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| |
| assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))) == |
| Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7))); |
| assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))) == |
| Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7))); |
| assert(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))) == |
| Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7))); |
| assert(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))) == |
| Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.intersection(interval).empty); |
| assert(!negInfInterval.intersection(cInterval).empty); |
| assert(!negInfInterval.intersection(iInterval).empty); |
| assert(!negInfInterval.intersection(posInfInterval).empty); |
| assert(!negInfInterval.intersection(cPosInfInterval).empty); |
| assert(!negInfInterval.intersection(iPosInfInterval).empty); |
| assert(!negInfInterval.intersection(negInfInterval).empty); |
| assert(!negInfInterval.intersection(cNegInfInterval).empty); |
| assert(!negInfInterval.intersection(iNegInfInterval).empty); |
| assert(!cNegInfInterval.intersection(interval).empty); |
| assert(!cNegInfInterval.intersection(cInterval).empty); |
| assert(!cNegInfInterval.intersection(iInterval).empty); |
| assert(!cNegInfInterval.intersection(posInfInterval).empty); |
| assert(!cNegInfInterval.intersection(cPosInfInterval).empty); |
| assert(!cNegInfInterval.intersection(iPosInfInterval).empty); |
| assert(!cNegInfInterval.intersection(negInfInterval).empty); |
| assert(!cNegInfInterval.intersection(cNegInfInterval).empty); |
| assert(!cNegInfInterval.intersection(iNegInfInterval).empty); |
| assert(!iNegInfInterval.intersection(interval).empty); |
| assert(!iNegInfInterval.intersection(cInterval).empty); |
| assert(!iNegInfInterval.intersection(iInterval).empty); |
| assert(!iNegInfInterval.intersection(posInfInterval).empty); |
| assert(!iNegInfInterval.intersection(cPosInfInterval).empty); |
| assert(!iNegInfInterval.intersection(iPosInfInterval).empty); |
| assert(!iNegInfInterval.intersection(negInfInterval).empty); |
| assert(!iNegInfInterval.intersection(cNegInfInterval).empty); |
| assert(!iNegInfInterval.intersection(iNegInfInterval).empty); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == |
| Interval!Date(Date(1990, 7, 6), Date(2012, 3, 1))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == |
| Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(1999, 7, 6))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2012, 3, 1))); |
| } |
| |
| //Test NegInfInterval's isAdjacent(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(scope const NegInfInterval!Date negInfInterval, scope const Interval!Date interval) |
| { |
| negInfInterval.isAdjacent(interval); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(!negInfInterval.isAdjacent(negInfInterval)); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)))); |
| assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)))); |
| assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6)))); |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8)))); |
| |
| assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval)); |
| assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval)); |
| |
| assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3)))); |
| assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4)))); |
| assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5)))); |
| assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6)))); |
| assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7)))); |
| assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8)))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.isAdjacent(interval)); |
| assert(!negInfInterval.isAdjacent(cInterval)); |
| assert(!negInfInterval.isAdjacent(iInterval)); |
| assert(!negInfInterval.isAdjacent(posInfInterval)); |
| assert(!negInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!negInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!negInfInterval.isAdjacent(negInfInterval)); |
| assert(!negInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!negInfInterval.isAdjacent(iNegInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(interval)); |
| assert(!cNegInfInterval.isAdjacent(cInterval)); |
| assert(!cNegInfInterval.isAdjacent(iInterval)); |
| assert(!cNegInfInterval.isAdjacent(posInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(negInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!cNegInfInterval.isAdjacent(iNegInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(interval)); |
| assert(!iNegInfInterval.isAdjacent(cInterval)); |
| assert(!iNegInfInterval.isAdjacent(iInterval)); |
| assert(!iNegInfInterval.isAdjacent(posInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(cPosInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(iPosInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(negInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(cNegInfInterval)); |
| assert(!iNegInfInterval.isAdjacent(iNegInfInterval)); |
| |
| //Verify Examples. |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4)))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1)))); |
| |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4)))); |
| assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1)))); |
| } |
| |
| //Test NegInfInterval's merge(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I, J)(scope const I interval1, scope const J interval2) |
| { |
| interval1.merge(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)))); |
| |
| assert(negInfInterval.merge(negInfInterval) == negInfInterval); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| NegInfInterval!Date(Date(2013, 7, 3))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| assert(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| assert(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))))); |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))))); |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))))); |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))))); |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))))); |
| static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.merge(interval).empty); |
| assert(!negInfInterval.merge(cInterval).empty); |
| assert(!negInfInterval.merge(iInterval).empty); |
| static assert(!__traits(compiles, negInfInterval.merge(posInfInterval))); |
| static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval))); |
| static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval))); |
| assert(!negInfInterval.merge(negInfInterval).empty); |
| assert(!negInfInterval.merge(cNegInfInterval).empty); |
| assert(!negInfInterval.merge(iNegInfInterval).empty); |
| assert(!cNegInfInterval.merge(interval).empty); |
| assert(!cNegInfInterval.merge(cInterval).empty); |
| assert(!cNegInfInterval.merge(iInterval).empty); |
| static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval))); |
| static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval))); |
| static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval))); |
| assert(!cNegInfInterval.merge(negInfInterval).empty); |
| assert(!cNegInfInterval.merge(cNegInfInterval).empty); |
| assert(!cNegInfInterval.merge(iNegInfInterval).empty); |
| assert(!iNegInfInterval.merge(interval).empty); |
| assert(!iNegInfInterval.merge(cInterval).empty); |
| assert(!iNegInfInterval.merge(iInterval).empty); |
| static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval))); |
| static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval))); |
| static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval))); |
| assert(!iNegInfInterval.merge(negInfInterval).empty); |
| assert(!iNegInfInterval.merge(cNegInfInterval).empty); |
| assert(!iNegInfInterval.merge(iNegInfInterval).empty); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| NegInfInterval!Date(Date(2012, 3, 1))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| NegInfInterval!Date(Date(2015, 9, 2))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(2012, 3, 1))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1, 12))); |
| } |
| |
| //Test NegInfInterval's span(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I, J)(scope const I interval1, scope const J interval2) |
| { |
| interval1.span(interval2); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0)))); |
| |
| assert(negInfInterval.span(negInfInterval) == negInfInterval); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))) == |
| NegInfInterval!Date(Date(2013, 7, 3))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))) == |
| NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| assert(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))) == |
| NegInfInterval!Date(Date(2012, 1, 8))); |
| assert(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))) == |
| NegInfInterval!Date(Date(2012, 1, 9))); |
| |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))) == NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| assert(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 7))); |
| assert(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval) == NegInfInterval!Date(Date(2012, 1, 8))); |
| |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))))); |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))))); |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))))); |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))))); |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))))); |
| static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))))); |
| |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!negInfInterval.span(interval).empty); |
| assert(!negInfInterval.span(cInterval).empty); |
| assert(!negInfInterval.span(iInterval).empty); |
| static assert(!__traits(compiles, negInfInterval.span(posInfInterval))); |
| static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval))); |
| static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval))); |
| assert(!negInfInterval.span(negInfInterval).empty); |
| assert(!negInfInterval.span(cNegInfInterval).empty); |
| assert(!negInfInterval.span(iNegInfInterval).empty); |
| assert(!cNegInfInterval.span(interval).empty); |
| assert(!cNegInfInterval.span(cInterval).empty); |
| assert(!cNegInfInterval.span(iInterval).empty); |
| static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval))); |
| static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval))); |
| static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval))); |
| assert(!cNegInfInterval.span(negInfInterval).empty); |
| assert(!cNegInfInterval.span(cNegInfInterval).empty); |
| assert(!cNegInfInterval.span(iNegInfInterval).empty); |
| assert(!iNegInfInterval.span(interval).empty); |
| assert(!iNegInfInterval.span(cInterval).empty); |
| assert(!iNegInfInterval.span(iInterval).empty); |
| static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval))); |
| static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval))); |
| static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval))); |
| assert(!iNegInfInterval.span(negInfInterval).empty); |
| assert(!iNegInfInterval.span(cNegInfInterval).empty); |
| assert(!iNegInfInterval.span(iNegInfInterval).empty); |
| |
| //Verify Examples. |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == |
| NegInfInterval!Date(Date(2012, 3, 1))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == |
| NegInfInterval!Date(Date(2015, 9, 2))); |
| assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == |
| NegInfInterval!Date(Date(2017, 7, 1))); |
| |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) == |
| NegInfInterval!Date(Date(2012, 3, 1))); |
| assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == |
| NegInfInterval!Date(Date(2013, 1, 12))); |
| } |
| |
| //Test NegInfInterval's shift(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I)(I interval, scope const Duration duration, |
| scope const I expected, size_t line = __LINE__) |
| { |
| interval.shift(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); |
| testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); |
| |
| const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.shift(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.shift(dur!"days"(5)))); |
| |
| //Verify Examples. |
| auto interval1 = NegInfInterval!Date(Date(2012, 4, 5)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 4, 5)); |
| |
| interval1.shift(dur!"days"(50)); |
| assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25))); |
| |
| interval2.shift(dur!"days"(-50)); |
| assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15))); |
| } |
| |
| //Test NegInfInterval's shift(int, int, AllowDayOverflow). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testIntervalFail(I)(I interval, int years, int months) |
| { |
| interval.shift(years, months); |
| } |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.shift(years, months, allow); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); |
| |
| auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30))); |
| } |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cNegInfInterval.shift(1))); |
| static assert(!__traits(compiles, iNegInfInterval.shift(1))); |
| |
| //Verify Examples. |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.shift(2); |
| assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); |
| |
| interval2.shift(-2); |
| assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); |
| } |
| |
| //Test NegInfInterval's expand(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I)(I interval, |
| scope const Duration duration, scope const I expected, size_t line = __LINE__) |
| { |
| interval.expand(duration); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29))); |
| testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16))); |
| |
| const cInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cInterval.expand(dur!"days"(5)))); |
| static assert(!__traits(compiles, iInterval.expand(dur!"days"(5)))); |
| |
| //Verify Examples. |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.expand(dur!"days"(2)); |
| assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3))); |
| |
| interval2.expand(dur!"days"(-2)); |
| assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28))); |
| } |
| |
| //Test NegInfInterval's expand(int, int, AllowDayOverflow). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| { |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, |
| in I expected, size_t line = __LINE__) |
| { |
| interval.expand(years, months, allow); |
| assert(interval == expected); |
| } |
| |
| testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7))); |
| testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7))); |
| |
| auto interval2 = NegInfInterval!Date(Date(2010, 5, 31)); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1))); |
| |
| testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30))); |
| testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30))); |
| testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30))); |
| testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30))); |
| } |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| static assert(!__traits(compiles, cNegInfInterval.expand(1))); |
| static assert(!__traits(compiles, iNegInfInterval.expand(1))); |
| |
| //Verify Examples. |
| auto interval1 = NegInfInterval!Date(Date(2012, 3, 1)); |
| auto interval2 = NegInfInterval!Date(Date(2012, 3, 1)); |
| |
| interval1.expand(2); |
| assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1))); |
| |
| interval2.expand(-2); |
| assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1))); |
| } |
| |
| //Test NegInfInterval's bwdRange(). |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| |
| static void testInterval(NegInfInterval!Date negInfInterval) |
| { |
| negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront(); |
| } |
| |
| assertThrown!DateTimeException(testInterval(negInfInterval)); |
| |
| assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front == |
| Date(2010, 10, 1)); |
| |
| assert(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front == Date(2010, 9, 24)); |
| |
| //Verify Examples. |
| auto interval = NegInfInterval!Date(Date(2010, 9, 9)); |
| auto func = delegate (scope const Date date) |
| { |
| if ((date.day & 1) == 0) |
| return date - dur!"days"(2); |
| return date - dur!"days"(1); |
| }; |
| auto range = interval.bwdRange(func); |
| |
| //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8). |
| assert(range.front == Date(2010, 9, 9)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 8)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(!range.empty); |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(!cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); |
| assert(!iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty); |
| } |
| |
| //Test NegInfInterval's toString(). |
| @safe unittest |
| { |
| import std.datetime.date; |
| |
| assert(NegInfInterval!Date(Date(2012, 1, 7)).toString() == "[-∞ - 2012-Jan-07)"); |
| |
| const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| assert(cNegInfInterval.toString()); |
| assert(iNegInfInterval.toString()); |
| } |
| |
| |
| /++ |
| Range-generating function. |
| |
| Returns a delegate which returns the next time point with the given |
| `DayOfWeek` in a range. |
| |
| Using this delegate allows iteration over successive time points which |
| are all the same day of the week. e.g. passing `DayOfWeek.mon` to |
| `everyDayOfWeek` would result in a delegate which could be used to |
| iterate over all of the Mondays in a range. |
| |
| Params: |
| dir = The direction to iterate in. If passing the return value to |
| `fwdRange`, use `Direction.fwd`. If passing it to |
| `bwdRange`, use `Direction.bwd`. |
| dayOfWeek = The week that each time point in the range will be. |
| +/ |
| TP delegate(scope const TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow |
| if (isTimePoint!TP && |
| (dir == Direction.fwd || dir == Direction.bwd) && |
| __traits(hasMember, TP, "dayOfWeek") && |
| !__traits(isStaticFunction, TP.dayOfWeek) && |
| is(typeof(TP.dayOfWeek) == DayOfWeek)) |
| { |
| TP func(scope const TP tp) |
| { |
| TP retval = cast(TP) tp; |
| immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek); |
| |
| static if (dir == Direction.fwd) |
| immutable adjustedDays = days == 0 ? 7 : days; |
| else |
| immutable adjustedDays = days == 0 ? -7 : days - 7; |
| |
| return retval += dur!"days"(adjustedDays); |
| } |
| |
| return &func; |
| } |
| |
| /// |
| @system unittest |
| { |
| import std.datetime.date : Date, DayOfWeek; |
| |
| auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.mon); |
| auto range = interval.fwdRange(func); |
| |
| // A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6). |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 13)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 20)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon); |
| auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon); |
| |
| assert(funcFwd(Date(2010, 8, 28)) == Date(2010, 8, 30)); |
| assert(funcFwd(Date(2010, 8, 29)) == Date(2010, 8, 30)); |
| assert(funcFwd(Date(2010, 8, 30)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 8, 31)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 1)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 2)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 3)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 4)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 5)) == Date(2010, 9, 6)); |
| assert(funcFwd(Date(2010, 9, 6)) == Date(2010, 9, 13)); |
| assert(funcFwd(Date(2010, 9, 7)) == Date(2010, 9, 13)); |
| |
| assert(funcBwd(Date(2010, 8, 28)) == Date(2010, 8, 23)); |
| assert(funcBwd(Date(2010, 8, 29)) == Date(2010, 8, 23)); |
| assert(funcBwd(Date(2010, 8, 30)) == Date(2010, 8, 23)); |
| assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 1)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 2)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 3)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 4)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 5)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 6)) == Date(2010, 8, 30)); |
| assert(funcBwd(Date(2010, 9, 7)) == Date(2010, 9, 6)); |
| |
| static assert(!__traits(compiles, everyDayOfWeek!TimeOfDay(DayOfWeek.mon))); |
| assert(everyDayOfWeek!DateTime(DayOfWeek.mon) !is null); |
| assert(everyDayOfWeek!SysTime(DayOfWeek.mon) !is null); |
| } |
| |
| |
| /++ |
| Range-generating function. |
| |
| Returns a delegate which returns the next time point with the given month |
| which would be reached by adding months to the given time point. |
| |
| So, using this delegate allows iteration over successive time points |
| which are in the same month but different years. For example, |
| iterate over each successive December 25th in an interval by starting with a |
| date which had the 25th as its day and passed `Month.dec` to |
| `everyMonth` to create the delegate. |
| |
| Since it wouldn't really make sense to be iterating over a specific month |
| and end up with some of the time points in the succeeding month or two years |
| after the previous time point, `AllowDayOverflow.no` is always used when |
| calculating the next time point. |
| |
| Params: |
| dir = The direction to iterate in. If passing the return value to |
| `fwdRange`, use `Direction.fwd`. If passing it to |
| `bwdRange`, use `Direction.bwd`. |
| month = The month that each time point in the range will be in |
| (January is 1). |
| +/ |
| TP delegate(scope const TP) everyMonth(TP, Direction dir = Direction.fwd)(int month) |
| if (isTimePoint!TP && |
| (dir == Direction.fwd || dir == Direction.bwd) && |
| __traits(hasMember, TP, "month") && |
| !__traits(isStaticFunction, TP.month) && |
| is(typeof(TP.month) == Month)) |
| { |
| import std.datetime.date : enforceValid, monthsToMonth; |
| |
| enforceValid!"months"(month); |
| |
| TP func(scope const TP tp) |
| { |
| TP retval = cast(TP) tp; |
| immutable months = monthsToMonth(retval.month, month); |
| |
| static if (dir == Direction.fwd) |
| immutable adjustedMonths = months == 0 ? 12 : months; |
| else |
| immutable adjustedMonths = months == 0 ? -12 : months - 12; |
| |
| retval.add!"months"(adjustedMonths, AllowDayOverflow.no); |
| |
| if (retval.month != month) |
| { |
| retval.add!"months"(-1); |
| assert(retval.month == month); |
| } |
| |
| return retval; |
| } |
| |
| return &func; |
| } |
| |
| /// |
| @system unittest |
| { |
| import std.datetime.date : Date, Month; |
| |
| auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5)); |
| auto func = everyMonth!Date(Month.feb); |
| auto range = interval.fwdRange(func); |
| |
| // Using PopFirst.yes would have made this Date(2010, 2, 29). |
| assert(range.front == Date(2000, 1, 30)); |
| |
| range.popFront(); |
| assert(range.front == Date(2000, 2, 29)); |
| |
| range.popFront(); |
| assert(range.front == Date(2001, 2, 28)); |
| |
| range.popFront(); |
| assert(range.front == Date(2002, 2, 28)); |
| |
| range.popFront(); |
| assert(range.front == Date(2003, 2, 28)); |
| |
| range.popFront(); |
| assert(range.front == Date(2004, 2, 28)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| auto funcFwd = everyMonth!Date(Month.jun); |
| auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun); |
| |
| assert(funcFwd(Date(2010, 5, 31)) == Date(2010, 6, 30)); |
| assert(funcFwd(Date(2010, 6, 30)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 7, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 8, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 9, 30)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 10, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 11, 30)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2010, 12, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2011, 1, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2011, 2, 28)) == Date(2011, 6, 28)); |
| assert(funcFwd(Date(2011, 3, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2011, 4, 30)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2011, 5, 31)) == Date(2011, 6, 30)); |
| assert(funcFwd(Date(2011, 6, 30)) == Date(2012, 6, 30)); |
| assert(funcFwd(Date(2011, 7, 31)) == Date(2012, 6, 30)); |
| |
| assert(funcBwd(Date(2010, 5, 31)) == Date(2009, 6, 30)); |
| assert(funcBwd(Date(2010, 6, 30)) == Date(2009, 6, 30)); |
| assert(funcBwd(Date(2010, 7, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2010, 8, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2010, 9, 30)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2010, 10, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2010, 11, 30)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2010, 12, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 1, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 2, 28)) == Date(2010, 6, 28)); |
| assert(funcBwd(Date(2011, 3, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 4, 30)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 5, 31)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 6, 30)) == Date(2010, 6, 30)); |
| assert(funcBwd(Date(2011, 7, 30)) == Date(2011, 6, 30)); |
| |
| static assert(!__traits(compiles, everyMonth!TimeOfDay(Month.jan))); |
| assert(everyMonth!DateTime(Month.jan) !is null); |
| assert(everyMonth!SysTime(Month.jan) !is null); |
| } |
| |
| |
| /++ |
| Range-generating function. |
| |
| Returns a delegate which returns the next time point which is the given |
| duration later. |
| |
| Using this delegate allows iteration over successive time points which |
| are apart by the given duration e.g. passing `dur!"days"(3)` to |
| `everyDuration` would result in a delegate which could be used to iterate |
| over a range of days which are each 3 days apart. |
| |
| Params: |
| dir = The direction to iterate in. If passing the return value to |
| `fwdRange`, use `Direction.fwd`. If passing it to |
| `bwdRange`, use `Direction.bwd`. |
| duration = The duration which separates each successive time point in |
| the range. |
| +/ |
| TP delegate(return scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D)(D duration) nothrow |
| if (isTimePoint!TP && |
| __traits(compiles, TP.init + duration) && |
| (dir == Direction.fwd || dir == Direction.bwd)) |
| { |
| TP func(return scope const TP tp) |
| { |
| static if (dir == Direction.fwd) |
| return tp + duration; |
| else |
| return tp - duration; |
| } |
| |
| return &func; |
| } |
| |
| /// |
| @system unittest |
| { |
| import core.time : dur; |
| import std.datetime.date : Date; |
| |
| auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27)); |
| auto func = everyDuration!Date(dur!"days"(8)); |
| auto range = interval.fwdRange(func); |
| |
| // Using PopFirst.yes would have made this Date(2010, 9, 10). |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 10)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 18)); |
| |
| range.popFront(); |
| assert(range.front == Date(2010, 9, 26)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| auto funcFwd = everyDuration!Date(dur!"days"(27)); |
| auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!"days"(27)); |
| |
| assert(funcFwd(Date(2009, 12, 25)) == Date(2010, 1, 21)); |
| assert(funcFwd(Date(2009, 12, 26)) == Date(2010, 1, 22)); |
| assert(funcFwd(Date(2009, 12, 27)) == Date(2010, 1, 23)); |
| assert(funcFwd(Date(2009, 12, 28)) == Date(2010, 1, 24)); |
| |
| assert(funcBwd(Date(2010, 1, 21)) == Date(2009, 12, 25)); |
| assert(funcBwd(Date(2010, 1, 22)) == Date(2009, 12, 26)); |
| assert(funcBwd(Date(2010, 1, 23)) == Date(2009, 12, 27)); |
| assert(funcBwd(Date(2010, 1, 24)) == Date(2009, 12, 28)); |
| |
| assert(everyDuration!Date(dur!"hnsecs"(1)) !is null); |
| assert(everyDuration!TimeOfDay(dur!"hnsecs"(1)) !is null); |
| assert(everyDuration!DateTime(dur!"hnsecs"(1)) !is null); |
| assert(everyDuration!SysTime(dur!"hnsecs"(1)) !is null); |
| } |
| |
| |
| /++ |
| Range-generating function. |
| |
| Returns a delegate which returns the next time point which is the given |
| number of years, month, and duration later. |
| |
| The difference between this version of `everyDuration` and the version |
| which just takes a $(REF Duration, core,time) is that this one also takes |
| the number of years and months (along with an `AllowDayOverflow` to |
| indicate whether adding years and months should allow the days to overflow). |
| |
| Note that if iterating forward, `add!"years"()` is called on the given |
| time point, then `add!"months"()`, and finally the duration is added |
| to it. However, if iterating backwards, the duration is added first, then |
| `add!"months"()` is called, and finally `add!"years"()` is called. |
| That way, going backwards generates close to the same time points that |
| iterating forward does, but since adding years and months is not entirely |
| reversible (due to possible day overflow, regardless of whether |
| `AllowDayOverflow.yes` or `AllowDayOverflow.no` is used), it can't be |
| guaranteed that iterating backwards will give the same time points as |
| iterating forward would have (even assuming that the end of the range is a |
| time point which would be returned by the delegate when iterating forward |
| from `begin`). |
| |
| Params: |
| dir = The direction to iterate in. If passing the return |
| value to `fwdRange`, use `Direction.fwd`. If |
| passing it to `bwdRange`, use `Direction.bwd`. |
| years = The number of years to add to the time point passed to |
| the delegate. |
| months = The number of months to add to the time point passed to |
| the delegate. |
| allowOverflow = Whether the days should be allowed to overflow on |
| `begin` and `end`, causing their month to |
| increment. |
| duration = The duration to add to the time point passed to the |
| delegate. |
| +/ |
| TP delegate(scope const TP) everyDuration(TP, Direction dir = Direction.fwd, D) |
| (int years, |
| int months = 0, |
| AllowDayOverflow allowOverflow = AllowDayOverflow.yes, |
| D duration = dur!"days"(0)) nothrow |
| if (isTimePoint!TP && |
| __traits(compiles, TP.init + duration) && |
| __traits(compiles, TP.init.add!"years"(years)) && |
| __traits(compiles, TP.init.add!"months"(months)) && |
| (dir == Direction.fwd || dir == Direction.bwd)) |
| { |
| TP func(scope const TP tp) |
| { |
| static if (dir == Direction.fwd) |
| { |
| TP retval = cast(TP) tp; |
| |
| retval.add!"years"(years, allowOverflow); |
| retval.add!"months"(months, allowOverflow); |
| |
| return retval + duration; |
| } |
| else |
| { |
| TP retval = tp - duration; |
| |
| retval.add!"months"(-months, allowOverflow); |
| retval.add!"years"(-years, allowOverflow); |
| |
| return retval; |
| } |
| } |
| |
| return &func; |
| } |
| |
| /// |
| @system unittest |
| { |
| import core.time : dur; |
| import std.datetime.date : AllowDayOverflow, Date; |
| |
| auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27)); |
| auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2)); |
| auto range = interval.fwdRange(func); |
| |
| // Using PopFirst.yes would have made this Date(2014, 10, 12). |
| assert(range.front == Date(2010, 9, 2)); |
| |
| range.popFront(); |
| assert(range.front == Date(2014, 10, 4)); |
| |
| range.popFront(); |
| assert(range.front == Date(2018, 11, 6)); |
| |
| range.popFront(); |
| assert(range.front == Date(2022, 12, 8)); |
| |
| range.popFront(); |
| assert(range.empty); |
| } |
| |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| { |
| auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"days"(3)); |
| auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); |
| |
| assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); |
| assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); |
| assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); |
| assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); |
| assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 4)); |
| |
| assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); |
| assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); |
| assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); |
| assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); |
| assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); |
| } |
| |
| { |
| auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!"days"(3)); |
| auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3)); |
| |
| assert(funcFwd(Date(2009, 12, 25)) == Date(2011, 2, 28)); |
| assert(funcFwd(Date(2009, 12, 26)) == Date(2011, 3, 1)); |
| assert(funcFwd(Date(2009, 12, 27)) == Date(2011, 3, 2)); |
| assert(funcFwd(Date(2009, 12, 28)) == Date(2011, 3, 3)); |
| assert(funcFwd(Date(2009, 12, 29)) == Date(2011, 3, 3)); |
| |
| assert(funcBwd(Date(2011, 2, 28)) == Date(2009, 12, 25)); |
| assert(funcBwd(Date(2011, 3, 1)) == Date(2009, 12, 26)); |
| assert(funcBwd(Date(2011, 3, 2)) == Date(2009, 12, 27)); |
| assert(funcBwd(Date(2011, 3, 3)) == Date(2009, 12, 28)); |
| assert(funcBwd(Date(2011, 3, 4)) == Date(2010, 1, 1)); |
| } |
| |
| assert(everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); |
| static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)))); |
| assert(everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); |
| assert(everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1)) !is null); |
| } |
| |
| |
| /++ |
| A range over an $(LREF Interval). |
| |
| `IntervalRange` is only ever constructed by $(LREF Interval). However, when |
| it is constructed, it is given a function, `func`, which is used to |
| generate the time points which are iterated over. `func` takes a time |
| point and returns a time point of the same type. For instance, |
| to iterate over all of the days in |
| the interval `Interval!Date`, pass a function to $(LREF Interval)'s |
| `fwdRange` where that function took a $(REF Date,std,datetime,date) and |
| returned a $(REF Date,std,datetime,date) which was one day later. That |
| function would then be used by `IntervalRange`'s `popFront` to iterate |
| over the $(REF Date,std,datetime,date)s in the interval. |
| |
| If $(D dir == Direction.fwd), then a range iterates forward in time, whereas |
| if $(D dir == Direction.bwd), then it iterates backwards in time. So, if |
| $(D dir == Direction.fwd) then $(D front == interval.begin), whereas if |
| $(D dir == Direction.bwd) then $(D front == interval.end). `func` must |
| generate a time point going in the proper direction of iteration, or a |
| $(REF DateTimeException,std,datetime,date) will be thrown. So, to iterate |
| forward in time, the time point that `func` generates must be later in |
| time than the one passed to it. If it's either identical or earlier in time, |
| then a $(REF DateTimeException,std,datetime,date) will be thrown. To |
| iterate backwards, then the generated time point must be before the time |
| point which was passed in. |
| |
| If the generated time point is ever passed the edge of the range in the |
| proper direction, then the edge of that range will be used instead. So, if |
| iterating forward, and the generated time point is past the interval's |
| `end`, then `front` becomes `end`. If iterating backwards, and the |
| generated time point is before `begin`, then `front` becomes |
| `begin`. In either case, the range would then be empty. |
| |
| Also note that while normally the `begin` of an interval is included in |
| it and its `end` is excluded from it, if $(D dir == Direction.bwd), then |
| `begin` is treated as excluded and `end` is treated as included. This |
| allows for the same behavior in both directions. This works because none of |
| $(LREF Interval)'s functions which care about whether `begin` or `end` |
| is included or excluded are ever called by `IntervalRange`. `interval` |
| returns a normal interval, regardless of whether $(D dir == Direction.fwd) |
| or if $(D dir == Direction.bwd), so any $(LREF Interval) functions which are |
| called on it which care about whether `begin` or `end` are included or |
| excluded will treat `begin` as included and `end` as excluded. |
| +/ |
| struct IntervalRange(TP, Direction dir) |
| if (isTimePoint!TP && dir != Direction.both) |
| { |
| public: |
| |
| /++ |
| Params: |
| rhs = The `IntervalRange` to assign to this one. |
| +/ |
| ref IntervalRange opAssign(ref IntervalRange rhs) pure nothrow |
| { |
| _interval = rhs._interval; |
| _func = rhs._func; |
| return this; |
| } |
| |
| |
| /++ Ditto +/ |
| ref IntervalRange opAssign(IntervalRange rhs) pure nothrow |
| { |
| return this = rhs; |
| } |
| |
| |
| /++ |
| Whether this `IntervalRange` is empty. |
| +/ |
| @property bool empty() const pure nothrow |
| { |
| return _interval.empty; |
| } |
| |
| |
| /++ |
| The first time point in the range. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the range is empty. |
| +/ |
| @property TP front() const pure |
| { |
| _enforceNotEmpty(); |
| |
| static if (dir == Direction.fwd) |
| return _interval.begin; |
| else |
| return _interval.end; |
| } |
| |
| |
| /++ |
| Pops `front` from the range, using `func` to generate the next |
| time point in the range. If the generated time point is beyond the edge |
| of the range, then `front` is set to that edge, and the range is then |
| empty. So, if iterating forwards, and the generated time point is |
| greater than the interval's `end`, then `front` is set to |
| `end`. If iterating backwards, and the generated time point is less |
| than the interval's `begin`, then `front` is set to `begin`. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the range is empty |
| or if the generated time point is in the wrong direction (i.e. if |
| iterating forward and the generated time point is before `front`, |
| or if iterating backwards and the generated time point is after |
| `front`). |
| +/ |
| void popFront() |
| { |
| _enforceNotEmpty(); |
| |
| static if (dir == Direction.fwd) |
| { |
| auto begin = _func(_interval.begin); |
| |
| if (begin > _interval.end) |
| begin = _interval.end; |
| |
| _enforceCorrectDirection(begin); |
| |
| _interval.begin = begin; |
| } |
| else |
| { |
| auto end = _func(_interval.end); |
| |
| if (end < _interval.begin) |
| end = _interval.begin; |
| |
| _enforceCorrectDirection(end); |
| |
| _interval.end = end; |
| } |
| } |
| |
| |
| /++ |
| Returns a copy of `this`. |
| +/ |
| @property IntervalRange save() pure nothrow |
| { |
| return this; |
| } |
| |
| |
| /++ |
| The interval that this `IntervalRange` currently covers. |
| +/ |
| @property Interval!TP interval() const pure nothrow |
| { |
| return cast(Interval!TP)_interval; |
| } |
| |
| |
| /++ |
| The function used to generate the next time point in the range. |
| +/ |
| TP delegate(scope const TP) func() pure nothrow @property |
| { |
| return _func; |
| } |
| |
| |
| /++ |
| The `Direction` that this range iterates in. |
| +/ |
| @property Direction direction() const pure nothrow |
| { |
| return dir; |
| } |
| |
| |
| private: |
| |
| /+ |
| Params: |
| interval = The interval that this range covers. |
| func = The function used to generate the time points which are |
| iterated over. |
| +/ |
| this(const Interval!TP interval, TP delegate(scope const TP) func) pure nothrow @safe |
| { |
| _func = func; |
| _interval = interval; |
| } |
| |
| |
| /+ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if this interval is |
| empty. |
| +/ |
| void _enforceNotEmpty(size_t line = __LINE__) const pure |
| { |
| if (empty) |
| throw new DateTimeException("Invalid operation for an empty IntervalRange.", __FILE__, line); |
| } |
| |
| |
| /+ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is |
| in the wrong direction. |
| +/ |
| void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const |
| { |
| import std.format : format; |
| |
| static if (dir == Direction.fwd) |
| { |
| enforce(newTP > _interval._begin, |
| new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", |
| interval._begin, |
| newTP), |
| __FILE__, |
| line)); |
| } |
| else |
| { |
| enforce(newTP < _interval._end, |
| new DateTimeException(format("Generated time point is after previous end: prev [%s] new [%s]", |
| interval._end, |
| newTP), |
| __FILE__, |
| line)); |
| } |
| } |
| |
| |
| Interval!TP _interval; |
| TP delegate(scope const TP) _func; |
| } |
| |
| //Test that IntervalRange satisfies the range predicates that it's supposed to satisfy. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| import std.range.primitives; |
| |
| static assert(isInputRange!(IntervalRange!(Date, Direction.fwd))); |
| static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd))); |
| |
| // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 |
| // static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date)); |
| |
| static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!hasLength!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd))); |
| static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd))); |
| |
| static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date)); |
| static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay)); |
| static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime)); |
| static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime)); |
| } |
| |
| //Test construction of IntervalRange. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| { |
| Date dateFunc(scope const Date date) { return date; } |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc); |
| } |
| |
| { |
| TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } |
| auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0)); |
| auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc); |
| } |
| |
| { |
| DateTime dtFunc(scope const DateTime dt) { return dt; } |
| auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0)); |
| auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc); |
| } |
| |
| { |
| SysTime stFunc(scope const SysTime st) { return SysTime.init; } |
| auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), |
| SysTime(DateTime(2012, 1, 7, 14, 0, 0))); |
| auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc); |
| } |
| } |
| |
| //Test IntervalRange's empty(). |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| |
| assert(!range.empty); |
| range.popFront(); |
| assert(range.empty); |
| |
| const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| assert(!cRange.empty); |
| |
| //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if |
| //empty works with it. However, since an immutable range is pretty useless, it's no great loss. |
| } |
| |
| //bwd |
| { |
| auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| |
| assert(!range.empty); |
| range.popFront(); |
| assert(range.empty); |
| |
| const cRange = Interval!Date( Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| assert(!cRange.empty); |
| |
| //Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if |
| //empty works with it. However, since an immutable range is pretty useless, it's no great loss. |
| } |
| } |
| |
| //Test IntervalRange's front. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( |
| everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| assertThrown!DateTimeException( |
| (scope const IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange)); |
| |
| auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); |
| assert(range.front == Date(2010, 7, 4)); |
| |
| auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( |
| everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| assert(poppedRange.front == Date(2010, 7, 7)); |
| |
| const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| assert(cRange.front != Date.init); |
| } |
| |
| //bwd |
| { |
| auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| assertThrown!DateTimeException( |
| (scope const IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange)); |
| |
| auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); |
| assert(range.front == Date(2012, 1, 7)); |
| |
| auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| assert(poppedRange.front == Date(2012, 1, 4)); |
| |
| const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| assert(cRange.front != Date.init); |
| } |
| } |
| |
| //Test IntervalRange's popFront(). |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.range.primitives : walkLength; |
| |
| //fwd |
| { |
| auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange( |
| everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange)); |
| |
| auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange( |
| everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| auto expected = range.front; |
| |
| foreach (date; range) |
| { |
| assert(date == expected); |
| expected += dur!"days"(7); |
| } |
| |
| assert(walkLength(range) == 79); |
| |
| const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| assert(cRange.front != Date.init); |
| } |
| |
| //bwd |
| { |
| auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange)); |
| |
| auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| auto expected = range.front; |
| |
| foreach (date; range) |
| { |
| assert(date == expected); |
| expected += dur!"days"(-7); |
| } |
| |
| assert(walkLength(range) == 79); |
| |
| const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| static assert(!__traits(compiles, cRange.popFront())); |
| } |
| } |
| |
| //Test IntervalRange's save. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.save == range); |
| } |
| |
| //bwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.save == range); |
| } |
| } |
| |
| //Test IntervalRange's interval. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.interval == interval); |
| |
| const cRange = range; |
| assert(!cRange.interval.empty); |
| } |
| |
| //bwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.interval == interval); |
| |
| const cRange = range; |
| assert(!cRange.interval.empty); |
| } |
| } |
| |
| //Test IntervalRange's func. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.func == func); |
| } |
| |
| //bwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.func == func); |
| } |
| } |
| |
| //Test IntervalRange's direction. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| //fwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.direction == Direction.fwd); |
| |
| const cRange = range; |
| assert(cRange.direction == Direction.fwd); |
| } |
| |
| //bwd |
| { |
| auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.direction == Direction.bwd); |
| |
| const cRange = range; |
| assert(cRange.direction == Direction.bwd); |
| } |
| } |
| |
| |
| /++ |
| A range over a `PosInfInterval`. It is an infinite range. |
| |
| `PosInfIntervalRange` is only ever constructed by `PosInfInterval`. |
| However, when it is constructed, it is given a function, `func`, which |
| is used to generate the time points which are iterated over. `func` |
| takes a time point and returns a time point of the same type. For |
| instance, to iterate |
| over all of the days in the interval `PosInfInterval!Date`, pass a |
| function to `PosInfInterval`'s `fwdRange` where that function took a |
| $(REF Date,std,datetime,date) and returned a $(REF Date,std,datetime,date) |
| which was one day later. That function would then be used by |
| `PosInfIntervalRange`'s `popFront` to iterate over the |
| $(REF Date,std,datetime,date)s in the interval - though obviously, since the |
| range is infinite, use a function such as `std.range.take` with it rather |
| than iterating over $(I all) of the dates. |
| |
| As the interval goes to positive infinity, the range is always iterated over |
| forwards, never backwards. `func` must generate a time point going in |
| the proper direction of iteration, or a |
| $(REF DateTimeException,std,datetime,date) will be thrown. So, the time |
| points that `func` generates must be later in time than the one passed to |
| it. If it's either identical or earlier in time, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. |
| +/ |
| struct PosInfIntervalRange(TP) |
| if (isTimePoint!TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| rhs = The `PosInfIntervalRange` to assign to this one. |
| +/ |
| ref PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow |
| { |
| _interval = rhs._interval; |
| _func = rhs._func; |
| return this; |
| } |
| |
| |
| /++ Ditto +/ |
| ref PosInfIntervalRange opAssign(PosInfIntervalRange rhs) pure nothrow |
| { |
| return this = rhs; |
| } |
| |
| |
| /++ |
| This is an infinite range, so it is never empty. |
| +/ |
| enum bool empty = false; |
| |
| |
| /++ |
| The first time point in the range. |
| +/ |
| @property TP front() const pure nothrow |
| { |
| return _interval.begin; |
| } |
| |
| |
| /++ |
| Pops `front` from the range, using `func` to generate the next |
| time point in the range. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the generated time |
| point is less than `front`. |
| +/ |
| void popFront() |
| { |
| auto begin = _func(_interval.begin); |
| _enforceCorrectDirection(begin); |
| _interval.begin = begin; |
| } |
| |
| |
| /++ |
| Returns a copy of `this`. |
| +/ |
| @property PosInfIntervalRange save() pure nothrow |
| { |
| return this; |
| } |
| |
| |
| /++ |
| The interval that this range currently covers. |
| +/ |
| @property PosInfInterval!TP interval() const pure nothrow |
| { |
| return cast(PosInfInterval!TP)_interval; |
| } |
| |
| |
| /++ |
| The function used to generate the next time point in the range. |
| +/ |
| TP delegate(scope const TP) func() pure nothrow @property |
| { |
| return _func; |
| } |
| |
| |
| private: |
| |
| /+ |
| Params: |
| interval = The interval that this range covers. |
| func = The function used to generate the time points which are |
| iterated over. |
| +/ |
| this(const PosInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow |
| { |
| _func = func; |
| _interval = interval; |
| } |
| |
| |
| /+ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is |
| in the wrong direction. |
| +/ |
| void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const |
| { |
| import std.format : format; |
| |
| enforce(newTP > _interval._begin, |
| new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]", |
| interval._begin, |
| newTP), |
| __FILE__, |
| line)); |
| } |
| |
| |
| PosInfInterval!TP _interval; |
| TP delegate(scope const TP) _func; |
| } |
| |
| //Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| import std.range.primitives; |
| |
| static assert(isInputRange!(PosInfIntervalRange!Date)); |
| static assert(isForwardRange!(PosInfIntervalRange!Date)); |
| static assert(isInfinite!(PosInfIntervalRange!Date)); |
| |
| // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 |
| // static assert(!isOutputRange!(PosInfIntervalRange!Date, Date)); |
| static assert(!isBidirectionalRange!(PosInfIntervalRange!Date)); |
| static assert(!isRandomAccessRange!(PosInfIntervalRange!Date)); |
| static assert(!hasSwappableElements!(PosInfIntervalRange!Date)); |
| static assert(!hasAssignableElements!(PosInfIntervalRange!Date)); |
| static assert(!hasLength!(PosInfIntervalRange!Date)); |
| static assert(!hasSlicing!(PosInfIntervalRange!Date)); |
| |
| static assert(is(ElementType!(PosInfIntervalRange!Date) == Date)); |
| static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay)); |
| static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime)); |
| static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime)); |
| } |
| |
| //Test construction of PosInfIntervalRange. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| { |
| Date dateFunc(scope const Date date) { return date; } |
| auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc); |
| } |
| |
| { |
| TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } |
| auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7)); |
| auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc); |
| } |
| |
| { |
| DateTime dtFunc(scope const DateTime dt) { return dt; } |
| auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7)); |
| auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc); |
| } |
| |
| { |
| SysTime stFunc(scope const SysTime st) { return SysTime.init; } |
| auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7))); |
| auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc); |
| } |
| } |
| |
| //Test PosInfIntervalRange's front. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed)); |
| assert(range.front == Date(2010, 7, 4)); |
| |
| auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| assert(poppedRange.front == Date(2010, 7, 7)); |
| |
| const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| assert(cRange.front != Date.init); |
| } |
| |
| //Test PosInfIntervalRange's popFront(). |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.range : take; |
| |
| auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes); |
| auto expected = range.front; |
| |
| foreach (date; take(range, 79)) |
| { |
| assert(date == expected); |
| expected += dur!"days"(7); |
| } |
| |
| const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)); |
| static assert(!__traits(compiles, cRange.popFront())); |
| } |
| |
| //Test PosInfIntervalRange's save. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.save == range); |
| } |
| |
| //Test PosInfIntervalRange's interval. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.interval == interval); |
| |
| const cRange = range; |
| assert(!cRange.interval.empty); |
| } |
| |
| //Test PosInfIntervalRange's func. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = PosInfInterval!Date(Date(2010, 7, 4)); |
| auto func = everyDayOfWeek!Date(DayOfWeek.fri); |
| auto range = interval.fwdRange(func); |
| |
| assert(range.func == func); |
| } |
| |
| |
| /++ |
| A range over a `NegInfInterval`. It is an infinite range. |
| |
| `NegInfIntervalRange` is only ever constructed by `NegInfInterval`. |
| However, when it is constructed, it is given a function, `func`, which |
| is used to generate the time points which are iterated over. `func` |
| takes a time point and returns a time point of the same type. For |
| instance, to iterate over all of the days in the interval |
| `NegInfInterval!Date`, pass a function to `NegInfInterval`'s |
| `bwdRange` where that function took a $(REF Date,std,datetime,date) and |
| returned a $(REF Date,std,datetime,date) which was one day earlier. That |
| function would then be used by `NegInfIntervalRange`'s `popFront` to |
| iterate over the $(REF Date,std,datetime,date)s in the interval - though |
| obviously, since the range is infinite, use a function such as |
| `std.range.take` with it rather than iterating over $(I all) of the dates. |
| |
| As the interval goes to negative infinity, the range is always iterated over |
| backwards, never forwards. `func` must generate a time point going in |
| the proper direction of iteration, or a |
| $(REF DateTimeException,std,datetime,date) will be thrown. So, the time |
| points that `func` generates must be earlier in time than the one passed |
| to it. If it's either identical or later in time, then a |
| $(REF DateTimeException,std,datetime,date) will be thrown. |
| |
| Also note that while normally the `end` of an interval is excluded from |
| it, `NegInfIntervalRange` treats it as if it were included. This allows |
| for the same behavior as with `PosInfIntervalRange`. This works |
| because none of `NegInfInterval`'s functions which care about whether |
| `end` is included or excluded are ever called by |
| `NegInfIntervalRange`. `interval` returns a normal interval, so any |
| `NegInfInterval` functions which are called on it which care about |
| whether `end` is included or excluded will treat `end` as excluded. |
| +/ |
| struct NegInfIntervalRange(TP) |
| if (isTimePoint!TP) |
| { |
| public: |
| |
| /++ |
| Params: |
| rhs = The `NegInfIntervalRange` to assign to this one. |
| +/ |
| ref NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow |
| { |
| _interval = rhs._interval; |
| _func = rhs._func; |
| |
| return this; |
| } |
| |
| |
| /++ Ditto +/ |
| ref NegInfIntervalRange opAssign(NegInfIntervalRange rhs) pure nothrow |
| { |
| return this = rhs; |
| } |
| |
| |
| /++ |
| This is an infinite range, so it is never empty. |
| +/ |
| enum bool empty = false; |
| |
| |
| /++ |
| The first time point in the range. |
| +/ |
| @property TP front() const pure nothrow |
| { |
| return _interval.end; |
| } |
| |
| |
| /++ |
| Pops `front` from the range, using `func` to generate the next |
| time point in the range. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the generated time |
| point is greater than `front`. |
| +/ |
| void popFront() |
| { |
| auto end = _func(_interval.end); |
| _enforceCorrectDirection(end); |
| _interval.end = end; |
| } |
| |
| |
| /++ |
| Returns a copy of `this`. |
| +/ |
| @property NegInfIntervalRange save() pure nothrow |
| { |
| return this; |
| } |
| |
| |
| /++ |
| The interval that this range currently covers. |
| +/ |
| @property NegInfInterval!TP interval() const pure nothrow |
| { |
| return cast(NegInfInterval!TP)_interval; |
| } |
| |
| |
| /++ |
| The function used to generate the next time point in the range. |
| +/ |
| TP delegate(scope const TP) func() pure nothrow @property |
| { |
| return _func; |
| } |
| |
| |
| private: |
| |
| /+ |
| Params: |
| interval = The interval that this range covers. |
| func = The function used to generate the time points which are |
| iterated over. |
| +/ |
| this(const NegInfInterval!TP interval, TP delegate(scope const TP) func) pure nothrow |
| { |
| _func = func; |
| _interval = interval; |
| } |
| |
| |
| /+ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D_PARAM newTP) is |
| in the wrong direction. |
| +/ |
| void _enforceCorrectDirection(scope const TP newTP, size_t line = __LINE__) const |
| { |
| import std.format : format; |
| |
| enforce(newTP < _interval._end, |
| new DateTimeException(format("Generated time point is before previous end: prev [%s] new [%s]", |
| interval._end, |
| newTP), |
| __FILE__, |
| line)); |
| } |
| |
| |
| NegInfInterval!TP _interval; |
| TP delegate(scope const TP) _func; |
| } |
| |
| //Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.range.primitives; |
| |
| static assert(isInputRange!(NegInfIntervalRange!Date)); |
| static assert(isForwardRange!(NegInfIntervalRange!Date)); |
| static assert(isInfinite!(NegInfIntervalRange!Date)); |
| |
| // Commented out due to bug https://issues.dlang.org/show_bug.cgi?id=4895 |
| // static assert(!isOutputRange!(NegInfIntervalRange!Date, Date)); |
| static assert(!isBidirectionalRange!(NegInfIntervalRange!Date)); |
| static assert(!isRandomAccessRange!(NegInfIntervalRange!Date)); |
| static assert(!hasSwappableElements!(NegInfIntervalRange!Date)); |
| static assert(!hasAssignableElements!(NegInfIntervalRange!Date)); |
| static assert(!hasLength!(NegInfIntervalRange!Date)); |
| static assert(!hasSlicing!(NegInfIntervalRange!Date)); |
| |
| static assert(is(ElementType!(NegInfIntervalRange!Date) == Date)); |
| static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay)); |
| static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime)); |
| } |
| |
| //Test construction of NegInfIntervalRange. |
| @safe unittest |
| { |
| import std.datetime.date; |
| import std.datetime.systime; |
| |
| { |
| Date dateFunc(scope const Date date) { return date; } |
| auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7)); |
| auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc); |
| } |
| |
| { |
| TimeOfDay todFunc(scope const TimeOfDay tod) { return tod; } |
| auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0)); |
| auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc); |
| } |
| |
| { |
| DateTime dtFunc(scope const DateTime dt) { return dt; } |
| auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0)); |
| auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc); |
| } |
| |
| { |
| SysTime stFunc(scope const SysTime st) { return SysTime.init; } |
| auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0))); |
| auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc); |
| } |
| } |
| |
| //Test NegInfIntervalRange's front. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed)); |
| assert(range.front == Date(2012, 1, 7)); |
| |
| auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| assert(poppedRange.front == Date(2012, 1, 4)); |
| |
| const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| assert(cRange.front != Date.init); |
| } |
| |
| //Test NegInfIntervalRange's popFront(). |
| @system unittest |
| { |
| import std.datetime.date; |
| import std.range : take; |
| |
| auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange( |
| everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes); |
| auto expected = range.front; |
| |
| foreach (date; take(range, 79)) |
| { |
| assert(date == expected); |
| expected += dur!"days"(-7); |
| } |
| |
| const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)); |
| static assert(!__traits(compiles, cRange.popFront())); |
| } |
| |
| //Test NegInfIntervalRange's save. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.save == range); |
| } |
| |
| //Test NegInfIntervalRange's interval. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.interval == interval); |
| |
| const cRange = range; |
| assert(!cRange.interval.empty); |
| } |
| |
| //Test NegInfIntervalRange's func. |
| @system unittest |
| { |
| import std.datetime.date; |
| |
| auto interval = NegInfInterval!Date(Date(2012, 1, 7)); |
| auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri); |
| auto range = interval.bwdRange(func); |
| |
| assert(range.func == func); |
| } |