diff --git a/src/buffer.hh b/src/buffer.hh index f3c80afc..260c00a0 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -244,6 +244,58 @@ constexpr Buffer::Flags operator~(Buffer::Flags lhs) return (Buffer::Flags)(~(int)lhs); } +class BufferChangeListener_AutoRegister : public BufferChangeListener +{ +public: + BufferChangeListener_AutoRegister(const Buffer& buffer) + : m_buffer(&buffer) + { + m_buffer->change_listeners().insert(this); + } + + 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; +}; } diff --git a/src/dynamic_selection_list.cc b/src/dynamic_selection_list.cc index bca16293..a258ddd7 100644 --- a/src/dynamic_selection_list.cc +++ b/src/dynamic_selection_list.cc @@ -5,55 +5,12 @@ namespace Kakoune DynamicSelectionList::DynamicSelectionList(const Buffer& buffer, SelectionList selections) - : m_buffer(&buffer), SelectionList(std::move(selections)) + : SelectionList(std::move(selections)), + BufferChangeListener_AutoRegister(buffer) { - m_buffer->change_listeners().insert(this); check_invariant(); } -DynamicSelectionList::~DynamicSelectionList() -{ - m_buffer->change_listeners().erase(this); -} - -DynamicSelectionList::DynamicSelectionList(const DynamicSelectionList& other) - : SelectionList(other), m_buffer(other.m_buffer) -{ - m_buffer->change_listeners().insert(this); -} - -DynamicSelectionList& DynamicSelectionList::operator=(const DynamicSelectionList& other) -{ - SelectionList::operator=((const SelectionList&)other); - if (m_buffer != other.m_buffer) - { - m_buffer->change_listeners().erase(this); - m_buffer = other.m_buffer; - m_buffer->change_listeners().insert(this); - } - check_invariant(); - return *this; -} - -DynamicSelectionList::DynamicSelectionList(DynamicSelectionList&& other) - : SelectionList(std::move(other)), m_buffer(other.m_buffer) -{ - m_buffer->change_listeners().insert(this); -} - -DynamicSelectionList& DynamicSelectionList::operator=(DynamicSelectionList&& other) -{ - SelectionList::operator=(std::move(other)); - if (m_buffer != other.m_buffer) - { - m_buffer->change_listeners().erase(this); - m_buffer = other.m_buffer; - m_buffer->change_listeners().insert(this); - } - check_invariant(); - return *this; -} - DynamicSelectionList& DynamicSelectionList::operator=(SelectionList selections) { SelectionList::operator=(std::move(selections)); @@ -64,9 +21,10 @@ DynamicSelectionList& DynamicSelectionList::operator=(SelectionList selections) void DynamicSelectionList::check_invariant() const { #ifdef KAK_DEBUG + const Buffer* buf = &buffer(); for (auto& sel : *this) { - assert(m_buffer == &sel.buffer()); + assert(buf == &sel.buffer()); sel.check_invariant(); } #endif diff --git a/src/dynamic_selection_list.hh b/src/dynamic_selection_list.hh index 4ae34969..34f4c05c 100644 --- a/src/dynamic_selection_list.hh +++ b/src/dynamic_selection_list.hh @@ -6,32 +6,23 @@ namespace Kakoune { -class DynamicSelectionList : public SelectionList, public BufferChangeListener +class DynamicSelectionList : public SelectionList, + public BufferChangeListener_AutoRegister { public: using iterator = SelectionList::iterator; using const_iterator = SelectionList::const_iterator; DynamicSelectionList(const Buffer& buffer, SelectionList selections = {}); - ~DynamicSelectionList(); - - DynamicSelectionList(const DynamicSelectionList& other); - DynamicSelectionList& operator=(const DynamicSelectionList& other); - DynamicSelectionList(DynamicSelectionList&& other); - DynamicSelectionList& operator=(DynamicSelectionList&& other); DynamicSelectionList& operator=(SelectionList selections); void check_invariant() const; - const Buffer& buffer() const { return *m_buffer; } - private: void on_insert(const BufferIterator& begin, const BufferIterator& end) override; void on_erase(const BufferIterator& begin, const BufferIterator& end) override; - - const Buffer* m_buffer; }; };