Extract AutoRegister logic to a helper class
This commit is contained in:
parent
b266035c71
commit
a18241a03b
|
@ -244,57 +244,28 @@ constexpr Buffer::Flags operator~(Buffer::Flags lhs)
|
|||
return (Buffer::Flags)(~(int)lhs);
|
||||
}
|
||||
|
||||
class BufferChangeListener_AutoRegister : public BufferChangeListener
|
||||
struct BufferListenerRegisterFuncs
|
||||
{
|
||||
static void insert(const Buffer& buffer, BufferChangeListener& listener)
|
||||
{
|
||||
buffer.change_listeners().insert(&listener);
|
||||
}
|
||||
static void remove(const Buffer& buffer, BufferChangeListener& listener)
|
||||
{
|
||||
buffer.change_listeners().erase(&listener);
|
||||
}
|
||||
};
|
||||
|
||||
class BufferChangeListener_AutoRegister
|
||||
: public BufferChangeListener,
|
||||
public AutoRegister<BufferChangeListener_AutoRegister,
|
||||
BufferListenerRegisterFuncs, const Buffer>
|
||||
{
|
||||
public:
|
||||
BufferChangeListener_AutoRegister(const Buffer& buffer)
|
||||
: m_buffer(&buffer)
|
||||
{
|
||||
m_buffer->change_listeners().insert(this);
|
||||
}
|
||||
: AutoRegister(buffer) {}
|
||||
|
||||
BufferChangeListener_AutoRegister(const BufferChangeListener_AutoRegister& other)
|
||||
: m_buffer(other.m_buffer)
|
||||
{
|
||||
m_buffer->change_listeners().insert(this);
|
||||
}
|
||||
|
||||
BufferChangeListener_AutoRegister(BufferChangeListener_AutoRegister&& other)
|
||||
: m_buffer(other.m_buffer)
|
||||
{
|
||||
m_buffer->change_listeners().insert(this);
|
||||
}
|
||||
|
||||
~BufferChangeListener_AutoRegister()
|
||||
{
|
||||
m_buffer->change_listeners().erase(this);
|
||||
}
|
||||
|
||||
BufferChangeListener_AutoRegister& operator=(const BufferChangeListener_AutoRegister& other)
|
||||
{
|
||||
if (m_buffer != other.m_buffer)
|
||||
{
|
||||
m_buffer->change_listeners().erase(this);
|
||||
m_buffer = other.m_buffer;
|
||||
m_buffer->change_listeners().insert(this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BufferChangeListener_AutoRegister& operator=(BufferChangeListener_AutoRegister&& other)
|
||||
{
|
||||
if (m_buffer != other.m_buffer)
|
||||
{
|
||||
m_buffer->change_listeners().erase(this);
|
||||
m_buffer = other.m_buffer;
|
||||
m_buffer->change_listeners().insert(this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Buffer& buffer() const { return *m_buffer; }
|
||||
private:
|
||||
const Buffer* m_buffer;
|
||||
const Buffer& buffer() const { return registry(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
57
src/utils.hh
57
src/utils.hh
|
@ -227,6 +227,63 @@ const T& clamp(const T& val, const T& min, const T& max)
|
|||
return (val < min ? min : (val > max ? max : val));
|
||||
}
|
||||
|
||||
// *** AutoRegister: RAII handling of value semantics registering classes ***
|
||||
|
||||
template<typename EffectiveType, typename RegisterFuncs, typename Registry>
|
||||
class AutoRegister
|
||||
{
|
||||
public:
|
||||
AutoRegister(Registry& registry)
|
||||
: m_registry(®istry)
|
||||
{
|
||||
RegisterFuncs::insert(*m_registry, effective_this());
|
||||
}
|
||||
|
||||
AutoRegister(const AutoRegister& other)
|
||||
: m_registry(other.m_registry)
|
||||
{
|
||||
RegisterFuncs::insert(*m_registry, effective_this());
|
||||
}
|
||||
|
||||
AutoRegister(AutoRegister&& other)
|
||||
: m_registry(other.m_registry)
|
||||
{
|
||||
RegisterFuncs::insert(*m_registry, effective_this());
|
||||
}
|
||||
|
||||
~AutoRegister()
|
||||
{
|
||||
RegisterFuncs::remove(*m_registry, effective_this());
|
||||
}
|
||||
|
||||
AutoRegister& operator=(const AutoRegister& other)
|
||||
{
|
||||
if (m_registry != other.m_registry)
|
||||
{
|
||||
RegisterFuncs::remove(*m_registry, effective_this());
|
||||
m_registry = other.m_registry;
|
||||
RegisterFuncs::insert(*m_registry, effective_this());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AutoRegister& operator=(AutoRegister&& other)
|
||||
{
|
||||
if (m_registry != other.m_registry)
|
||||
{
|
||||
RegisterFuncs::remove(*m_registry, effective_this());
|
||||
m_registry = other.m_registry;
|
||||
RegisterFuncs::insert(*m_registry, effective_this());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Registry& registry() const { return *m_registry; }
|
||||
|
||||
private:
|
||||
EffectiveType& effective_this() { return static_cast<EffectiveType&>(*this); }
|
||||
Registry* m_registry;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // utils_hh_INCLUDED
|
||||
|
|
Loading…
Reference in New Issue
Block a user