0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-03 06:08:52 +02:00

ircd::util: Add instance_list pattern utility.

This commit is contained in:
Jason Volk 2017-11-08 14:39:16 -08:00
parent ea097c9f53
commit 3680ae37f2

View file

@ -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
//