Let Interval inherit from Range

- Remove 1 level of indirection
- Remove public field Interval::range (instead use interval directly)
This commit is contained in:
Thomas Lauf 2018-06-13 23:01:35 +02:00
parent 0d33700336
commit 9dd106116c
30 changed files with 289 additions and 280 deletions

View file

@ -117,7 +117,7 @@ Interval getFilter (const CLI& cli)
if (args.size () == 1 &&
args[0] == "<date>")
{
filter.range = {Datetime (start), 0};
filter.setRange ({Datetime (start), 0});
}
// from <date>
@ -125,7 +125,7 @@ Interval getFilter (const CLI& cli)
args[0] == "from" &&
args[1] == "<date>")
{
filter.range = {Datetime (start), 0};
filter.setRange ({Datetime (start), 0});
}
// <date> to/- <date>
@ -134,7 +134,7 @@ Interval getFilter (const CLI& cli)
(args[1] == "to" || args[1] == "-") &&
args[2] == "<date>")
{
filter.range = {Datetime (start), Datetime (end)};
filter.setRange ({Datetime (start), Datetime (end)});
}
// from <date> to/- <date>
@ -144,7 +144,7 @@ Interval getFilter (const CLI& cli)
(args[2] == "to" || args[2] == "-") &&
args[3] == "<date>")
{
filter.range = {Datetime (start), Datetime (end)};
filter.setRange ({Datetime (start), Datetime (end)});
}
// <date> for <duration>
@ -153,7 +153,7 @@ Interval getFilter (const CLI& cli)
args[1] == "for" &&
args[2] == "<duration>")
{
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
}
// from <date> for <duration>
@ -163,7 +163,7 @@ Interval getFilter (const CLI& cli)
args[2] == "for" &&
args[3] == "<duration>")
{
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
}
// <duration> before <date>
@ -172,7 +172,7 @@ Interval getFilter (const CLI& cli)
args[1] == "before" &&
args[2] == "<date>")
{
filter.range = {Datetime (start) - Duration (duration).toTime_t (), Datetime (start)};
filter.setRange ({Datetime (start) - Duration (duration).toTime_t (), Datetime (start)});
}
// <duration> after <date>
@ -181,7 +181,7 @@ Interval getFilter (const CLI& cli)
args[1] == "after" &&
args[2] == "<date>")
{
filter.range = {Datetime (start), Datetime (start) + Duration (duration).toTime_t ()};
filter.setRange ({Datetime (start), Datetime (start) + Duration (duration).toTime_t ()});
}
// <duration> ago
@ -189,7 +189,7 @@ Interval getFilter (const CLI& cli)
args[0] == "<duration>" &&
args[1] == "ago")
{
filter.range = {now - Duration (duration).toTime_t (), 0};
filter.setRange ({now - Duration (duration).toTime_t (), 0});
}
// for <duration>
@ -197,14 +197,14 @@ Interval getFilter (const CLI& cli)
args[0] == "for" &&
args[1] == "<duration>")
{
filter.range = {now - Duration (duration).toTime_t (), now};
filter.setRange ({now - Duration (duration).toTime_t (), now});
}
// <duration>
else if (args.size () == 1 &&
args[0] == "<duration>")
{
filter.range = {now - Duration (duration).toTime_t (), now};
filter.setRange ({now - Duration (duration).toTime_t (), now});
}
// Unrecognized date range construct.
@ -213,10 +213,10 @@ Interval getFilter (const CLI& cli)
throw std::string ("Unrecognized date range: '") + join (" ", args) + "'.";
}
if (filter.range.start > now)
if (filter.start > now)
throw std::string ("Time tracking cannot be set in the future.");
if (filter.range.end != 0 && filter.range.start > filter.range.end)
if (filter.end != 0 && filter.start > filter.end)
throw std::string ("The end of a date range must be after the start.");
return filter;
@ -359,7 +359,8 @@ std::vector <Interval> subset (
{
std::vector <Interval> all;
for (auto& interval : intervals) {
if (range.intersects (interval.range)) {
if (range.intersects (interval))
{
all.push_back (interval);
}
}
@ -376,29 +377,29 @@ std::vector <Interval> flatten (
std::vector <Range> enclosed;
for (auto& e : exclusions)
if (interval.range.encloses (e))
if (interval.encloses (e))
enclosed.push_back (e);
Datetime now;
for (auto& result : subtractRanges ({interval.range}, enclosed))
for (auto& result : subtractRanges ({interval}, enclosed))
{
Interval chunk {interval};
chunk.range = result;
chunk.setRange (result);
// Only historical data is included.
if (chunk.range.start <= now)
if (chunk.start <= now)
{
// Closed chunk ranges in the future need to be adjusted.
if (! chunk.range.is_open () &&
chunk.range.end > now)
if (! chunk.is_open () &&
chunk.end > now)
{
// If the interval is open, so must be chunk.
if (interval.range.is_open ())
chunk.range.end = {0};
if (interval.is_open ())
chunk.end = {0};
// Otherwise truncate to now.
else
chunk.range.end = now;
chunk.end = now;
}
all.push_back (chunk);
@ -496,17 +497,17 @@ Range outerRange (const std::vector <Interval>& intervals)
Range outer;
for (auto& interval : intervals)
{
if (interval.range.start < outer.start || outer.start.toEpoch () == 0)
outer.start = interval.range.start;
if (interval.start < outer.start || outer.start.toEpoch () == 0)
outer.start = interval.start;
// Deliberately mixed start/end.
if (interval.range.start > outer.end)
outer.end = interval.range.start;
if (interval.start > outer.end)
outer.end = interval.start;
if (interval.range.end > outer.end)
outer.end = interval.range.end;
if (interval.end > outer.end)
outer.end = interval.end;
if (! interval.range.is_ended ())
if (! interval.is_ended ())
outer.end = Datetime ();
}
@ -517,10 +518,10 @@ Range outerRange (const std::vector <Interval>& intervals)
// An interval matches a filter interval if the start/end overlaps, and all
// filter interval tags are found in the interval.
//
// [1] interval.range.end.toEpoch () == 0
// [2] interval.range.end > filter.range.start
// [3] filter.range.end.toEpoch () == 0
// [4] interval.range.start < filter.range.end
// [1] interval.end.toEpoch () == 0
// [2] interval.end > filter.start
// [3] filter.end.toEpoch () == 0
// [4] interval.start < filter.end
//
// Match: (1 || 2) && (3 || 4)
@ -552,9 +553,9 @@ Range outerRange (const std::vector <Interval>& intervals)
//
bool matchesFilter (const Interval& interval, const Interval& filter)
{
if ((filter.range.start.toEpoch () == 0 &&
filter.range.end.toEpoch () == 0
) || interval.range.intersects (filter.range))
if ((filter.start.toEpoch () == 0 &&
filter.end.toEpoch () == 0
) || interval.intersects (filter))
{
for (auto& tag : filter.tags ())
if (! interval.hasTag (tag))
@ -567,7 +568,7 @@ bool matchesFilter (const Interval& interval, const Interval& filter)
}
////////////////////////////////////////////////////////////////////////////////
// Take an interval and clip it to the range.
// Take an interval and clip it to the
Interval clip (const Interval& interval, const Range& range)
{
if (! range.is_started () ||
@ -575,13 +576,13 @@ Interval clip (const Interval& interval, const Range& range)
return interval;
Interval clipped {interval};
if (clipped.range.start.toEpoch () &&
clipped.range.start < range.start)
clipped.range.start = range.start;
if (clipped.start.toEpoch () &&
clipped.start < range.start)
clipped.start = range.start;
if (clipped.range.end.toEpoch () &&
clipped.range.end > range.end)
clipped.range.end = range.end;
if (clipped.end.toEpoch () &&
clipped.end > range.end)
clipped.end = range.end;
return clipped;
}
@ -600,16 +601,16 @@ std::vector <Interval> getTracked (
// [earliest start, infinity)
//
// Avoid assigning a zero-width range - leave it unstarted instead.
if (! filter.range.is_started ())
if (! filter.is_started ())
{
auto outer = outerRange (inclusions);
if (outer.total ())
filter.range = outer;
filter.setRange (outer);
// Use an infinite range instead of the last end date; this prevents
// issues when there is an empty range [q, q) at the end of a filter
// [p, q), in which case there is no overlap or intersection.
filter.range.end = 0;
filter.end = 0;
}
std::vector <Interval> intervals = inclusions;
@ -618,11 +619,11 @@ std::vector <Interval> getTracked (
{
auto latest = inclusions.back ();
if (latest.range.is_open ())
if (latest.is_open ())
{
// Get the set of expanded exclusions that overlap the range defined by the
// timeline.
auto exclusions = getAllExclusions (rules, filter.range);
auto exclusions = getAllExclusions (rules, filter);
if (! exclusions.empty ())
{
intervals.pop_back ();
@ -630,7 +631,7 @@ std::vector <Interval> getTracked (
for (auto& interval : flatten (latest, exclusions))
{
if (latest.synthetic ||
latest.range != interval.range)
latest != interval)
interval.synthetic = true;
intervals.push_back (interval);
@ -656,9 +657,9 @@ std::vector <Range> getUntracked (
{
std::vector <Range> inclusion_ranges;
for (auto& i : subset (filter, getAllInclusions (database)))
inclusion_ranges.push_back (i.range);
inclusion_ranges.push_back (i);
auto available = subtractRanges ({filter.range}, getAllExclusions (rules, filter.range));
auto available = subtractRanges ({filter}, getAllExclusions (rules, filter));
auto untracked = subtractRanges (available, inclusion_ranges);
debug (format ("Loaded {1} untracked ranges", untracked.size ()));
return untracked;