-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcalitem.cpp
157 lines (131 loc) · 3.94 KB
/
calitem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <algorithm>
using std::min;
#include <stdexcept>
using std::invalid_argument;
#include <sstream>
using std::stringstream;
#include "config.hpp"
#include "calitem.hpp"
calitem::calitem(const string &name,
const set<time_period> &coverage,
const set<calitem*> &children,
const set<calitem*> &parents)
:
mName(name),
mCoverage(coverage),
mChildren(children),
mParents(parents)
{
#ifdef CSEPT_PPI_TESTS
// Precondition checks
// Check if mCoverage is non-self-intersecting
set<time_period>::const_iterator it_a = mCoverage.begin();
for(; it_a != mCoverage.end(); it_a++)
{
set<time_period>::const_iterator it_b = mCoverage.begin();
for(; it_b != mCoverage.end(); it_b++)
{
if(it_a != it_b && it_a->intersects(*it_b))
{
stringstream msg;
msg << "calitem::constructor: argument coverage contains"
" intersecting time periods. ";
msg << *it_a << " " << *it_b;
throw invalid_argument(msg.str());
}
}
}
// Check for invalid pointers in mChildren
set<calitem*>::const_iterator it_children = mChildren.begin();
for(; it_children != mChildren.end(); it_children++)
{
if(dynamic_cast<calitem*>(*it_children) == NULL)
{
stringstream msg;
msg << "calitem::constructor: argument children contains null"
" pointer";
throw invalid_argument(msg.str());
}
}
// Check for invalid pointers in mParents
set<calitem*>::const_iterator it_parents = mParents.begin();
for(; it_parents != mParents.end(); it_parents++)
{
if(dynamic_cast<calitem*>(*it_parents) == NULL)
{
stringstream msg;
msg << "calitem::constructor: argument parents contains null"
" pointer";
throw invalid_argument(msg.str());
}
}
#endif
// End precondition checks
}
string calitem::name() const
{
return mName;
}
void calitem::addchild(calitem &child, bool link_back)
{
mChildren.insert(&child);
if(link_back)
{
child.addparent(*this, false);
}
}
void calitem::addparent(calitem &parent, bool link_back)
{
mParents.insert(&parent);
if(link_back)
{
parent.addchild(*this, false);
}
}
set<time_period> calitem::coverage() const
{
return mCoverage;
}
set<time_period> calitem::intersect(const calitem &other) const
{
set<time_period> condensedperiods;
// Intersect the time period sets. Because we know the sets are
// non-self-intersecting, we can intersect every element in the first set
// with every element in the second set and push all the valid intersections
// into the result set.
set<time_period>::const_iterator period_it = other.mCoverage.begin();
for(; period_it != other.mCoverage.end(); period_it++)
{
set<time_period>::const_iterator this_it = mCoverage.begin();
for(; this_it != mCoverage.end(); this_it++)
{
if(this_it->intersects(*period_it))
condensedperiods.insert(this_it->intersection(*period_it));
}
}
return condensedperiods;
}
set<time_period> calitem::unify(const calitem &other) const
{
set<time_period>::const_iterator it_a = mCoverage.begin();
set<time_period>::const_iterator it_b = other.mCoverage.begin();
set<time_period> union_set;
while(it_a != mCoverage.end() && it_b != other.mCoverage.end())
{
if(it_a->intersects(*it_b))
{
union_set.insert(it_a->merge(*it_b));
it_a++;
it_b++;
}
else
{
union_set.insert(min(*it_a, *it_b));
if(min(*it_a, *it_b) == *it_a)
it_a++;
else
it_b++;
}
}
return union_set;
}