Added the definition of an observable_list class

This commit is contained in:
Joel Holdsworth 2008-12-06 23:46:01 +00:00
parent 0799a4d297
commit bbc55e6324
3 changed files with 294 additions and 0 deletions

View file

@ -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)

View file

@ -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 \

View file

@ -0,0 +1,286 @@
/*
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:
// ========== 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