MTC
cost_queue.h
1 #pragma once
2 
3 #include <queue>
4 #include <list>
5 #include <deque>
6 #include <iostream>
7 #include <algorithm>
8 
10 template <typename T, typename = bool>
11 struct ValueOrPointeeLess : public std::less<T>
12 {};
13 
15 template <typename T>
16 struct ValueOrPointeeLess<T, decltype(*std::declval<T>() < *std::declval<T>())>
17 {
18  bool operator()(const T& x, const T& y) const { return *x < *y; }
19 };
20 
28 template <typename T, typename Compare = ValueOrPointeeLess<T>>
29 class ordered
30 {
31 public:
32  using container_type = std::list<T>;
33  using value_type = typename container_type::value_type;
34  using size_type = typename container_type::size_type;
35  using difference_type = typename container_type::difference_type;
36 
37  using reference = typename container_type::reference;
38  using const_reference = typename container_type::const_reference;
39 
40  using pointer = typename container_type::pointer;
41  using const_pointer = typename container_type::const_pointer;
42 
43  using iterator = typename container_type::iterator;
44  using const_iterator = typename container_type::const_iterator;
45 
46  using reverse_iterator = typename container_type::reverse_iterator;
47  using const_reverse_iterator = typename container_type::const_reverse_iterator;
48 
49 protected:
50  container_type c;
51  Compare comp;
52 
53 public:
55  explicit ordered() {}
56 
57  bool empty() const { return c.empty(); }
58  size_type size() const { return c.size(); }
59 
60  void clear() { c.clear(); }
61 
62  reference top() { return c.front(); }
63  const_reference top() const { return c.front(); }
64  value_type pop() {
65  value_type result(top());
66  c.pop_front();
67  return result;
68  }
69 
70  reference front() { return c.front(); }
71  const_reference front() const { return c.front(); }
72  reference back() { return c.back(); }
73  const_reference back() const { return c.back(); }
74 
75  iterator begin() { return c.begin(); }
76  iterator end() { return c.end(); }
77 
78  const_iterator begin() const { return c.begin(); }
79  const_iterator end() const { return c.end(); }
80  const_iterator cbegin() const { return c.begin(); }
81  const_iterator cend() const { return c.end(); }
82 
83  const_reverse_iterator rbegin() const { return c.rbegin(); }
84  const_reverse_iterator rend() const { return c.rend(); }
85  const_reverse_iterator crbegin() const { return c.rbegin(); }
86  const_reverse_iterator crend() const { return c.rend(); }
87 
89  void sort() { c.sort(comp); }
90 
91  iterator insert(const value_type& item) {
92  iterator at = std::upper_bound(c.begin(), c.end(), item, comp);
93  return c.insert(at, item);
94  }
95  iterator insert(value_type&& item) {
96  iterator at = std::upper_bound(c.begin(), c.end(), item, comp);
97  return c.insert(at, std::move(item));
98  }
99  inline void push(const value_type& item) { insert(item); }
100  inline void push(value_type&& item) { insert(std::move(item)); }
101 
102  iterator erase(const_iterator pos) { return c.erase(pos); }
103 
105  iterator update(iterator& it) {
106  container_type temp;
107  temp.splice(temp.end(), c, it); // move it from c to temp
108  iterator at = std::upper_bound(c.begin(), c.end(), *it, comp);
109  c.splice(at, temp, it);
110  return it;
111  }
112 
114  iterator moveTo(iterator pos, container_type& other, iterator other_pos) {
115  other.splice(other_pos, c, pos);
116  return pos;
117  }
119  iterator moveFrom(iterator pos, container_type& other) {
120  iterator at = std::upper_bound(begin(), end(), *pos, comp);
121  c.splice(at, other, pos);
122  return pos;
123  }
124 
125  template <typename Predicate>
126  void remove_if(Predicate p) {
127  c.remove_if(p);
128  }
129 };
130 
131 namespace detail {
132 
133 template <typename ValueType, typename CostType>
134 struct ItemCostPair : std::pair<ValueType, CostType>
135 {
136  using cost_type = CostType;
137 
138  ItemCostPair(const std::pair<ValueType, CostType>& other) : std::pair<ValueType, CostType>(other) {}
139  ItemCostPair(std::pair<ValueType, CostType>&& other) : std::pair<ValueType, CostType>(std::move(other)) {}
140 
141  inline ValueType& value() { return this->first; }
142  inline const ValueType& value() const { return this->first; }
143 
144  inline CostType cost() const { return this->second; }
145 
146  // comparison only considers cost
147  constexpr bool operator<(const ItemCostPair& other) const { return this->cost() < other.cost(); }
148 };
149 
150 } // namespace detail
151 
152 template <typename ValueType, typename CostType = double,
153  typename Compare = std::less<detail::ItemCostPair<ValueType, CostType>>>
154 class cost_ordered : public ordered<detail::ItemCostPair<ValueType, CostType>, Compare>
155 {
157 
158 public:
159  auto insert(const ValueType& value, const CostType cost) { return base_type::insert(std::make_pair(value, cost)); }
160  auto insert(ValueType&& value, const CostType cost) {
161  return base_type::insert(std::make_pair(std::move(value), cost));
162  }
163 };
Definition: cost_queue.h:155
ordered<ValueType> provides an adapter for a std::list to allow sorting.
Definition: cost_queue.h:30
iterator moveTo(iterator pos, container_type &other, iterator other_pos)
move element pos from this to other container, inserting before other_pos
Definition: cost_queue.h:114
void sort()
explicitly sort container, useful if many items have changed their value
Definition: cost_queue.h:89
ordered()
initialize empty container
Definition: cost_queue.h:55
iterator moveFrom(iterator pos, container_type &other)
move element pos from other container into this one (sorted)
Definition: cost_queue.h:119
iterator update(iterator &it)
update sort position of a single item after changes
Definition: cost_queue.h:105
ValueOrPointeeLess provides correct comparison for plain and pointer-like types.
Definition: cost_queue.h:12
Definition: cost_queue.h:135