TCPSPSuite
intervalrunner.hpp
1 #ifndef INTERVALRUNNER_HPP
2 #define INTERVALRUNNER_HPP
3 
4 #include "../datastructures/maybe.hpp"
5 
6 template<class It1, class It2, class Point, class PointGetter, class EventHandler, class DataGetter, class Data>
7 void process_intervals(It1 start_a, It1 end_a, It2 start_b, It2 end_b, PointGetter &pg, EventHandler &handler, DataGetter &dg) {
8  using CbData = Maybe<Data>;
9 
10  Point last_point = Point();
11 
12  if ((start_a != end_a) && ((start_b == end_b) || (pg(start_a, true) < pg(start_b, true)))) {
13  last_point = pg(start_a, true);
14  }
15 
16  bool event_a;
17  bool event_b;
18 
19  if ((start_a != end_a) && (pg(start_a, true) == last_point)) {
20  event_a = true;
21  } else {
22  event_a = false;
23  }
24 
25  if ((start_b != end_b) && (pg(start_b, true) == last_point)) {
26  event_b = true;
27  } else {
28  event_b = false;
29  }
30 
31  handler(last_point,
32  event_a ? CbData(dg(start_a)) : CbData(),
33  CbData(),
34  event_b ? CbData(dg(start_b)) : CbData(),
35  CbData()
36  );
37 
38  while ((start_a != end_a) || (start_b != end_b)) {
39  Point next_point = last_point;
40 
41  bool a_ends = false;
42  bool a_starts = false;
43  bool b_ends = false;
44  bool b_starts = false;
45 
46  if (start_a != end_a) {
47  if (pg(start_a, true) > last_point) {
48  a_starts = true;
49  next_point = pg(start_a, true);
50  } else {
51 #ifdef ENABLE_ASSERTIONS
52  assert(pg(start_a, false) > last_point);
53 #endif
54  a_ends = true;
55  next_point = pg(start_a, false);
56  if ((start_a + 1) != end_a) {
57  if (pg((start_a + 1), true) == next_point) {
58  a_starts = true;
59  }
60  }
61  }
62  }
63 
64  if (start_b != end_b) {
65  //std::cout << "Comparing for B: " << pg(start_b, true) << " vs " << last_point << "\n";
66  if (pg(start_b, true) > last_point) {
67  //std::cout << "Taking B's lower point\n";
68 
69  if ((next_point == last_point) || (pg(start_b, true) < next_point)) {
70  b_starts = true;
71  a_starts = false;
72  a_ends = false;
73  next_point = pg(start_b, true);
74  } else if (pg(start_b, true) == next_point) {
75  b_starts = true;
76  }
77  } else {
78 #ifdef ENABLE_ASSERTIONS
79  assert(pg(start_b, false) > last_point);
80 #endif
81  if ((next_point == last_point) || (pg(start_b, false) < next_point)) {
82  b_starts = false;
83  b_ends = true;
84  a_starts = false;
85  a_ends = false;
86  next_point = pg(start_b, false);
87  } else if (pg(start_b, false) == next_point) {
88  b_ends = true;
89  }
90 
91  if ((b_ends) && ((start_b + 1) != end_b) && (pg((start_b + 1), true) == next_point)) {
92  b_starts = true;
93  }
94  }
95  }
96  //std::cout << "A Starts: " << a_starts << " / A Ends: " << a_ends ;
97  //std::cout << "B Starts: " << b_starts << " / B Ends: " << b_ends ;
98  //std::cout << "Next point: " << next_point ;
99 
100  handler(next_point,
101  // start data in A: start_a starts here
102  a_starts && (!a_ends) ? CbData(dg(start_a)) :
103  // Start data in A: (start_a + 1) starts here
104  a_starts && a_ends ? CbData(dg(start_a + 1)) :
105  // Start data in A: nothing starts here
106  CbData(),
107 
108  a_ends ? CbData(dg(start_a)) : CbData(),
109 
110  // start data in B: start_b starts here
111  b_starts && (!b_ends) ? CbData(dg(start_b)) :
112  // Start data in B: (start_b + 1) starts here
113  b_starts && b_ends ? CbData(dg(start_b + 1)) :
114  // Start data in B: nothing starts here
115  CbData(),
116 
117  b_ends ? CbData(dg(start_b)) : CbData()
118  );
119 
120  last_point = next_point;
121  if (a_ends) {
122  start_a++;
123  }
124  if (b_ends) {
125  start_b++;
126  }
127  }
128 }
129 
130 #endif