297 lines
6.9 KiB
C++
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
|