Yggdrasill  0.2
intervalmap.hpp
1 //
2 // Created by lukas on 31.08.17.
3 //
4 
5 #ifndef YGG_INTERVALMAP_HPP
6 #define YGG_INTERVALMAP_HPP
7 
8 #include "intervaltree.hpp"
9 #include "list.hpp"
10 #include "options.hpp"
11 #include "rbtree.hpp"
12 #include "size_holder.hpp"
13 
14 namespace ygg {
15 
16 namespace intervalmap_internal {
18 class SegListTag {
19 };
20 class RepresentativeSegListTag {
21 };
22 class InnerRBTTag {
23 };
24 
25 template <class KeyT, class ValueT>
26 class InnerNode
27  : public RBTreeNodeBase<InnerNode<KeyT, ValueT>,
28  TreeOptions<TreeFlags::MULTIPLE>, InnerRBTTag>,
29  public ListNodeBase<InnerNode<KeyT, ValueT>, SegListTag>,
30  public ListNodeBase<InnerNode<KeyT, ValueT>, RepresentativeSegListTag> {
31 public:
32  KeyT point;
33  ValueT aggregate;
34  InnerNode<KeyT, ValueT> * repr;
35 
36  class Compare {
37  public:
38  constexpr bool
39  operator()(const InnerNode<KeyT, ValueT> & lhs,
40  const InnerNode<KeyT, ValueT> & rhs) const
41  {
42  return lhs.point < rhs.point;
43  }
44 
45  constexpr bool
46  operator()(int lhs, const InnerNode<KeyT, ValueT> & rhs) const
47  {
48  return lhs < rhs.point;
49  }
50 
51  constexpr bool
52  operator()(const InnerNode<KeyT, ValueT> & lhs, int rhs) const
53  {
54  return lhs.point < rhs;
55  }
56  };
57 };
59 } // namespace intervalmap_internal
60 
80 template <class KeyT, class ValueT, class Tag = int>
81 class IMapNodeBase {
82 public:
88  using Segment = intervalmap_internal::InnerNode<KeyT, ValueT>;
89 
91  Segment _imap_begin;
92  Segment _imap_end;
93 
94  using value_type = ValueT;
95  using key_type = KeyT;
97 };
98 
110 template <class Node>
111 class IMapNodeTraits {
112 public:
116  using key_type = typename Node::key_type;
120  using value_type = typename Node::value_type;
121 
129  static key_type get_lower(const Node & n) = delete;
130 
138  static key_type get_upper(const Node & n) = delete;
139 
147  static value_type get_value(const Node & n) = delete;
148 
157  static void
158  on_value_changed(typename Node::Segment & seg, const value_type & old_val,
159  const value_type & new_val)
160  {
161  (void)seg;
162  (void)old_val;
163  (void)new_val;
164  }
165 
176  static void
177  on_length_changed(typename Node::Segment & seg)
178  {
179  (void)seg;
180  }
181 
189  static void
190  on_segment_inserted(typename Node::Segment & seg)
191  {
192  (void)seg;
193  }
194 
201  static void
202  on_segment_removed(typename Node::Segment & seg)
203  {
204  (void)seg;
205  }
206 };
207 
240 template <class Node, class NodeTraits, class Options = DefaultOptions,
241  class Tag = int>
242 class IntervalMap {
243 public:
257  using Segment = intervalmap_internal::InnerNode<typename Node::key_type,
258  typename Node::value_type>;
259 
261  static_assert(std::is_base_of<IMapNodeTraits<Node>, NodeTraits>::value,
262  "NodeTraits not properly derived from IMapNodeTraits!");
263 
264  static_assert(Options::multiple,
265  "IntervalMap always allows multiple equal intervals.");
266 
267  using NB =
268  IMapNodeBase<typename Node::key_type, typename Node::value_type, Tag>;
269  static_assert(std::is_base_of<NB, Node>::value,
270  "Node class not properly derived from IMapNodeBase!");
271  using ITree =
272  RBTree<Segment, RBDefaultNodeTraits, TreeOptions<TreeFlags::MULTIPLE>,
273  intervalmap_internal::InnerRBTTag, typename Segment::Compare>;
274  using SegList =
275  List<Segment, TreeOptions<>, intervalmap_internal::SegListTag>;
276  using RepresentativeSegList =
277  List<Segment, TreeOptions<>,
278  intervalmap_internal::RepresentativeSegListTag>;
279  using value_type = typename Node::value_type;
280  using key_type = typename Node::key_type;
282 
290  void insert(Node & n);
291 
299  void remove(Node & n);
300 
310  size_t size() const;
311 
319  bool empty() const;
320 
327  value_type get_aggregate(Segment & s);
328 
330  template <class ConcreteIterator, class InnerIterator>
331  class IteratorBase {
332  public:
333  typedef typename InnerIterator::difference_type difference_type;
334  typedef typename InnerIterator::value_type value_type;
335  typedef typename InnerIterator::reference reference;
336  typedef typename InnerIterator::pointer pointer;
337  typedef std::input_iterator_tag iterator_category;
338 
339  IteratorBase();
340  IteratorBase(const InnerIterator & it, RepresentativeSegList * l);
341  IteratorBase(const ConcreteIterator & other);
342 
343  ConcreteIterator & operator=(const ConcreteIterator & other);
344  ConcreteIterator & operator=(ConcreteIterator && other);
345 
346  bool operator==(const ConcreteIterator & other) const;
347  bool operator!=(const ConcreteIterator & other) const;
348 
349  ConcreteIterator & operator++();
350  ConcreteIterator operator++(int);
351  ConcreteIterator & operator+=(size_t steps);
352  ConcreteIterator operator+(size_t steps) const;
353 
354  ConcreteIterator & operator--();
355  ConcreteIterator operator--(int);
356 
357  reference operator*() const;
358  pointer operator->() const;
359 
360  key_type get_lower() const;
361  key_type get_upper() const;
362  const typename IntervalMap<Node, NodeTraits, Options, Tag>::value_type &
363  get_value() const;
364 
365  private:
366  InnerIterator inner;
367  RepresentativeSegList * l;
368  };
370 
374  class const_iterator
375  : public IteratorBase<const_iterator,
376  typename RepresentativeSegList::const_iterator> {
377  public:
378  using IteratorBase<
379  const_iterator,
380  typename RepresentativeSegList::const_iterator>::IteratorBase;
381  };
382 
386  class iterator
387  : public IteratorBase<iterator,
388  typename RepresentativeSegList::iterator> {
389  public:
390  using IteratorBase<iterator,
391  typename RepresentativeSegList::iterator>::IteratorBase;
392  };
393 
394  const_iterator begin() const;
395  const_iterator end() const;
396  iterator begin();
397  iterator end();
398 
399  void dbg_verify();
400 
401 private:
402  Segment * get_head(Segment * seg);
403 
404  Segment * insert_segment(Segment * seg);
405  void remove_segment(Segment * seg);
406 
407  void repr_now_equal(Segment * a, Segment * b);
408  void repr_now_different(Segment * a, Segment * b);
409  void repr_replaced(Segment * old, Segment * replacement);
410 
411  // TODO FIXME is this needed?
412  iterator find_lower_bound_representative(typename Node::key_type point);
413 
414  ITree t;
415  SegList l;
416  RepresentativeSegList repr_list;
417 
418  SizeHolder<Options::constant_time_size> s;
419 
420  void dbg_verify_list();
421  void dbg_verify_representatives();
422 };
423 
424 } // namespace ygg
425 
426 #include "intervalmap.cpp"
427 
428 #endif // YGG_INTERVALMAP_HPP
Definition: rbtree.hpp:18