9#ifndef slimsig_signal_set_h
10#define slimsig_signal_set_h
21#define _FORCE_INLINE __forceinline
23#define _FORCE_INLINE [[gnu::always_inline]] inline
32template <
class Callback,
class SlotID>
35template <
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>>
156class 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;
170 using pointer =
typename container_type::pointer;
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;
bool operator>=(const OdString &s1, const OdString &s2)
bool operator<=(const OdString &s1, const OdString &s2)
bool operator<(const OdString &s1, const OdString &s2)
bool operator>(const OdString &s1, const OdString &s2)
_FORCE_INLINE void disconnect()
_FORCE_INLINE bool operator==(const basic_slot &other) const
_FORCE_INLINE bool connected() const
basic_slot(slot_id sid, callback fn)
basic_slot(const basic_slot &)=default
std::function< R(Args...)> callback
_FORCE_INLINE const callback * operator->() const
basic_slot & operator=(basic_slot &&)=default
basic_slot(basic_slot &&)=default
_FORCE_INLINE bool operator==(const slot_id &other) const
_FORCE_INLINE const callback & operator*() const
basic_slot(slot_id sid, Arguments &&... args)
basic_slot & operator=(const basic_slot &)=default
iterator erase(const_iterator position)
basic_slot< T, slot_id > slot
bool locked() const noexcept(noexcept(bool(std::declval< FlagType >())))
bool pending_empty() const
const_iterator cbegin() const
typename std::allocator_traits< Allocator >::template rebind_traits< slot >::allocator_type allocator_type
size_type pending_size() const
decltype(slot_id_helper(std::declval< IDGenerator >())) slot_id
size_type active_size() const
typename container_type::value_type value_type
slot_id push(const value_type &value)
typename container_type::reference reference
bool active_empty() const
slot_list(allocator_type alloc)
typename slot::callback callback
iterator find(slot_id index) noexcept
slot_list(slot_list &&)=default
const_iterator cend() const
const_iterator find(slot_id index) const noexcept
typename container_type::pointer pointer
typename container_type::iterator iterator
slot_list(const slot_list &)=default
slot_id emplace_extended(Args &&... args)
std::vector< slot, allocator_type > container_type
typename container_type::const_reference const_reference
iterator erase(const_iterator begin, const_iterator end)
slot_id push(value_type &&value)
const_reference cback() const
typename container_type::size_type size_type
size_type total_size() const
typename container_type::const_iterator const_iterator
slot_id emplace(Args &&... args)
GLsizei const GLfloat * value
_FORCE_INLINE T default_value()
_FORCE_INLINE void default_value< void >()