mirror of
https://github.com/matrix-construct/construct
synced 2025-01-14 00:34:18 +01:00
ircd::util: Add instance_list pattern utility.
This commit is contained in:
parent
ea097c9f53
commit
3680ae37f2
1 changed files with 53 additions and 1 deletions
|
@ -1038,7 +1038,7 @@ end(const const_iterators<T> &ci)
|
|||
// For objects using the pattern of adding their own instance to a container
|
||||
// in their constructor, storing an iterator as a member, and then removing
|
||||
// themselves using the iterator in their destructor. It is unsafe to do that.
|
||||
// Use this instead.
|
||||
// Use this instead; or better, use ircd::instance_list<>
|
||||
//
|
||||
template<class container,
|
||||
class iterator = typename container::iterator>
|
||||
|
@ -1090,6 +1090,58 @@ struct unique_const_iterator
|
|||
};
|
||||
|
||||
|
||||
/// The instance_list pattern is where every instance of a class registers
|
||||
/// itself in a static list of all instances and removes itself on dtor.
|
||||
/// IRCd Ex. All clients use instance_list so all clients can be listed for
|
||||
/// an administrator or be interrupted and disconnected on server shutdown.
|
||||
///
|
||||
/// `struct myobj : ircd::instance_list<myobj> {};`
|
||||
///
|
||||
/// * The creator of the class no longer has to manually specify what is
|
||||
/// defined here using unique_iterator; however, one still must provide
|
||||
/// linkage for the static list.
|
||||
///
|
||||
/// * The container pointer used by unique_iterator is eliminated here
|
||||
/// because of the static list.
|
||||
///
|
||||
template<class T>
|
||||
struct instance_list
|
||||
{
|
||||
static std::list<T *> list;
|
||||
|
||||
protected:
|
||||
typename decltype(list)::iterator it;
|
||||
|
||||
instance_list(typename decltype(list)::iterator it)
|
||||
:it{std::move(it)}
|
||||
{}
|
||||
|
||||
instance_list()
|
||||
:it{list.emplace(end(list), static_cast<T *>(this))}
|
||||
{}
|
||||
|
||||
instance_list(const instance_list &) = delete;
|
||||
instance_list(instance_list &&o) noexcept
|
||||
:it{std::move(o.it)}
|
||||
{
|
||||
o.it = end(list);
|
||||
}
|
||||
|
||||
instance_list &operator=(const instance_list &) = delete;
|
||||
instance_list &operator=(instance_list &&o) noexcept
|
||||
{
|
||||
std::swap(it, o.it);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~instance_list() noexcept
|
||||
{
|
||||
if(it != end(list))
|
||||
list.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Get the index of a tuple element by address at runtime
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue