VCCC  2024.05
VisualCamp Common C++ library
slot_group.h
Go to the documentation of this file.
1 # /*
2 # * Created by YongGyu Lee on 2021/06/03.
3 # */
4 #
5 # ifndef VCCC_SIGNAL_SLOT_GROUP_H_
6 # define VCCC_SIGNAL_SLOT_GROUP_H_
7 #
8 # include <algorithm>
9 # include <iterator>
10 # include <list>
11 # include <map>
12 # include <memory>
13 # include <tuple>
14 # include <utility>
15 # include <vector>
16 #
17 # include "vccc/__signal/group_key.h"
18 
19 namespace vccc {
20 
23 };
24 
25 template<typename Group, typename Slot>
27  using group_type = Group;
30 
31  using slot_type = Slot;
32  using slot_ptr_type = std::shared_ptr<slot_type>;
33  using list = std::list<slot_ptr_type>;
34  using list_iterator = typename list::iterator;
35  using map = std::map<group_key_type, list_iterator, group_key_compare_type>;
36  using map_iterator = typename map::iterator;
38 
39  using weak_slot_ptr_type = std::weak_ptr<slot_type>;
40 
43 
44  using insert_token = std::pair<map_iterator, list_iterator>;
45  using weak_slot = std::pair<weak_slot_ptr_type, insert_token>;
46  using weak_slot_list = std::vector<weak_slot>;
47 
49  : list_(), map_(group_key_compare_type {}) {}
50 
51  // insert grouped slot
53  group_key_type key(grouped, group);
54  if (pos == at_back)
55  return insert_back(key, std::move(slot));
56  else
57  return insert_front(key, std::move(slot));
58  }
59 
60  // insert ungrouped slot
63  if (pos == at_back) {
64  key.group_token.first = ungrouped_back;
65  } else {
66  key.group_token.first = ungrouped_front;
67  }
68  return insert_back(key, std::move(slot));
69  }
70 
72  auto group_it = map_.upper_bound(group); // find a upper bound of a group_key
73  list_iterator list_it;
74 
75  if (group_it == map_.end()) {
76  list_it = list_.emplace(list_.end(), std::move(slot));
77  group_it = map_.emplace_hint(group_it, group, list_it);
78  } else {
79  list_it = list_.emplace(group_it->second, std::move(slot));
80  if (group_it->first != group) { // if group does not exist
81  group_it = map_.emplace_hint(group_it, group, list_it);
82  }
83  }
84 
85  return getWeakSlot(group_it, list_it);
86  }
87 
89  map_iterator group_it = map_.lower_bound(group); // find a lower bound of a group_key
90  list_iterator list_it;
91 
92  if (group_it == map_.end()) {
93  list_it = list_.emplace(list_.end(), std::move(slot));
94  group_it = map_.emplace_hint(group_it, group, list_it);
95  } else {
96  if (group_it->first == group) { // if group exists
97  list_it = list_.emplace(group_it->second, std::move(slot));
98  group_it->second = list_it;
99  } else { // group not exists
100  list_it = list_.emplace(group_it->second, std::move(slot));
101  group_it = map_.emplace_hint(group_it, group, list_it);
102  }
103  }
104 
105  return getWeakSlot(group_it, list_it);
106  }
107 
108  iterator begin() { return list_.begin(); }
109  const_iterator begin() const { return list_.begin(); }
110  iterator end() { return list_.end(); }
111  const_iterator end() const { return list_.end(); }
112 
113  auto size() const { return list_.size(); }
114 
115 
116  // remove 1 list element
117  void remove(const insert_token& conn) {
118  auto m_pos = conn.first;
119  auto l_pos = conn.second;
120 
121  auto g_pos = map_.find(m_pos->first);
122  if (g_pos == map_.end())
123  return;
124 
125  auto next_group_l_pos = getNextGroupListPosition(m_pos);
126  if (std::distance(g_pos->second, next_group_l_pos) <= 1) {
127  map_.erase(m_pos);
128  eraseList(l_pos);
129  } else if (m_pos->second == l_pos) {
130  m_pos->second = list_.erase(l_pos);
131  } else {
132  eraseList(l_pos);
133  }
134  }
135 
137  auto g_pos = map_.find(group_key);
138  if (g_pos == map_.end())
139  return;
140 
141  auto next_group_l_pos = getNextGroupListPosition(g_pos);
142  eraseList(g_pos->second, next_group_l_pos);
143  map_.erase(g_pos);
144  }
145 
146  void remove_all() {
147  list_.clear();
148  map_.clear();
149  }
150 
152  return {*index, insert_token{group, index}};
153  }
154 
156  weak_slot_list weak_list;
157  weak_list.reserve(size());
158 
159  for (auto group_it = map_.begin(); group_it != map_.end(); ++group_it) {
160  auto list_end = getNextGroupListPosition(group_it);
161  for (auto list_it = group_it->second; list_it != list_end; ++list_it) {
162  weak_list.emplace_back(getWeakSlot(group_it, list_it));
163  }
164  }
165 
166  return weak_list;
167  }
168 
169  private:
170  void eraseList(list_iterator begin, list_iterator end) {
171  list_.erase(begin, end);
172  }
173 
174  void eraseList(list_iterator it) {
175  if (it == list_.end())
176  return;
177 
178  list_.erase(it);
179  }
180 
181  list_iterator getNextGroupListPosition(map_const_iterator m_pos) const {
182  auto next_group_m_pos = std::next(m_pos);
183  if (next_group_m_pos == map_.end())
184  return list_.end();
185  return next_group_m_pos->second;
186  }
187 
188  list_iterator getListIterator(const map_iterator& m_pos) {
189  if (m_pos == map_.end())
190  return list_.end();
191  return m_pos->second;
192  }
193 
194  list_iterator groupBegin(group_type group) {
195  auto pos = map_.find(group);
196  if (pos == map_.end())
197  return list_.end();
198  return pos->second;
199  }
200 
201  list_iterator groupBeginNoCheck(map_iterator it) const {
202  return it->second;
203  }
204 
205  list_iterator groupEndNoCheck(map_iterator it) const {
206  auto next_group_map_it = std::next(it);
207  if (next_group_map_it == map_.end())
208  return list_.end();
209  return next_group_map_it->second;
210  }
211 
212  mutable list list_;
213  mutable map map_;
214 };
215 
216 } // namespace vccc
217 
218 # endif // VCCC_SIGNAL_SLOT_GROUP_H_
Definition: slot.h:16
constexpr VCCC_INLINE_OR_STATIC detail::next_niebloid next
Definition: next.hpp:65
std::enable_if_t< input_iterator< I >::value, std::conditional_t< detail::constant_iterator< I >::value, I, basic_const_iterator< I > > > const_iterator
Definition: basic_const_iterator.hpp:377
constexpr VCCC_INLINE_OR_STATIC detail::distance_niebloid distance
Definition: distance.hpp:72
Definition: directory.h:12
@ ungrouped_back
Definition: group_key.h:14
@ grouped
Definition: group_key.h:14
@ ungrouped_front
Definition: group_key.h:14
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 0 > key
Definition: key_value.hpp:33
slot_position
Definition: slot_group.h:21
@ at_front
Definition: slot_group.h:22
@ at_back
Definition: slot_group.h:22
Definition: group_key.h:49
Definition: group_key.h:17
Definition: slot_group.h:26
auto size() const
Definition: slot_group.h:113
void remove_group(const group_key_type &group_key)
Definition: slot_group.h:136
typename map::iterator map_iterator
Definition: slot_group.h:36
const_iterator begin() const
Definition: slot_group.h:109
typename list::const_iterator const_iterator
Definition: slot_group.h:42
weak_slot insert_front(group_key_type group, slot_ptr_type slot)
Definition: slot_group.h:88
std::list< slot_ptr_type > list
Definition: slot_group.h:33
Slot slot_type
Definition: slot_group.h:31
void remove(const insert_token &conn)
Definition: slot_group.h:117
typename list::iterator list_iterator
Definition: slot_group.h:34
weak_slot getWeakSlot(map_iterator group, list_iterator index) const
Definition: slot_group.h:151
std::weak_ptr< slot_type > weak_slot_ptr_type
Definition: slot_group.h:39
void remove_all()
Definition: slot_group.h:146
std::shared_ptr< slot_type > slot_ptr_type
Definition: slot_group.h:32
std::vector< weak_slot > weak_slot_list
Definition: slot_group.h:46
std::pair< map_iterator, list_iterator > insert_token
Definition: slot_group.h:44
Group group_type
Definition: slot_group.h:27
list_iterator iterator
Definition: slot_group.h:41
std::pair< weak_slot_ptr_type, insert_token > weak_slot
Definition: slot_group.h:45
std::map< group_key_type, list_iterator, group_key_compare_type > map
Definition: slot_group.h:35
weak_slot insert(group_type group, slot_ptr_type slot, slot_position pos=at_back)
Definition: slot_group.h:52
iterator end()
Definition: slot_group.h:110
const_iterator end() const
Definition: slot_group.h:111
iterator begin()
Definition: slot_group.h:108
weak_slot insert_back(group_key_type group, slot_ptr_type slot)
Definition: slot_group.h:71
weak_slot insert(slot_ptr_type slot, slot_position pos=at_back)
Definition: slot_group.h:61
weak_slot_list getWeakList() const
Definition: slot_group.h:155
grouped_slot_list()
Definition: slot_group.h:48
typename map::const_iterator map_const_iterator
Definition: slot_group.h:37