9 #ifndef slimsig_signal_set_h
10 #define slimsig_signal_set_h
15 #include <type_traits>
21 #define _FORCE_INLINE __forceinline
23 #define _FORCE_INLINE [[gnu::always_inline]] inline
32 template <
class Callback,
class SlotID>
35 template <
class R,
class... Args,
class SlotID>
43 template <
class... Arguments>
44 basic_slot(
slot_id sid, Arguments&&... args) : m_fn(std::forward<Arguments>(args)...), m_slot_id(sid), m_is_connected(bool(m_fn)), m_is_running(
false) {};
52 return m_slot_id == other.m_slot_id;
56 return m_slot_id == other;
60 return m_slot_id < other.m_slot_id;
64 return m_slot_id < other;
68 return m_slot_id > other.m_slot_id;
72 return m_slot_id > other;
76 return m_slot_id <= other;
80 return m_slot_id >= other;
83 explicit operator bool()
const{
84 return m_is_connected;
88 return m_is_connected;
92 m_is_connected =
false;
107 R operator() (Args... args)
const{
111 ~invoke_guard() { slot.m_is_running =
false;}
114 return m_fn(std::forward<Args>(args)...);
152 class IDGenerator = std::size_t,
153 class FlagType = bool,
154 class Allocator = std::allocator<std::function<T>>
156 class slot_list :
public std::enable_shared_from_this<slot_list<T, IDGenerator, FlagType, Allocator>>{
157 using id_generator = IDGenerator;
158 using flag = FlagType;
159 static auto slot_id_helper(IDGenerator gen) -> decltype(gen++);
161 using slot_id = decltype(slot_id_helper(std::declval<IDGenerator>()));
164 using allocator_type =
typename std::allocator_traits<Allocator>::template rebind_traits<slot>::allocator_type;
171 using iterator =
typename container_type::iterator;
180 void lock() { is_locked =
true; }
184 using std::make_move_iterator;
190 ~guard_t() {
locked =
false; pending.clear();};
191 } guard { is_locked, pending };
195 active.insert(active.end(), make_move_iterator(pending.begin()), make_move_iterator(pending.end()));
198 sort(active.begin() +
offset, active.end());
203 bool locked() const noexcept (noexcept(
bool(std::declval<FlagType>()))) {
return is_locked; }
207 auto& queue = !is_locked ? active : pending;
208 auto sid = last_id++;
209 queue.emplace_back({ sid, move(
value)});
215 auto& queue = !is_locked ? active : pending;
216 auto sid = last_id++;
217 queue.emplace_back({ sid, move(
value)});
221 template <
class... Args>
223 auto& queue = !is_locked ? active : pending;
224 auto sid = last_id++;
225 queue.emplace_back(sid, std::forward<Args>(args)...);
229 template <
class U,
class... Args>
231 auto& queue = !is_locked ? active : pending;
232 auto sid = last_id++;
233 queue.emplace_back(sid, U{std::forward<Args>(args)..., {this->shared_from_this(), sid}});
251 inline void clear() { active.clear(); pending.clear(); }
257 auto end = active.end();
260 auto pend = pending.end();
268 auto end = active.cend();
271 auto pend = pending.cend();
279 template <
class Iterator>
282 using std::lower_bound;
285 using std::less_equal;
294 id_generator last_id;