TCPSPSuite
skyline_interface.hpp
1 #ifndef SKYLINE_INTERFACE_HPP
2 #define SKYLINE_INTERFACE_HPP
3 
4 #include "../instance/job.hpp"
5 #include "../instance/resource.hpp"
6 
7 #include <dyno.hpp>
8 
9 #include <cassert>
10 #include <iterator>
11 #include <type_traits>
12 #include <utility>
13 
14 #include "skyline.hpp"
15 
16 namespace ds {
17 using dyno::literals::operator""_s;
18 
19 struct SkyLineIteratorInterface
20  : decltype(::dyno::requires(
21  dyno::CopyConstructible{}, dyno::CopyAssignable{},
22  dyno::Destructible{}, dyno::EqualityComparable{},
23  dyno::DefaultConstructible{},
24 
25  "operator++_prefix"_s = ::dyno::method<void()>,
26  "operator++_postfix"_s = ::dyno::method<void(int)>,
27  "operator--_prefix"_s = ::dyno::method<void()>,
28  "operator--_postfix"_s = ::dyno::method<void(int)>,
29  "dereference"_s = ::dyno::method<const SkyLineEvent &()>))
30 {
31 };
32 
33 /*
34  * SkyLine Interface
35  */
36 struct SkyLineInterface
37  : decltype(::dyno::requires(
38  dyno::MoveConstructible{},
39  "remove_job__job"_s = ::dyno::method<void(const Job &)>,
40  "remove_job__jid"_s = ::dyno::method<void(Job::JobId)>,
41  "insert_job__job"_s =
42  ::dyno::method<void(const Job &, unsigned int pos)>,
43  "insert_job__jid"_s =
44  ::dyno::method<void(const Job::JobId, unsigned int pos)>,
45 
46  "set_pos__job"_s = dyno::method<void(const Job &, unsigned int)>,
47  "set_pos__jid"_s = dyno::method<void(Job::JobId, unsigned int)>,
48 
49  "get_maximum__unbounded"_s = dyno::method<Resources()>,
50  "get_maximum__bounded"_s =
51  dyno::method<Resources(unsigned int, unsigned int)>,
52 
53  "get_maximum_range__unbounded"_s = dyno::method<MaxRange() const>,
54  "get_maximum_range__bounded"_s =
55  dyno::method<MaxRange(unsigned int, unsigned int) const>,
56 
57  "begin"_s = dyno::method<SkyLineIterator()>,
58  "end"_s = dyno::method<SkyLineIterator()>,
59 
60  "lower_bound"_s = dyno::method<SkyLineIterator(unsigned int)>,
61  "upper_bound"_s = dyno::method<SkyLineIterator(unsigned int)>))
62 {
63 };
64 
65 } // namespace ds
66 
67 /*
68  * Iterator concept map
69  *
70  * Can't happen at ::ds namespace…
71  */
72 template <class T>
73 auto const dyno::default_concept_map<ds::SkyLineIteratorInterface, T> =
74  dyno::make_concept_map("operator++_prefix"_s = [](T & self) { ++self; },
75  "operator++_postfix"_s =
76  [](T & self, int dummy) {
77  (void)dummy;
78  self++;
79  }, // TODO there is an unnecessary copy here
80  "operator--_prefix"_s = [](T & self) { --self; },
81  "operator--_postfix"_s =
82  [](T & self, int dummy) {
83  (void)dummy;
84  self--;
85  },
86  "dereference"_s = [](T & self)
87  -> const ds::SkyLineEvent & { return *self; });
88 
89 /*
90  * SkyLine Concept Map
91  *
92  * This can't happen at ::ds namespace…
93  */
94 template <class T>
95 auto const
96  dyno::default_concept_map<ds::SkyLineInterface, T> = dyno::make_concept_map(
97  "remove_job__job"_s = [](T & self,
98  const Job & job) { self.remove_job(job); },
99  "remove_job__jid"_s = [](T & self,
100  Job::JobId jid) { self.remove_job(jid); },
101  "insert_job__job"_s =
102  [](T & self, const Job & job, unsigned int pos) {
103  self.insert_job(job, pos);
104  },
105  "insert_job__jid"_s =
106  [](T & self, Job::JobId jid, unsigned int pos) {
107  self.insert_job(jid, pos);
108  },
109  "set_pos__job"_s = [](T & self, const Job & job,
110  unsigned int pos) { self.set_pos(job, pos); },
111  "set_pos__jid"_s = [](T & self, Job::JobId jid,
112  unsigned int pos) { self.set_pos(jid, pos); },
113  "get_maximum__unbounded"_s =
114  [](T & self) { return self.get_maximum(); },
115  "get_maximum__bounded"_s =
116  [](T & self, unsigned int lb, unsigned int ub) {
117  return self.get_maximum(lb, ub);
118  },
119  "get_maximum_range__unbounded"_s =
120  [](const T & self) { return self.get_maximum_range(); },
121  "get_maximum_range__bounded"_s =
122  [](const T & self, unsigned int lb, unsigned int ub) {
123  return self.get_maximum_range(lb, ub);
124  },
125  "begin"_s = [](T & self) { return ds::SkyLineIterator(self.begin()); },
126  "end"_s = [](T & self) { return ds::SkyLineIterator(self.end()); },
127  "lower_bound"_s = [](T & self,
128  unsigned int x) { return self.lower_bound(x); },
129  "upper_bound"_s = [](T & self,
130  unsigned int x) { return self.upper_bound(x); }
131 
132  );
133 
134 namespace ds {
135 /*
136  * Iterator wrapper class
137  */
138 class SkyLineIterator {
139 public:
140  typedef std::ptrdiff_t difference_type;
141  typedef SkyLineEvent value_type;
142  typedef const SkyLineEvent & reference;
143  typedef const SkyLineEvent * pointer;
144  typedef std::forward_iterator_tag iterator_category;
145 
146  template <class T>
147  SkyLineIterator(T x) : poly_(x)
148  {}
149 
150  SkyLineIterator(const SkyLineIterator & other) : poly_(other.poly_) {}
151 
152  SkyLineIterator &
153  operator=(const SkyLineIterator other)
154  {
155  this->poly_ = other.poly_;
156  return *this;
157  }
158 
159  SkyLineIterator &
160  operator++()
161  {
162  this->poly_.virtual_("operator++_prefix"_s)();
163  return *this;
164  }
165 
166  SkyLineIterator
167  operator++(int)
168  {
169  SkyLineIterator cpy = *this;
170  this->poly_.virtual_("operator++_postfix"_s)(0);
171  return cpy;
172  }
173 
174  const SkyLineEvent & operator*()
175  {
176  return this->poly_.virtual_("dereference"_s)();
177  }
178 
179  friend bool
180  operator==(const SkyLineIterator & lhs, const SkyLineIterator & rhs)
181  {
182  // TODO should we check this?
183  // assert(lhs.poly_.virtual_("typeid"_s)() ==
184  // rhs.poly_.virtual_("typeid"_s)());
185  return lhs.poly_.virtual_("equal"_s)(lhs.poly_, rhs.poly_);
186  }
187 
188  bool
189  operator!=(const SkyLineIterator & other)
190  {
191  return !(*this == other);
192  }
193 
194  void
195  swap(SkyLineIterator & other)
196  {
197  std::swap(this->poly_, other.poly_);
198  }
199 
200  friend void
201  swap(SkyLineIterator & a, SkyLineIterator & b)
202  {
203  a.swap(b);
204  }
205 
206 private:
207  dyno::poly<SkyLineIteratorInterface,
208  dyno::local_storage<std::max(
209  sizeof(ArraySkyLineBase<true>::iterator),
210  sizeof(TreeSkyLineBase<true, false>::iterator))>,
211  dyno::vtable<dyno::local<dyno::everything>>>
212  poly_;
213 };
214 
215 /*
216  * SkyLine wrapper class
217  */
218 class SkyLine {
219 public:
220  // Convert anything that is compatible into a SkyLine
221  template <class T>
222  SkyLine(T && x) : poly_(std::move(x))
223  {}
224 
225  void
226  remove_job(const Job & job) noexcept
227  {
228  poly_.virtual_("remove_job__job"_s)(job);
229  }
230 
231  void
232  remove_job(Job::JobId jid) noexcept
233  {
234  poly_.virtual_("remove_job__jid"_s)(jid);
235  }
236 
237  void
238  insert_job(const Job & job, unsigned int pos) noexcept
239  {
240  poly_.virtual_("insert_job__job"_s)(job, pos);
241  }
242 
243  void
244  insert_job(Job::JobId jid, unsigned int pos) noexcept
245  {
246  poly_.virtual_("insert_job__jid"_s)(jid, pos);
247  }
248 
249  void
250  set_pos(const Job & job, unsigned int pos) noexcept
251  {
252  poly_.virtual_("set_pos__job"_s)(job, pos);
253  }
254 
255  void
256  set_pos(Job::JobId jid, int pos) noexcept
257  {
258  poly_.virtual_("set_pos__jid"_s)(jid, pos);
259  }
260 
261  Resources
262  get_maximum() noexcept
263  {
264  return poly_.virtual_("get_maximum__unbounded"_s)();
265  }
266 
267  Resources
268  get_maximum(unsigned int lb, unsigned int ub) noexcept
269  {
270  return poly_.virtual_("get_maximum__bounded"_s)(lb, ub);
271  }
272 
273  MaxRange
274  get_maximum_range() const noexcept
275  {
276  return poly_.virtual_("get_maximum_range__unbounded"_s)();
277  }
278 
279  MaxRange
280  get_maximum_range(unsigned int lb, unsigned int ub) const noexcept
281  {
282  return poly_.virtual_("get_maximum_range__bounded"_s)(lb, ub);
283  }
284 
285  SkyLineIterator
286  begin() noexcept
287  {
288  return SkyLineIterator(poly_.virtual_("begin"_s)());
289  }
290 
291  SkyLineIterator
292  end() noexcept
293  {
294  return SkyLineIterator(poly_.virtual_("end"_s)());
295  }
296 
297  SkyLineIterator
298  lower_bound(unsigned int x) noexcept
299  {
300  return SkyLineIterator(poly_.virtual_("lower_bound"_s)(x));
301  }
302 
303  SkyLineIterator
304  upper_bound(unsigned int x) noexcept
305  {
306  return SkyLineIterator(poly_.virtual_("upper_bound"_s)(x));
307  }
308 
309 private:
310  dyno::poly<
311  SkyLineInterface,
312  dyno::local_storage<std::max(sizeof(ArraySkyLineBase<true>),
313  sizeof(TreeSkyLineBase<true, false>))>,
314  dyno::vtable<dyno::local<dyno::everything>>>
315  poly_;
316 };
317 
318 } // namespace ds
319 
320 #endif
Job
A job of an TCPSP instance.
Definition: job.hpp:21