Fcitx
handlertable.h
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_HANDLERTABLE_H_
8 #define _FCITX_UTILS_HANDLERTABLE_H_
9 
10 #include <cstddef>
11 #include <functional>
12 #include <memory>
13 #include <tuple>
14 #include <unordered_map>
15 #include <utility>
16 #include <fcitx-utils/handlertable_details.h> // IWYU pragma: export
17 #include <fcitx-utils/intrusivelist.h>
18 #include <fcitx-utils/macros.h>
19 #include <fcitx-utils/misc.h>
20 
21 namespace fcitx {
22 
23 template <typename T>
25 
26 template <typename T>
28 
29 template <typename T>
30 class HandlerTable {
31 public:
32  HandlerTable() = default;
33  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE(HandlerTable)
34 
35  template <typename... Args>
36  FCITX_NODISCARD std::unique_ptr<HandlerTableEntry<T>> add(Args &&...args) {
37  auto result = std::make_unique<ListHandlerTableEntry<T>>(
38  std::forward<Args>(args)...);
39  handlers_.push_back(*result);
40  return result;
41  }
42 
43  HandlerTableView<T> view() const {
44  return {handlers_.begin(), handlers_.end()};
45  }
46 
47  size_t size() const { return handlers_.size(); }
48  bool empty() const { return size() == 0; }
49 
50 private:
52 };
53 
54 template <typename Key, typename T>
56  friend class MultiHandlerTableEntry<Key, T>;
57  using map_type =
58  std::unordered_map<Key,
60 
61 public:
62  MultiHandlerTable(std::function<bool(const Key &)> addKey = {},
63  std::function<void(const Key &)> removeKey = {})
64  : addKey_(std::move(addKey)), removeKey_(std::move(removeKey)) {}
65 
66  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE(MultiHandlerTable)
67 
68  template <typename M>
69  FCITX_NODISCARD std::unique_ptr<HandlerTableEntry<T>> add(const Key &key,
70  M &&t) {
71  auto iter = keyToHandlers_.find(key);
72  if (iter == keyToHandlers_.end()) {
73  if (addKey_) {
74  if (!addKey_(key)) {
75  return nullptr;
76  }
77  }
78  iter = keyToHandlers_
79  .emplace(std::piecewise_construct,
80  std::forward_as_tuple(key),
81  std::forward_as_tuple())
82  .first;
83  }
84  auto result = std::make_unique<MultiHandlerTableEntry<Key, T>>(
85  this, key, std::forward<M>(t));
86  iter->second.push_back(*result);
87  return result;
88  }
89 
90  HandlerTableView<T> view(const Key &key) {
91  auto iter = keyToHandlers_.find(key);
92  if (iter == keyToHandlers_.end()) {
93  return {};
94  }
95  return {iter->second.begin(), iter->second.end()};
96  }
97 
98  bool hasKey(const Key &key) const {
99  auto iter = keyToHandlers_.find(key);
100  return iter != keyToHandlers_.end();
101  }
102 
105  keyToHandlers_.begin()),
107  keyToHandlers_.end())};
108  }
109 
110 private:
111  void postRemove(const Key &k) {
112  auto iter = keyToHandlers_.find(k);
113  if (iter != keyToHandlers_.end() && iter->second.empty()) {
114  if (removeKey_) {
115  removeKey_(k);
116  }
117  keyToHandlers_.erase(iter);
118  }
119  }
120  std::unordered_map<Key, IntrusiveListFor<MultiHandlerTableEntry<Key, T>>>
121  keyToHandlers_;
122  std::function<bool(const Key &)> addKey_;
123  std::function<void(const Key &)> removeKey_;
124 };
125 } // namespace fcitx
126 
127 #endif // _FCITX_UTILS_HANDLERTABLE_H_
Definition: action.cpp:17