Add and use a Set template class for recuring small sets

This commit is contained in:
Maxime Coste 2013-01-11 14:28:13 +01:00
parent 79d28e68dc
commit 914ede7a82
7 changed files with 55 additions and 50 deletions

View File

@ -414,19 +414,4 @@ void Buffer::notify_saved()
} }
} }
void Buffer::add_change_listener(BufferChangeListener& listener) const
{
assert(not contains(m_change_listeners, &listener));
m_change_listeners.push_back(&listener);
}
void Buffer::remove_change_listener(BufferChangeListener& listener) const
{
auto it = std::find(m_change_listeners.begin(),
m_change_listeners.end(),
&listener);
assert(it != m_change_listeners.end());
m_change_listeners.erase(it);
}
} }

View File

@ -167,9 +167,7 @@ public:
HookManager& hooks() { return m_hooks; } HookManager& hooks() { return m_hooks; }
const HookManager& hooks() const { return m_hooks; } const HookManager& hooks() const { return m_hooks; }
void add_change_listener(BufferChangeListener& listener) const; Set<BufferChangeListener*>& change_listeners() const { return m_change_listeners; }
void remove_change_listener(BufferChangeListener& listener) const;
private: private:
friend class BufferIterator; friend class BufferIterator;
@ -213,7 +211,7 @@ private:
// this is mutable as adding or removing listeners is not muting the // this is mutable as adding or removing listeners is not muting the
// buffer observable state. // buffer observable state.
mutable std::vector<BufferChangeListener*> m_change_listeners; mutable Set<BufferChangeListener*> m_change_listeners;
OptionManager m_options; OptionManager m_options;
HookManager m_hooks; HookManager m_hooks;

View File

@ -7,19 +7,19 @@ DynamicSelectionList::DynamicSelectionList(const Buffer& buffer,
SelectionList selections) SelectionList selections)
: m_buffer(&buffer), SelectionList(std::move(selections)) : m_buffer(&buffer), SelectionList(std::move(selections))
{ {
m_buffer->add_change_listener(*this); m_buffer->change_listeners().add(this);
check_invariant(); check_invariant();
} }
DynamicSelectionList::~DynamicSelectionList() DynamicSelectionList::~DynamicSelectionList()
{ {
m_buffer->remove_change_listener(*this); m_buffer->change_listeners().remove(this);
} }
DynamicSelectionList::DynamicSelectionList(const DynamicSelectionList& other) DynamicSelectionList::DynamicSelectionList(const DynamicSelectionList& other)
: SelectionList(other), m_buffer(other.m_buffer) : SelectionList(other), m_buffer(other.m_buffer)
{ {
m_buffer->add_change_listener(*this); m_buffer->change_listeners().add(this);
} }
DynamicSelectionList& DynamicSelectionList::operator=(const DynamicSelectionList& other) DynamicSelectionList& DynamicSelectionList::operator=(const DynamicSelectionList& other)
@ -27,9 +27,9 @@ DynamicSelectionList& DynamicSelectionList::operator=(const DynamicSelectionList
SelectionList::operator=((const SelectionList&)other); SelectionList::operator=((const SelectionList&)other);
if (m_buffer != other.m_buffer) if (m_buffer != other.m_buffer)
{ {
m_buffer->remove_change_listener(*this); m_buffer->change_listeners().remove(this);
m_buffer = other.m_buffer; m_buffer = other.m_buffer;
m_buffer->add_change_listener(*this); m_buffer->change_listeners().add(this);
} }
check_invariant(); check_invariant();
return *this; return *this;
@ -38,7 +38,7 @@ DynamicSelectionList& DynamicSelectionList::operator=(const DynamicSelectionList
DynamicSelectionList::DynamicSelectionList(DynamicSelectionList&& other) DynamicSelectionList::DynamicSelectionList(DynamicSelectionList&& other)
: SelectionList(std::move(other)), m_buffer(other.m_buffer) : SelectionList(std::move(other)), m_buffer(other.m_buffer)
{ {
m_buffer->add_change_listener(*this); m_buffer->change_listeners().add(this);
} }
DynamicSelectionList& DynamicSelectionList::operator=(DynamicSelectionList&& other) DynamicSelectionList& DynamicSelectionList::operator=(DynamicSelectionList&& other)
@ -46,9 +46,9 @@ DynamicSelectionList& DynamicSelectionList::operator=(DynamicSelectionList&& oth
SelectionList::operator=(std::move(other)); SelectionList::operator=(std::move(other));
if (m_buffer != other.m_buffer) if (m_buffer != other.m_buffer)
{ {
m_buffer->remove_change_listener(*this); m_buffer->change_listeners().remove(this);
m_buffer = other.m_buffer; m_buffer = other.m_buffer;
m_buffer->add_change_listener(*this); m_buffer->change_listeners().add(this);
} }
check_invariant(); check_invariant();
return *this; return *this;

View File

@ -327,10 +327,10 @@ class LastModifiedRangeListener : public BufferChangeListener
public: public:
LastModifiedRangeListener(Buffer& buffer) LastModifiedRangeListener(Buffer& buffer)
: m_buffer(buffer) : m_buffer(buffer)
{ m_buffer.add_change_listener(*this); } { m_buffer.change_listeners().add(this); }
~LastModifiedRangeListener() ~LastModifiedRangeListener()
{ m_buffer.remove_change_listener(*this); } { m_buffer.change_listeners().remove(this); }
void on_insert(const BufferIterator& begin, const BufferIterator& end) void on_insert(const BufferIterator& begin, const BufferIterator& end)
{ {

View File

@ -8,12 +8,12 @@ namespace Kakoune
FDWatcher::FDWatcher(int fd, Callback callback) FDWatcher::FDWatcher(int fd, Callback callback)
: m_fd{fd}, m_callback{std::move(callback)} : m_fd{fd}, m_callback{std::move(callback)}
{ {
EventManager::instance().register_fd_watcher(this); EventManager::instance().m_fd_watchers.add(this);
} }
FDWatcher::~FDWatcher() FDWatcher::~FDWatcher()
{ {
EventManager::instance().unregister_fd_watcher(this); EventManager::instance().m_fd_watchers.remove(this);
} }
EventManager::EventManager() EventManager::EventManager()
@ -42,7 +42,7 @@ void EventManager::handle_next_events()
const int fd = event.fd; const int fd = event.fd;
if (event.revents or contains(forced, fd)) if (event.revents or contains(forced, fd))
{ {
auto it = std::find_if(m_fd_watchers.begin(), m_fd_watchers.end(), auto it = find_if(m_fd_watchers,
[fd](FDWatcher* w) { return w->fd() == fd; }); [fd](FDWatcher* w) { return w->fd() == fd; });
if (it != m_fd_watchers.end()) if (it != m_fd_watchers.end())
(*it)->run(); (*it)->run();
@ -55,17 +55,5 @@ void EventManager::force_signal(int fd)
m_forced_fd.push_back(fd); m_forced_fd.push_back(fd);
} }
void EventManager::register_fd_watcher(FDWatcher* event)
{
assert(not contains(m_fd_watchers, event));
m_fd_watchers.push_back(event);
}
void EventManager::unregister_fd_watcher(FDWatcher* event)
{
auto it = find(m_fd_watchers, event);
assert(it != m_fd_watchers.end());
m_fd_watchers.erase(it);
}
} }

View File

@ -39,10 +39,7 @@ public:
private: private:
friend class FDWatcher; friend class FDWatcher;
void register_fd_watcher(FDWatcher* watcher); Set<FDWatcher*> m_fd_watchers;
void unregister_fd_watcher(FDWatcher* watcher);
std::vector<FDWatcher*> m_fd_watchers;
std::vector<int> m_forced_fd; std::vector<int> m_forced_fd;
}; };

View File

@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include <algorithm> #include <algorithm>
#include <vector>
namespace Kakoune namespace Kakoune
{ {
@ -206,6 +207,42 @@ const T& clamp(const T& val, const T& min, const T& max)
return (val < min ? min : (val > max ? max : val)); return (val < min ? min : (val > max ? max : val));
} }
// *** set ***
// generic simple set based on vector
template<typename T>
class Set
{
public:
using iterator = typename std::vector<T>::iterator;
using const_iterator = typename std::vector<T>::const_iterator;
void add(T value)
{
assert(not contains(m_values, value));
m_values.push_back(value);
}
void remove(T value)
{
auto it = find(m_values, value);
assert(it != m_values.end());
m_values.erase(it);
}
size_t size() const { return m_values.size(); }
bool empty() const { return m_values.empty(); }
iterator begin() { return m_values.begin(); }
iterator end() { return m_values.end(); }
const_iterator begin() const { return m_values.begin(); }
const_iterator end() const { return m_values.end(); }
private:
std::vector<T> m_values;
};
} }
#endif // utils_hh_INCLUDED #endif // utils_hh_INCLUDED