Range: Renamed Daterange to Range

This commit is contained in:
Paul Beckingham 2016-04-23 08:47:08 -04:00
parent ce29626777
commit 4176bf23d4
20 changed files with 319 additions and 319 deletions

View file

@ -9,12 +9,12 @@ set (timew_SRCS CLI.cpp CLI.h
Composite.cpp Composite.h Composite.cpp Composite.h
Database.cpp Database.h Database.cpp Database.h
Datafile.cpp Datafile.h Datafile.cpp Datafile.h
Daterange.cpp Daterange.h
Exclusion.cpp Exclusion.h Exclusion.cpp Exclusion.h
Extensions.cpp Extensions.h Extensions.cpp Extensions.h
Interval.cpp Interval.h Interval.cpp Interval.h
Lexer.cpp Lexer.h Lexer.cpp Lexer.h
Palette.cpp Palette.h Palette.cpp Palette.h
Range.cpp Range.h
Rules.cpp Rules.h Rules.cpp Rules.h
Timeline.cpp Timeline.h Timeline.cpp Timeline.h
init.cpp init.cpp

View file

@ -214,9 +214,9 @@ unsigned int Database::getDatafile (int year, int month)
// 2016-03-01 to 2016-04-01 // 2016-03-01 to 2016-04-01
// 2016-04-01 to 2016-05-15 // 2016-04-01 to 2016-05-15
// //
std::vector <Daterange> Database::segmentRange (const Daterange& range) std::vector <Range> Database::segmentRange (const Range& range)
{ {
std::vector <Daterange> segments; std::vector <Range> segments;
auto start_y = range.start ().year (); auto start_y = range.start ().year ();
auto start_m = range.start ().month (); auto start_m = range.start ().month ();
@ -244,7 +244,7 @@ std::vector <Daterange> Database::segmentRange (const Daterange& range)
// Capture date after incrementing month. // Capture date after incrementing month.
Datetime segmentEnd (start_m, 1, start_y); Datetime segmentEnd (start_m, 1, start_y);
segments.push_back (Daterange (segmentStart, segmentEnd)); segments.push_back (Range (segmentStart, segmentEnd));
} }
return segments; return segments;

View file

@ -29,7 +29,7 @@
#include <Datafile.h> #include <Datafile.h>
#include <Interval.h> #include <Interval.h>
#include <Daterange.h> #include <Range.h>
#include <vector> #include <vector>
#include <string> #include <string>
@ -54,7 +54,7 @@ public:
private: private:
unsigned int getDatafile (int, int); unsigned int getDatafile (int, int);
std::vector <Daterange> segmentRange (const Daterange&); std::vector <Range> segmentRange (const Range&);
void initializeDatafiles (); void initializeDatafiles ();
void validateAddition (const Interval&) const; void validateAddition (const Interval&) const;

View file

@ -50,7 +50,7 @@ void Datafile::initialize (const std::string& name)
month = 1; month = 1;
} }
Datetime end (month, 1, year, 0, 0, 0); Datetime end (month, 1, year, 0, 0, 0);
_range = Daterange (start, end); _range = Range (start, end);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -28,7 +28,7 @@
#define INCLUDED_DATAFILE #define INCLUDED_DATAFILE
#include <Interval.h> #include <Interval.h>
#include <Daterange.h> #include <Range.h>
#include <FS.h> #include <FS.h>
#include <vector> #include <vector>
#include <string> #include <string>
@ -59,7 +59,7 @@ private:
std::vector <std::string> _lines {}; std::vector <std::string> _lines {};
bool _lines_loaded {false}; bool _lines_loaded {false};
std::vector <std::string> _exclusions {}; std::vector <std::string> _exclusions {};
Daterange _range {}; Range _range {};
}; };
#endif #endif

View file

@ -93,9 +93,9 @@ std::vector <std::string> Exclusion::tokens () const
// exc day on <date> --> yields single day range // exc day on <date> --> yields single day range
// exc day off <date> --> yields single day range // exc day off <date> --> yields single day range
// //
std::vector <Daterange> Exclusion::ranges (const Daterange& range) const std::vector <Range> Exclusion::ranges (const Range& range) const
{ {
std::vector <Daterange> results; std::vector <Range> results;
int dayOfWeek; int dayOfWeek;
if (_tokens[1] == "day" && if (_tokens[1] == "day" &&
@ -105,7 +105,7 @@ std::vector <Daterange> Exclusion::ranges (const Daterange& range) const
Datetime start (_tokens[3]); Datetime start (_tokens[3]);
Datetime end (start); Datetime end (start);
++end; ++end;
Daterange day (start, end); Range day (start, end);
if (range.overlap (day)) if (range.overlap (day))
results.push_back (day); results.push_back (day);
} }
@ -121,9 +121,9 @@ std::vector <Daterange> Exclusion::ranges (const Daterange& range) const
++end; ++end;
// Now that 'start' and 'end' respresent the correct day, compose a set // Now that 'start' and 'end' respresent the correct day, compose a set
// of Daterange objects for each time block. // of Range objects for each time block.
for (unsigned int b = 2; b < _tokens.size (); ++b) for (unsigned int b = 2; b < _tokens.size (); ++b)
results.push_back (daterangeFromTimeBlock (_tokens[b], start, end)); results.push_back (rangeFromTimeBlock (_tokens[b], start, end));
} }
++start; ++start;
@ -152,7 +152,7 @@ std::string Exclusion::dump () const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Daterange Exclusion::daterangeFromTimeBlock ( Range Exclusion::rangeFromTimeBlock (
const std::string& block, const std::string& block,
const Datetime& start, const Datetime& start,
const Datetime& end) const const Datetime& end) const
@ -163,7 +163,7 @@ Daterange Exclusion::daterangeFromTimeBlock (
{ {
int hh, mm, ss; int hh, mm, ss;
if (pig.getHMS (hh, mm, ss)) if (pig.getHMS (hh, mm, ss))
return Daterange (start, Datetime (start.month (), start.day (), start.year (), hh, mm, ss)); return Range (start, Datetime (start.month (), start.day (), start.year (), hh, mm, ss));
throw format ("Malformed time block '{1}'.", block); throw format ("Malformed time block '{1}'.", block);
} }
@ -171,7 +171,7 @@ Daterange Exclusion::daterangeFromTimeBlock (
{ {
int hh, mm, ss; int hh, mm, ss;
if (pig.getHMS (hh, mm, ss)) if (pig.getHMS (hh, mm, ss))
return Daterange (Datetime (start.month (), start.day (), start.year (), hh, mm, ss), end); return Range (Datetime (start.month (), start.day (), start.year (), hh, mm, ss), end);
throw format ("Malformed time block '{1}'.", block); throw format ("Malformed time block '{1}'.", block);
} }
@ -181,7 +181,7 @@ Daterange Exclusion::daterangeFromTimeBlock (
if (pig.getHMS (hh1, mm1, ss1) && if (pig.getHMS (hh1, mm1, ss1) &&
pig.skip ('-') && pig.skip ('-') &&
pig.getHMS (hh2, mm2, ss2)) pig.getHMS (hh2, mm2, ss2))
return Daterange ( return Range (
Datetime (start.month (), start.day (), start.year (), hh1, mm1, ss1), Datetime (start.month (), start.day (), start.year (), hh1, mm1, ss1),
Datetime (start.month (), start.day (), start.year (), hh2, mm2, ss2)); Datetime (start.month (), start.day (), start.year (), hh2, mm2, ss2));

View file

@ -28,7 +28,7 @@
#define INCLUDED_EXCLUSION #define INCLUDED_EXCLUSION
#include <Interval.h> #include <Interval.h>
#include <Daterange.h> #include <Range.h>
#include <vector> #include <vector>
#include <string> #include <string>
@ -38,14 +38,14 @@ public:
Exclusion () = default; Exclusion () = default;
void initialize (const std::string&); void initialize (const std::string&);
std::vector <std::string> tokens () const; std::vector <std::string> tokens () const;
std::vector <Daterange> ranges (const Daterange&) const; std::vector <Range> ranges (const Range&) const;
bool additive () const; bool additive () const;
std::string serialize () const; std::string serialize () const;
std::string dump () const; std::string dump () const;
private: private:
Daterange daterangeFromTimeBlock (const std::string&, const Datetime&, const Datetime&) const; Range rangeFromTimeBlock (const std::string&, const Datetime&, const Datetime&) const;
private: private:
std::vector <std::string> _tokens {}; std::vector <std::string> _tokens {};

View file

@ -90,13 +90,13 @@ bool Interval::empty () const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Daterange Interval::range () const Range Interval::range () const
{ {
return _range; return _range;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Interval::range (const Daterange& range) void Interval::range (const Range& range)
{ {
_range = range; _range = range;
} }

View file

@ -27,7 +27,7 @@
#ifndef INCLUDED_INTERVAL #ifndef INCLUDED_INTERVAL
#define INCLUDED_INTERVAL #define INCLUDED_INTERVAL
#include <Daterange.h> #include <Range.h>
#include <set> #include <set>
#include <string> #include <string>
@ -38,8 +38,8 @@ public:
void initialize (const std::string&); void initialize (const std::string&);
bool empty () const; bool empty () const;
Daterange range () const; Range range () const;
void range (const Daterange&); void range (const Range&);
Datetime start () const; Datetime start () const;
void start (const Datetime&); void start (const Datetime&);
@ -59,7 +59,7 @@ public:
std::string json () const; std::string json () const;
private: private:
Daterange _range {}; Range _range {};
std::set <std::string> _tags {}; std::set <std::string> _tags {};
}; };

View file

@ -25,60 +25,60 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <cmake.h> #include <cmake.h>
#include <Daterange.h> #include <Range.h>
#include <sstream> #include <sstream>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// A Daterange consists of a start time and optional end time. A missing end // A Range consists of a start time and optional end time. A missing end
// time makes the Daterange 'started' but not 'ended'. // time makes the Range 'started' but not 'ended'.
// //
// [start, end) // [start, end)
// //
Daterange::Daterange (const Datetime& start, const Datetime& end) Range::Range (const Datetime& start, const Datetime& end)
{ {
_start = start; _start = start;
_end = end; _end = end;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Daterange::operator== (const Daterange& other) const bool Range::operator== (const Range& other) const
{ {
return _start == other._start && return _start == other._start &&
_end == other._end; _end == other._end;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Datetime Daterange::start () const Datetime Range::start () const
{ {
return _start; return _start;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Daterange::start (const Datetime& value) void Range::start (const Datetime& value)
{ {
_start = value; _start = value;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Datetime Daterange::end () const Datetime Range::end () const
{ {
return _end; return _end;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Daterange::end (const Datetime& value) void Range::end (const Datetime& value)
{ {
_end = value; _end = value;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Daterange::isStarted () const bool Range::isStarted () const
{ {
return _start.toEpoch () > 0; return _start.toEpoch () > 0;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Daterange::isEnded () const bool Range::isEnded () const
{ {
return _end.toEpoch () > 0; return _end.toEpoch () > 0;
} }
@ -108,7 +108,7 @@ bool Daterange::isEnded () const
// H |... // H |...
// I |... // I |...
// //
bool Daterange::overlap (const Daterange& other) const bool Range::overlap (const Range& other) const
{ {
if (! isStarted () || if (! isStarted () ||
! other.isStarted ()) ! other.isStarted ())
@ -152,9 +152,9 @@ bool Daterange::overlap (const Daterange& other) const
// H |... // H |...
// I |... // I |...
// //
Daterange Daterange::intersect (const Daterange& other) const Range Range::intersect (const Range& other) const
{ {
Daterange result; Range result;
if (overlap (other)) if (overlap (other))
{ {
@ -204,20 +204,20 @@ Daterange Daterange::intersect (const Daterange& other) const
// H |... // H |...
// I |... // I |...
// //
std::vector <Daterange> Daterange::subtract (const Daterange& other) const std::vector <Range> Range::subtract (const Range& other) const
{ {
std::vector <Daterange> results; std::vector <Range> results;
if (overlap (other)) if (overlap (other))
{ {
if (start () < other.start ()) if (start () < other.start ())
{ {
results.push_back (Daterange (start (), other.start ())); results.push_back (Range (start (), other.start ()));
if (other.isEnded () && if (other.isEnded () &&
(! isEnded () || end () > other.end ())) (! isEnded () || end () > other.end ()))
{ {
results.push_back (Daterange (other.end (), end ())); results.push_back (Range (other.end (), end ()));
} }
} }
else else
@ -227,11 +227,11 @@ std::vector <Daterange> Daterange::subtract (const Daterange& other) const
if (isEnded ()) if (isEnded ())
{ {
if (end () > other.end ()) if (end () > other.end ())
results.push_back (Daterange (other.end (), end ())); results.push_back (Range (other.end (), end ()));
} }
else else
{ {
results.push_back (Daterange (other.end (), end ())); results.push_back (Range (other.end (), end ()));
} }
} }
} }
@ -247,10 +247,10 @@ std::vector <Daterange> Daterange::subtract (const Daterange& other) const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string Daterange::dump () const std::string Range::dump () const
{ {
std::stringstream out; std::stringstream out;
out << "Daterange " out << "Range "
<< (_start.toEpoch () ? _start.toISOLocalExtended () : "n/a") << (_start.toEpoch () ? _start.toISOLocalExtended () : "n/a")
<< " - " << " - "
<< (_end.toEpoch () ? _end.toISOLocalExtended () : "n/a"); << (_end.toEpoch () ? _end.toISOLocalExtended () : "n/a");

View file

@ -24,18 +24,18 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_DATERANGE #ifndef INCLUDED_RANGE
#define INCLUDED_DATERANGE #define INCLUDED_RANGE
#include <Datetime.h> #include <Datetime.h>
#include <vector> #include <vector>
class Daterange class Range
{ {
public: public:
Daterange () = default; Range () = default;
Daterange (const Datetime&, const Datetime&); Range (const Datetime&, const Datetime&);
bool operator== (const Daterange&) const; bool operator== (const Range&) const;
Datetime start () const; Datetime start () const;
void start (const Datetime&); void start (const Datetime&);
@ -45,9 +45,9 @@ public:
bool isStarted () const; bool isStarted () const;
bool isEnded () const; bool isEnded () const;
bool overlap (const Daterange&) const; bool overlap (const Range&) const;
Daterange intersect (const Daterange&) const; Range intersect (const Range&) const;
std::vector <Daterange> subtract (const Daterange&) const; std::vector <Range> subtract (const Range&) const;
std::string dump () const; std::string dump () const;

View file

@ -50,7 +50,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Timeline::range (const Daterange& range) void Timeline::range (const Range& range)
{ {
_range = range; _range = range;
} }
@ -72,7 +72,7 @@ std::vector <Interval> Timeline::tracked (Rules& rules) const
{ {
// Create a range representing the whole timeline. // Create a range representing the whole timeline.
// If no range is defined, then assume the full range of all the inclusions. // If no range is defined, then assume the full range of all the inclusions.
Daterange overallRange {_range}; Range overallRange {_range};
if (! overallRange.isStarted () && if (! overallRange.isStarted () &&
! overallRange.isEnded ()) ! overallRange.isEnded ())
overallRange = overallRangeFromIntervals (_inclusions); overallRange = overallRangeFromIntervals (_inclusions);
@ -83,11 +83,11 @@ std::vector <Interval> Timeline::tracked (Rules& rules) const
std::vector <Interval> combined; std::vector <Interval> combined;
for (auto& interval : _inclusions) for (auto& interval : _inclusions)
{ {
std::vector <Daterange> intervalFragments {interval.range ()}; std::vector <Range> intervalFragments {interval.range ()};
for (auto& exclusion : nonTrackable) for (auto& exclusion : nonTrackable)
{ {
std::vector <Daterange> brokenFragments; std::vector <Range> brokenFragments;
for (auto& fragment : intervalFragments) for (auto& fragment : intervalFragments)
for (auto& broken : fragment.subtract (exclusion)) for (auto& broken : fragment.subtract (exclusion))
brokenFragments.push_back (broken); brokenFragments.push_back (broken);

View file

@ -29,7 +29,7 @@
#include <Interval.h> #include <Interval.h>
#include <Exclusion.h> #include <Exclusion.h>
#include <Daterange.h> #include <Range.h>
#include <Rules.h> #include <Rules.h>
#include <vector> #include <vector>
@ -37,7 +37,7 @@ class Timeline
{ {
public: public:
Timeline () = default; Timeline () = default;
void range (const Daterange&); void range (const Range&);
void include (const Interval&); void include (const Interval&);
void exclude (const Exclusion&); void exclude (const Exclusion&);
@ -47,7 +47,7 @@ public:
std::string dump () const; std::string dump () const;
private: private:
Daterange _range {}; Range _range {};
std::vector <Interval> _inclusions {}; std::vector <Interval> _inclusions {};
std::vector <Exclusion> _exclusions {}; std::vector <Exclusion> _exclusions {};
}; };

View file

@ -176,7 +176,7 @@ Interval createFilterIntervalFromCLI (const CLI& cli)
} }
} }
Daterange range; Range range;
// <date> // <date>
if (args.size () == 1 && if (args.size () == 1 &&
@ -392,17 +392,17 @@ std::string jsonFromIntervals (const std::vector <Interval>& intervals)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Read rules and extract all holiday definitions. Create a Daterange for each // Read rules and extract all holiday definitions. Create a Range for each
// one that spans from midnight to midnight. // one that spans from midnight to midnight.
std::vector <Daterange> rangesFromHolidays (const Rules& rules) std::vector <Range> rangesFromHolidays (const Rules& rules)
{ {
std::vector <Daterange> results; std::vector <Range> results;
for (auto& holiday : rules.all ("holidays.")) for (auto& holiday : rules.all ("holidays."))
{ {
auto lastDot = holiday.rfind ('.'); auto lastDot = holiday.rfind ('.');
if (lastDot != std::string::npos) if (lastDot != std::string::npos)
{ {
Daterange r; Range r;
Datetime d (holiday.substr (lastDot + 1), "Y_M_D"); Datetime d (holiday.substr (lastDot + 1), "Y_M_D");
r.start (d); r.start (d);
++d; ++d;
@ -416,12 +416,12 @@ std::vector <Daterange> rangesFromHolidays (const Rules& rules)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Subset both ranges and additions by limits, and combine. // Subset both ranges and additions by limits, and combine.
std::vector <Daterange> addRanges ( std::vector <Range> addRanges (
const Daterange& limits, const Range& limits,
const std::vector <Daterange>& ranges, const std::vector <Range>& ranges,
const std::vector <Daterange>& additions) const std::vector <Range>& additions)
{ {
std::vector <Daterange> results; std::vector <Range> results;
for (auto& range : ranges) for (auto& range : ranges)
if (limits.overlap (range)) if (limits.overlap (range))
@ -435,17 +435,17 @@ std::vector <Daterange> addRanges (
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Subtract a set of Dateranges from another set of Dateranges, all within a // Subtract a set of Range from another set of Range, all within a defined
// defined range. // range.
std::vector <Daterange> subtractRanges ( std::vector <Range> subtractRanges (
const Daterange& limits, const Range& limits,
const std::vector <Daterange>& ranges, const std::vector <Range>& ranges,
const std::vector <Daterange>& subtractions) const std::vector <Range>& subtractions)
{ {
if (! subtractions.size ()) if (! subtractions.size ())
return ranges; return ranges;
std::vector <Daterange> results; std::vector <Range> results;
for (auto& r1 : ranges) for (auto& r1 : ranges)
for (auto& r2 : subtractions) for (auto& r2 : subtractions)
for (auto& r3 : r1.subtract (r2)) for (auto& r3 : r1.subtract (r2))
@ -456,10 +456,10 @@ std::vector <Daterange> subtractRanges (
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// From a set of intervals, find the earliest start and the latest end, and // From a set of intervals, find the earliest start and the latest end, and
// return these in a Daterange. // return these in a Range.
Daterange overallRangeFromIntervals (const std::vector <Interval>& intervals) Range overallRangeFromIntervals (const std::vector <Interval>& intervals)
{ {
Daterange overall; Range overall;
for (auto& interval : intervals) for (auto& interval : intervals)
{ {
@ -479,7 +479,7 @@ Daterange overallRangeFromIntervals (const std::vector <Interval>& intervals)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// [1] Read holiday definitions from the rules, extract their dates and create // [1] Read holiday definitions from the rules, extract their dates and create
// a set of Dateranges from them. // a set of Range from them.
// [2] For 'exc day ...' exclusions, separate into daysOn and daysOff sets, // [2] For 'exc day ...' exclusions, separate into daysOn and daysOff sets,
// based on whether the exclusion is additive. // based on whether the exclusion is additive.
// [3] Treat daysOff as additional holidays. // [3] Treat daysOff as additional holidays.
@ -489,19 +489,19 @@ Daterange overallRangeFromIntervals (const std::vector <Interval>& intervals)
// //
// The result is the complete set of untrackable time that lies within the // The result is the complete set of untrackable time that lies within the
// input range. This will be a set of nights, weekends, holidays and lunchtimes. // input range. This will be a set of nights, weekends, holidays and lunchtimes.
std::vector <Daterange> combineHolidaysAndExclusions ( std::vector <Range> combineHolidaysAndExclusions (
const Daterange& range, const Range& range,
const Rules& rules, const Rules& rules,
const std::vector <Exclusion>& exclusions) const std::vector <Exclusion>& exclusions)
{ {
// Start with the set of all holidays, intersected with range. // Start with the set of all holidays, intersected with range.
std::vector <Daterange> results; std::vector <Range> results;
results = addRanges (range, results, rangesFromHolidays (rules)); results = addRanges (range, results, rangesFromHolidays (rules));
// Find exclusions 'exc day on <date>' and remove from holidays. // Find exclusions 'exc day on <date>' and remove from holidays.
// Find exlcusions 'exc day off <date>' and add to holidays. // Find exlcusions 'exc day off <date>' and add to holidays.
std::vector <Daterange> daysOn; std::vector <Range> daysOn;
std::vector <Daterange> daysOff; std::vector <Range> daysOff;
for (auto& exclusion : exclusions) for (auto& exclusion : exclusions)
{ {
if (exclusion.tokens ()[1] == "day") if (exclusion.tokens ()[1] == "day")
@ -523,7 +523,7 @@ std::vector <Daterange> combineHolidaysAndExclusions (
// Expand all exclusions that are not 'exc day ...' into excluded ranges that // Expand all exclusions that are not 'exc day ...' into excluded ranges that
// overlage with range. // overlage with range.
std::vector <Daterange> exclusionRanges; std::vector <Range> exclusionRanges;
for (auto& exclusion : exclusions) for (auto& exclusion : exclusions)
if (exclusion.tokens ()[1] != "day") if (exclusion.tokens ()[1] != "day")
for (auto& r : exclusion.ranges (range)) for (auto& r : exclusion.ranges (range))

View file

@ -52,11 +52,11 @@ Timeline createTimelineFromData (const Rules&, Database&, const Interval&);
Interval getLatestInterval (Database&); Interval getLatestInterval (Database&);
bool intervalMatchesFilterInterval (const Interval&, const Interval&); bool intervalMatchesFilterInterval (const Interval&, const Interval&);
std::string jsonFromIntervals (const std::vector <Interval>&); std::string jsonFromIntervals (const std::vector <Interval>&);
std::vector <Daterange> rangesFromHolidays (const Rules&); std::vector <Range> rangesFromHolidays (const Rules&);
std::vector <Daterange> addRanges (const Daterange&, const std::vector <Daterange>&, const std::vector <Daterange>&); std::vector <Range> addRanges (const Range&, const std::vector <Range>&, const std::vector <Range>&);
std::vector <Daterange> subtractRanges (const Daterange&, const std::vector <Daterange>&, const std::vector <Daterange>&); std::vector <Range> subtractRanges (const Range&, const std::vector <Range>&, const std::vector <Range>&);
Daterange overallRangeFromIntervals (const std::vector <Interval>&); Range overallRangeFromIntervals (const std::vector <Interval>&);
std::vector <Daterange> combineHolidaysAndExclusions (const Daterange&, const Rules&, const std::vector <Exclusion>&); std::vector <Range> combineHolidaysAndExclusions (const Range&, const Rules&, const std::vector <Exclusion>&);
// utiŀ.cpp // utiŀ.cpp
std::string osName (); std::string osName ();

2
test/.gitignore vendored
View file

@ -1,10 +1,10 @@
all.log all.log
*.pyc *.pyc
composite.t composite.t
daterange.t
exclusion.t exclusion.t
interval.t interval.t
lexer.t lexer.t
palette.t palette.t
range.t
rules.t rules.t
util.t util.t

View file

@ -14,7 +14,7 @@ include_directories (${CMAKE_SOURCE_DIR}
include_directories (${CMAKE_INSTALL_PREFIX}/include) include_directories (${CMAKE_INSTALL_PREFIX}/include)
link_directories(${CMAKE_INSTALL_PREFIX}/lib) link_directories(${CMAKE_INSTALL_PREFIX}/lib)
set (test_SRCS composite.t daterange.t exclusion.t interval.t lexer.t palette.t rules.t util.t) set (test_SRCS composite.t exclusion.t interval.t lexer.t palette.t range.t rules.t util.t)
add_custom_target (test ./run_all --verbose add_custom_target (test ./run_all --verbose
DEPENDS ${test_SRCS} DEPENDS ${test_SRCS}

View file

@ -1,218 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <Daterange.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest t (60);
// bool isStarted () const;
// bool isEnded () const;
Daterange i1;
t.is (i1.isStarted (), false, "Daterange().isStarted -> false");
t.is (i1.isEnded (), false, "Daterange().isEnded -> false");
// void start (Datetime);
i1.start (Datetime ());
t.is (i1.isStarted (), true, "Daterange(start=now).isStarted -> true");
t.is (i1.isEnded (), false, "Daterange(start=now).isEnded -> false");
// void end (Datetime);
i1.end (Datetime ());
t.is (i1.isStarted (), true, "Daterange(start=now,end=now).isStarted -> true");
t.is (i1.isEnded (), true, "Daterange(start=now,end=now).isEnded -> true");
// this [--------)
// A [--------)
// B [--------)
// C [----|
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Daterange refClosed;
refClosed.start (Datetime (6, 1, 2016));
refClosed.end (Datetime (6, 30, 2016));
Daterange testA; testA.start (Datetime (4, 1, 2016)); testA.end (Datetime (4, 30, 2016));
Daterange testB; testB.start (Datetime (5, 15, 2016)); testB.end (Datetime (6, 15, 2016));
Daterange testC; testC.start (Datetime (6, 10, 2016)); testC.end (Datetime (6, 20, 2016));
Daterange testD; testD.start (Datetime (6, 15, 2016)); testD.end (Datetime (7, 15, 2016));
Daterange testE; testE.start (Datetime (8, 1, 2016)); testE.end (Datetime (8, 31, 2016));
Daterange testF; testF.start (Datetime (5, 15, 2016)); testF.end (Datetime (7, 15, 2016));
Daterange testG; testG.start (Datetime (5, 15, 2016));
Daterange testH; testH.start (Datetime (6, 15, 2016));
Daterange testI; testI.start (Datetime (7, 15, 2016));
t.notok (refClosed.overlap (testA), "Daterange: ! refClosed.overlap(testA)");
t.ok (refClosed.overlap (testB), "Daterange: refClosed.overlap(testB)");
t.ok (refClosed.overlap (testC), "Daterange: refClosed.overlap(testC)");
t.ok (refClosed.overlap (testD), "Daterange: refClosed.overlap(testD)");
t.notok (refClosed.overlap (testE), "Daterange: ! refClosed.overlap(testE)");
t.ok (refClosed.overlap (testF), "Daterange: refClosed.overlap(testF)");
t.ok (refClosed.overlap (testG), "Daterange: refClosed.overlap(testG)");
t.ok (refClosed.overlap (testH), "Daterange: refClosed.overlap(testH)");
t.notok (refClosed.overlap (testI), "Daterange: ! refClosed.overlap(testI)");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Daterange refOpen;
refOpen.start (Datetime (6, 1, 2016));
t.notok (refOpen.overlap (testA), "Daterange: ! refOpen.overlap(testA)");
t.ok (refOpen.overlap (testB), "Daterange: refOpen.overlap(testB)");
t.ok (refOpen.overlap (testC), "Daterange: refOpen.overlap(testC)");
t.ok (refOpen.overlap (testD), "Daterange: refOpen.overlap(testD)");
t.ok (refOpen.overlap (testE), "Daterange: refOpen.overlap(testE)");
t.ok (refOpen.overlap (testF), "Daterange: refOpen.overlap(testF)");
t.ok (refOpen.overlap (testG), "Daterange: refOpen.overlap(testG)");
t.ok (refOpen.overlap (testH), "Daterange: refOpen.overlap(testH)");
t.ok (refOpen.overlap (testI), "Daterange: refOpen.overlap(testI)");
// this [--------)
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Daterange empty;
t.ok (refClosed.intersect (testA) == empty, "Daterange: refClosed.intersect(testA) == empty");
t.ok (refClosed.intersect (testB) == Daterange (refClosed.start (), testB.end ()), "Daterange: refClosed.intersect(testB) == Daterange(refClosed.start(), testB.end())");
t.ok (refClosed.intersect (testC) == testC, "Daterange: refClosed.intersect(testB) == testC");
t.ok (refClosed.intersect (testD) == Daterange (testD.start (), refClosed.end ()), "Daterange: refClosed.intersect(testB) == Daterange(testD.start(), refClosed.end())");
t.ok (refClosed.intersect (testE) == empty, "Daterange: refClosed.intersect(testE) == empty");
t.ok (refClosed.intersect (testF) == refClosed, "Daterange: refClosed.intersect(testF) == refClosed");
t.ok (refClosed.intersect (testG) == refClosed, "Daterange: refClosed.intersect(testG) == refClosed");
t.ok (refClosed.intersect (testH) == Daterange (testH.start (), refClosed.end ()), "Daterange: refClosed.intersect(testH) == Daterange(testH.start(), refClosed.end())");
t.ok (refClosed.intersect (testI) == empty, "Daterange: refClosed.intersect(testI) == empty");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
t.ok (refOpen.intersect (testA) == empty, "Daterange: refOpen.intersect(testA) == empty");
t.ok (refOpen.intersect (testB) == Daterange (refOpen.start (), testB.end ()), "Daterange: refOpen.intersect(testB) == Daterange(refOpen.start(), testB.end())");
t.ok (refOpen.intersect (testC) == testC, "Daterange: refOpen.intersect(testC) == testC");
t.ok (refOpen.intersect (testD) == testD, "Daterange: refOpen.intersect(testD) == testD");
t.ok (refOpen.intersect (testE) == testE, "Daterange: refOpen.intersect(testE) == testE");
t.ok (refOpen.intersect (testF) == Daterange (refOpen.start (), testF.end ()), "Daterange: refOpen.intersect(testF) == Daterange(refOpen.start(), testF.end()");
t.ok (refOpen.intersect (testG) == refOpen, "Daterange: refOpen.intersect(testG) == refOpen");
t.ok (refOpen.intersect (testH) == testH, "Daterange: refOpen.intersect(testH) == testH");
t.ok (refOpen.intersect (testI) == testI, "Daterange: refOpen.intersect(testI) == testI");
// this [--------)
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
std::vector <Daterange> closedSubtractA {refClosed};
std::vector <Daterange> closedSubtractB {Daterange (testB.end (), refClosed.end ())};
std::vector <Daterange> closedSubtractC {Daterange (refClosed.start (), testC.start ()), Daterange (testC.end (), refClosed.end ())};
std::vector <Daterange> closedSubtractD {Daterange (refClosed.start (), testD.start ())};
std::vector <Daterange> closedSubtractE {refClosed};
std::vector <Daterange> closedSubtractF {};
std::vector <Daterange> closedSubtractG {};
std::vector <Daterange> closedSubtractH {Daterange (refClosed.start (), testH.start ())};
std::vector <Daterange> closedSubtractI {refClosed};
t.ok (refClosed.subtract (testA) == closedSubtractA, "Daterange: refClosed.subtract(testA) == {refClosed}");
t.ok (refClosed.subtract (testB) == closedSubtractB, "Daterange: refClosed.subtract(testB) == {Daterange(testB.end(), refClosed.end())}");
t.ok (refClosed.subtract (testC) == closedSubtractC, "Daterange: refClosed.subtract(testC) == {Daterange(refClosed.start(), testC.start()),"
"Daterange(testC.end(), refClosed.end()}");
t.ok (refClosed.subtract (testD) == closedSubtractD, "Daterange: refClosed.subtract(testD) == {Daterange(refClosed.start(), testD.start())}");
t.ok (refClosed.subtract (testE) == closedSubtractE, "Daterange: refClosed.subtract(testE) == {refClosed}");
t.ok (refClosed.subtract (testF) == closedSubtractF, "Daterange: refClosed.subtract(testF) == {}");
t.ok (refClosed.subtract (testG) == closedSubtractG, "Daterange: refClosed.subtract(testG) == {}");
t.ok (refClosed.subtract (testH) == closedSubtractH, "Daterange: refClosed.subtract(testH) == {refClosed.start(), testH.start()}");
t.ok (refClosed.subtract (testI) == closedSubtractI, "Daterange: refClosed.subtract(testI) == {refClosed}");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
std::vector <Daterange> openSubtractA {refOpen};
std::vector <Daterange> openSubtractB {Daterange (testB.end (), refOpen.end ())};
std::vector <Daterange> openSubtractC {Daterange (refOpen.start (), testC.start ()), Daterange (testC.end (), refOpen.end ())};
std::vector <Daterange> openSubtractD {Daterange (refOpen.start (), testD.start ()), Daterange (testD.end (), refOpen.end ())};
std::vector <Daterange> openSubtractE {Daterange (refOpen.start (), testE.start ()), Daterange (testE.end (), refOpen.end ())};
std::vector <Daterange> openSubtractF {Daterange (testF.end (), refOpen.end ())};
std::vector <Daterange> openSubtractG {};
std::vector <Daterange> openSubtractH {Daterange (refOpen.start (), testH.start ())};
std::vector <Daterange> openSubtractI {Daterange (refOpen.start (), testI.start ())};
t.ok (refOpen.subtract (testA) == openSubtractA, "Daterange: refOpen.subtract(testA) == {refOpen}");
t.ok (refOpen.subtract (testB) == openSubtractB, "Daterange: refOpen.subtract(testB) == {Daterange(testB.end(), refOpen.end()}");
t.ok (refOpen.subtract (testC) == openSubtractC, "Daterange: refOpen.subtract(testC) == {Daterange(refOpen.start(), testC.start()),"
"Daterange(testC.end(), refOpen.end()}");
t.ok (refOpen.subtract (testD) == openSubtractD, "Daterange: refOpen.subtract(testD) == {Daterange(refOpen.start(), testD.start()),"
"Daterange(testD.end(), refOpen.end()}");
t.ok (refOpen.subtract (testE) == openSubtractE, "Daterange: refOpen.subtract(testE) == {Daterange(refOpen.start(), testE.start()),"
"Daterange(testE.end(), refOpen.end()}");
t.ok (refOpen.subtract (testF) == openSubtractF, "Daterange: refOpen.subtract(testF) == {Daterange(testF.end(), refOpen.end()}");
t.ok (refOpen.subtract (testG) == openSubtractG, "Daterange: refOpen.subtract(testG) == {}");
t.ok (refOpen.subtract (testH) == openSubtractH, "Daterange: refOpen.subtract(testH) == {Daterange(refOpen.start(), testH.start()}");
t.ok (refOpen.subtract (testI) == openSubtractI, "Daterange: refOpen.subtract(testI) == {Daterange(refOpen.start(), testI.start()}");
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -26,7 +26,7 @@
#include <cmake.h> #include <cmake.h>
#include <Exclusion.h> #include <Exclusion.h>
#include <Daterange.h> #include <Range.h>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <test.h> #include <test.h>
@ -48,7 +48,7 @@ int main (int, char**)
// 20 21 22 23 24 25 26 17 18 19 20 21 22 23 // 20 21 22 23 24 25 26 17 18 19 20 21 22 23
// 27 28 29 30 31 24 25 26 27 28 29 30 // 27 28 29 30 31 24 25 26 27 28 29 30
// 31 // 31
Daterange r (Datetime ("2015-12-15"), Datetime ("2016-01-15")); Range r (Datetime ("2015-12-15"), Datetime ("2016-01-15"));
// exc monday <8:00:00 12:00:00-12:45:00 >17:30:00 // exc monday <8:00:00 12:00:00-12:45:00 >17:30:00
Exclusion e; Exclusion e;

218
test/range.t.cpp Normal file
View file

@ -0,0 +1,218 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <Range.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
int main (int, char**)
{
UnitTest t (60);
// bool isStarted () const;
// bool isEnded () const;
Range i1;
t.is (i1.isStarted (), false, "Range().isStarted -> false");
t.is (i1.isEnded (), false, "Range().isEnded -> false");
// void start (Datetime);
i1.start (Datetime ());
t.is (i1.isStarted (), true, "Range(start=now).isStarted -> true");
t.is (i1.isEnded (), false, "Range(start=now).isEnded -> false");
// void end (Datetime);
i1.end (Datetime ());
t.is (i1.isStarted (), true, "Range(start=now,end=now).isStarted -> true");
t.is (i1.isEnded (), true, "Range(start=now,end=now).isEnded -> true");
// this [--------)
// A [--------)
// B [--------)
// C [----|
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Range refClosed;
refClosed.start (Datetime (6, 1, 2016));
refClosed.end (Datetime (6, 30, 2016));
Range testA; testA.start (Datetime (4, 1, 2016)); testA.end (Datetime (4, 30, 2016));
Range testB; testB.start (Datetime (5, 15, 2016)); testB.end (Datetime (6, 15, 2016));
Range testC; testC.start (Datetime (6, 10, 2016)); testC.end (Datetime (6, 20, 2016));
Range testD; testD.start (Datetime (6, 15, 2016)); testD.end (Datetime (7, 15, 2016));
Range testE; testE.start (Datetime (8, 1, 2016)); testE.end (Datetime (8, 31, 2016));
Range testF; testF.start (Datetime (5, 15, 2016)); testF.end (Datetime (7, 15, 2016));
Range testG; testG.start (Datetime (5, 15, 2016));
Range testH; testH.start (Datetime (6, 15, 2016));
Range testI; testI.start (Datetime (7, 15, 2016));
t.notok (refClosed.overlap (testA), "Range: ! refClosed.overlap(testA)");
t.ok (refClosed.overlap (testB), "Range: refClosed.overlap(testB)");
t.ok (refClosed.overlap (testC), "Range: refClosed.overlap(testC)");
t.ok (refClosed.overlap (testD), "Range: refClosed.overlap(testD)");
t.notok (refClosed.overlap (testE), "Range: ! refClosed.overlap(testE)");
t.ok (refClosed.overlap (testF), "Range: refClosed.overlap(testF)");
t.ok (refClosed.overlap (testG), "Range: refClosed.overlap(testG)");
t.ok (refClosed.overlap (testH), "Range: refClosed.overlap(testH)");
t.notok (refClosed.overlap (testI), "Range: ! refClosed.overlap(testI)");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Range refOpen;
refOpen.start (Datetime (6, 1, 2016));
t.notok (refOpen.overlap (testA), "Range: ! refOpen.overlap(testA)");
t.ok (refOpen.overlap (testB), "Range: refOpen.overlap(testB)");
t.ok (refOpen.overlap (testC), "Range: refOpen.overlap(testC)");
t.ok (refOpen.overlap (testD), "Range: refOpen.overlap(testD)");
t.ok (refOpen.overlap (testE), "Range: refOpen.overlap(testE)");
t.ok (refOpen.overlap (testF), "Range: refOpen.overlap(testF)");
t.ok (refOpen.overlap (testG), "Range: refOpen.overlap(testG)");
t.ok (refOpen.overlap (testH), "Range: refOpen.overlap(testH)");
t.ok (refOpen.overlap (testI), "Range: refOpen.overlap(testI)");
// this [--------)
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
Range empty;
t.ok (refClosed.intersect (testA) == empty, "Range: refClosed.intersect(testA) == empty");
t.ok (refClosed.intersect (testB) == Range (refClosed.start (), testB.end ()), "Range: refClosed.intersect(testB) == Range(refClosed.start(), testB.end())");
t.ok (refClosed.intersect (testC) == testC, "Range: refClosed.intersect(testB) == testC");
t.ok (refClosed.intersect (testD) == Range (testD.start (), refClosed.end ()), "Range: refClosed.intersect(testB) == Range(testD.start(), refClosed.end())");
t.ok (refClosed.intersect (testE) == empty, "Range: refClosed.intersect(testE) == empty");
t.ok (refClosed.intersect (testF) == refClosed, "Range: refClosed.intersect(testF) == refClosed");
t.ok (refClosed.intersect (testG) == refClosed, "Range: refClosed.intersect(testG) == refClosed");
t.ok (refClosed.intersect (testH) == Range (testH.start (), refClosed.end ()), "Range: refClosed.intersect(testH) == Range(testH.start(), refClosed.end())");
t.ok (refClosed.intersect (testI) == empty, "Range: refClosed.intersect(testI) == empty");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
t.ok (refOpen.intersect (testA) == empty, "Range: refOpen.intersect(testA) == empty");
t.ok (refOpen.intersect (testB) == Range (refOpen.start (), testB.end ()), "Range: refOpen.intersect(testB) == Range(refOpen.start(), testB.end())");
t.ok (refOpen.intersect (testC) == testC, "Range: refOpen.intersect(testC) == testC");
t.ok (refOpen.intersect (testD) == testD, "Range: refOpen.intersect(testD) == testD");
t.ok (refOpen.intersect (testE) == testE, "Range: refOpen.intersect(testE) == testE");
t.ok (refOpen.intersect (testF) == Range (refOpen.start (), testF.end ()), "Range: refOpen.intersect(testF) == Range(refOpen.start(), testF.end()");
t.ok (refOpen.intersect (testG) == refOpen, "Range: refOpen.intersect(testG) == refOpen");
t.ok (refOpen.intersect (testH) == testH, "Range: refOpen.intersect(testH) == testH");
t.ok (refOpen.intersect (testI) == testI, "Range: refOpen.intersect(testI) == testI");
// this [--------)
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
std::vector <Range> closedSubtractA {refClosed};
std::vector <Range> closedSubtractB {Range (testB.end (), refClosed.end ())};
std::vector <Range> closedSubtractC {Range (refClosed.start (), testC.start ()), Range (testC.end (), refClosed.end ())};
std::vector <Range> closedSubtractD {Range (refClosed.start (), testD.start ())};
std::vector <Range> closedSubtractE {refClosed};
std::vector <Range> closedSubtractF {};
std::vector <Range> closedSubtractG {};
std::vector <Range> closedSubtractH {Range (refClosed.start (), testH.start ())};
std::vector <Range> closedSubtractI {refClosed};
t.ok (refClosed.subtract (testA) == closedSubtractA, "Range: refClosed.subtract(testA) == {refClosed}");
t.ok (refClosed.subtract (testB) == closedSubtractB, "Range: refClosed.subtract(testB) == {Range(testB.end(), refClosed.end())}");
t.ok (refClosed.subtract (testC) == closedSubtractC, "Range: refClosed.subtract(testC) == {Range(refClosed.start(), testC.start()),"
"Range(testC.end(), refClosed.end()}");
t.ok (refClosed.subtract (testD) == closedSubtractD, "Range: refClosed.subtract(testD) == {Range(refClosed.start(), testD.start())}");
t.ok (refClosed.subtract (testE) == closedSubtractE, "Range: refClosed.subtract(testE) == {refClosed}");
t.ok (refClosed.subtract (testF) == closedSubtractF, "Range: refClosed.subtract(testF) == {}");
t.ok (refClosed.subtract (testG) == closedSubtractG, "Range: refClosed.subtract(testG) == {}");
t.ok (refClosed.subtract (testH) == closedSubtractH, "Range: refClosed.subtract(testH) == {refClosed.start(), testH.start()}");
t.ok (refClosed.subtract (testI) == closedSubtractI, "Range: refClosed.subtract(testI) == {refClosed}");
// this [...
// A [--------)
// B [--------)
// C [----)
// D [--------)
// E [--------)
// F [-------------)
// G [...
// H [...
// I [...
std::vector <Range> openSubtractA {refOpen};
std::vector <Range> openSubtractB {Range (testB.end (), refOpen.end ())};
std::vector <Range> openSubtractC {Range (refOpen.start (), testC.start ()), Range (testC.end (), refOpen.end ())};
std::vector <Range> openSubtractD {Range (refOpen.start (), testD.start ()), Range (testD.end (), refOpen.end ())};
std::vector <Range> openSubtractE {Range (refOpen.start (), testE.start ()), Range (testE.end (), refOpen.end ())};
std::vector <Range> openSubtractF {Range (testF.end (), refOpen.end ())};
std::vector <Range> openSubtractG {};
std::vector <Range> openSubtractH {Range (refOpen.start (), testH.start ())};
std::vector <Range> openSubtractI {Range (refOpen.start (), testI.start ())};
t.ok (refOpen.subtract (testA) == openSubtractA, "Range: refOpen.subtract(testA) == {refOpen}");
t.ok (refOpen.subtract (testB) == openSubtractB, "Range: refOpen.subtract(testB) == {Range(testB.end(), refOpen.end()}");
t.ok (refOpen.subtract (testC) == openSubtractC, "Range: refOpen.subtract(testC) == {Range(refOpen.start(), testC.start()),"
"Range(testC.end(), refOpen.end()}");
t.ok (refOpen.subtract (testD) == openSubtractD, "Range: refOpen.subtract(testD) == {Range(refOpen.start(), testD.start()),"
"Range(testD.end(), refOpen.end()}");
t.ok (refOpen.subtract (testE) == openSubtractE, "Range: refOpen.subtract(testE) == {Range(refOpen.start(), testE.start()),"
"Range(testE.end(), refOpen.end()}");
t.ok (refOpen.subtract (testF) == openSubtractF, "Range: refOpen.subtract(testF) == {Range(testF.end(), refOpen.end()}");
t.ok (refOpen.subtract (testG) == openSubtractG, "Range: refOpen.subtract(testG) == {}");
t.ok (refOpen.subtract (testH) == openSubtractH, "Range: refOpen.subtract(testH) == {Range(refOpen.start(), testH.start()}");
t.ok (refOpen.subtract (testI) == openSubtractI, "Range: refOpen.subtract(testI) == {Range(refOpen.start(), testI.start()}");
return 0;
}
////////////////////////////////////////////////////////////////////////////////