/* observable-list.hpp - Defines the observable std::list class Copyright (C) Lumiera.org 2008, Joel Holdsworth 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 #include 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 observable_list { public: /* ===== Typedefs ===== */ typedef typename std::list::iterator iterator; typedef typename std::list::const_iterator const_iterator; typedef typename std::list::iterator reverse_iterator; typedef typename std::list::const_reverse_iterator const_reverse_iterator; typedef typename std::list::reference reference; typedef typename std::list::const_reference const_reference; typedef typename std::list::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 observable_list(InputIterator first, InputIterator last, const Allocator& allocator = Allocator()) : list(first, last, allocator) {}; observable_list(const std::list& x) : list(x) {}; observable_list(const observable_list& 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 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 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& 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& x) { list.splice(position, x); changed.emit(); } void splice(iterator position, std::list& x, iterator i) { list.splice(position, x, i); changed.emit(); } void splice(iterator position, std::list& x, iterator first, iterator last) { list.splice(position, x, first, last); changed.emit(); } void remove(const T& value) { list.remove(value); changed.emit(); } template void remove_if(Predicate pred) { list.remove_if(pred); changed.emit(); } void unique() { list.unique(); } template void unique(BinaryPredicate binary_pred) { list.unique(binary_pred); } void merge(std::list& x) { list.merge(x); changed.emit(); } template void merge(std::list& x, Compare comp) { list.merge(x, comp); changed.emit(); } void sort() { list.sort(); changed.emit(); } template 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& 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& signal_changed() { return changed; } private: sigc::signal changed; std::list list; }; } // namespace lumiera #endif // OBSERVABLE_LIST_HPP