From bbc55e63245e49792aef731dc2ae89756bc61f8c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 6 Dec 2008 23:46:01 +0000 Subject: [PATCH] Added the definition of an observable_list class --- configure.ac | 7 + src/common/Makefile.am | 1 + src/common/observable-list.hpp | 286 +++++++++++++++++++++++++++++++++ 3 files changed, 294 insertions(+) create mode 100644 src/common/observable-list.hpp diff --git a/configure.ac b/configure.ac index 4f705e01b..b21e70b97 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,11 @@ AC_CHECK_HEADER([tr1/memory], , AC_MSG_ERROR([std::tr1 proposed standard extension for shared_ptr missing]) ) + +AC_CHECK_HEADER([boost/foreach.hpp], + , + AC_MSG_ERROR([boost::foreach missing (http://www.boost.org/)]) + ) AC_CHECK_HEADER([boost/shared_ptr.hpp], , @@ -123,6 +128,8 @@ AC_CHECK_HEADER([boost/regex.hpp], AC_LANG_POP([C++]) +PKG_CHECK_MODULES(LUMIERA_GUI_LIBS, [sigc++-2.0 >= 2.0.18]) + ############## Internatinalization #GETTEXT_PACKAGE=gtk-lumiera #AC_SUBST(GETTEXT_PACKAGE) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index a2a9e45a2..71291ef82 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -61,6 +61,7 @@ noinst_HEADERS += \ $(liblumicommon_a_srcdir)/meta/generator.hpp \ $(liblumicommon_a_srcdir)/meta/typelistutil.hpp \ $(liblumicommon_a_srcdir)/util.hpp \ + $(liblumicommon_a_srcdir)/observable-list.hpp \ $(liblumicommon_a_srcdir)/test/mockinjector.hpp \ $(liblumicommon_a_srcdir)/test/suite.hpp \ $(liblumicommon_a_srcdir)/test/testoption.hpp \ diff --git a/src/common/observable-list.hpp b/src/common/observable-list.hpp new file mode 100644 index 000000000..6b27a4d19 --- /dev/null +++ b/src/common/observable-list.hpp @@ -0,0 +1,286 @@ +/* + 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: + // ========== 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