LUMIERA.clone/src/lib/observable-list.hpp
Ichthyostega 1a4b6545a0 maximum munch
...feels like X-mas
2016-12-23 04:23:03 +01:00

297 lines
6.9 KiB
C++

/*
observable-list.hpp - Defines the observable std::list class
Copyright (C) Lumiera.org
2008, Joel Holdsworth <joel@airwebreathe.org.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file observable-list.hpp
** This file contains the definition of the observable list class
*/
#ifndef OBSERVABLE_LIST_HPP
#define OBSERVABLE_LIST_HPP
#include <list>
#include <sigc++/sigc++.h>
namespace lumiera
{
/**
* An observable_list is an STL list with an inbuilt sigc++ signal that
* allows observers to be notified when changes are made to the list.
*/
template<class T, class Allocator = std::allocator<T>>
class observable_list
{
public:
/* ===== Typedefs ===== */
typedef typename std::list<T, Allocator>::iterator iterator;
typedef typename std::list<T, Allocator>::const_iterator
const_iterator;
typedef typename std::list<T, Allocator>::iterator reverse_iterator;
typedef typename std::list<T, Allocator>::const_reverse_iterator
const_reverse_iterator;
typedef typename std::list<T, Allocator>::reference reference;
typedef typename std::list<T, Allocator>::const_reference
const_reference;
typedef typename std::list<T, Allocator>::size_type size_type;
public:
/* ===== Constructors ===== */
explicit observable_list(const Allocator& allocator = Allocator()) :
list(allocator) {};
explicit observable_list(size_type n, const T& value = T(),
const Allocator& allocator = Allocator()) :
list(n, value, allocator) {};
template<class InputIterator>
observable_list(InputIterator first, InputIterator last,
const Allocator& allocator = Allocator()) :
list(first, last, allocator) {};
observable_list(const std::list<T,Allocator>& x) :
list(x) {};
observable_list(const observable_list<T,Allocator>& x) :
list(x.list) {};
public:
/* ===== Iterators ===== */
iterator begin() { return list.begin(); }
const_iterator begin() const { return list.begin(); }
iterator end() { return list.end(); }
const_iterator end() const { return list.end(); }
reverse_iterator rbegin() { return list.rbegin(); }
const_reverse_iterator rbegin() const { return list.rbegin(); }
reverse_iterator rend() { return list.rend(); }
const_reverse_iterator rend() const { return list.rend(); }
public:
/* ===== Capacity ===== */
bool empty() const { return list.empty(); };
size_type size() const { return list.size(); };
size_type max_size() const { return list.max_size(); };
void resize(size_type sz, T c = T())
{
list.resize(sz, c);
changed.emit();
}
public:
/* ===== Element Access ===== */
reference front() { return list.front(); };
const_reference front() const { return list.front(); };
reference back() { return list.back(); };
const_reference back() const { return list.back(); };
public:
/* ===== Modifiers ===== */
template<class InputIterator>
void assign(InputIterator first, InputIterator last)
{
list.assign(first, last);
changed.emit();
}
void assign(size_type n, const T& u)
{
list.assign(n, u);
changed.emit();
}
iterator insert(iterator position, const T& x)
{
iterator i = list.insert(position, x);
changed.emit();
return i;
}
void insert(iterator position, size_type n, const T& x)
{
list.insert(position, n, x);
changed.emit();
}
template <class InputIterator>
void insert(iterator position,
InputIterator first, InputIterator last )
{
list.insert(position, first, last);
changed.emit();
}
iterator erase(iterator position)
{
iterator i = list.erase(position);
changed.emit();
return i;
}
iterator erase ( iterator first, iterator last )
{
iterator i = list.erase(first, last);
changed.emit();
return i;
}
void swap(std::list<T, Allocator>& lst)
{
list.swap(lst);
changed.emit();
}
void clear()
{
list.clear();
changed.emit();
}
void push_front(const T& x)
{
list.push_front(x);
changed.emit();
}
void pop_front()
{
list.pop_front();
changed.emit();
}
void push_back(const T& x)
{
list.push_back(x);
changed.emit();
}
void pop_back()
{
list.pop_back();
changed.emit();
}
void splice(iterator position, std::list<T,Allocator>& x)
{
list.splice(position, x);
changed.emit();
}
void splice(iterator position, std::list<T,Allocator>& x, iterator i)
{
list.splice(position, x, i);
changed.emit();
}
void splice(iterator position, std::list<T,Allocator>& x,
iterator first, iterator last)
{
list.splice(position, x, first, last);
changed.emit();
}
void remove(const T& value)
{
list.remove(value);
changed.emit();
}
template <class Predicate>
void remove_if(Predicate pred)
{
list.remove_if(pred);
changed.emit();
}
void unique()
{
list.unique();
}
template<class BinaryPredicate>
void unique(BinaryPredicate binary_pred)
{
list.unique(binary_pred);
}
void merge(std::list<T,Allocator>& x)
{
list.merge(x);
changed.emit();
}
template<class Compare>
void merge(std::list<T,Allocator>& x, Compare comp)
{
list.merge(x, comp);
changed.emit();
}
void sort()
{
list.sort();
changed.emit();
}
template<class Compare>
void sort(Compare comp)
{
list.sort(comp);
changed.emit();
}
void reverse()
{
list.reverse();
changed.emit();
}
public:
/* ===== Conversions ===== */
/**
* Returns a read only reference to the list.
*/
const std::list<T, Allocator>& get_list() const
{
return list;
}
public:
/* ===== Signals ===== */
/**
* Access to the signal which will be emit every time the list is
* changed in some way.
* @return Returns the signal object which will emit notifications.
*/
sigc::signal<void>& signal_changed()
{
return changed;
}
private:
sigc::signal<void> changed;
std::list<T, Allocator> list;
};
} // namespace lumiera
#endif // OBSERVABLE_LIST_HPP