summaryrefslogtreecommitdiff
path: root/libs/glibmm2/glibmm/containers.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/glibmm2/glibmm/containers.h')
-rw-r--r--libs/glibmm2/glibmm/containers.h372
1 files changed, 372 insertions, 0 deletions
diff --git a/libs/glibmm2/glibmm/containers.h b/libs/glibmm2/glibmm/containers.h
new file mode 100644
index 0000000000..c7090681a3
--- /dev/null
+++ b/libs/glibmm2/glibmm/containers.h
@@ -0,0 +1,372 @@
+// -*- c++ -*-
+#ifndef _GLIBMM_CONTAINERS_H
+#define _GLIBMM_CONTAINERS_H
+
+/* $Id$ */
+
+/* containers.h
+ *
+ * Copyright (C) 1998-2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glib/glist.h>
+#include <glib/gslist.h>
+#include <glibmm/sarray.h> /* for backward compatibility */
+
+#include <iterator>
+#include <glibmmconfig.h>
+
+GLIBMM_USING_STD(bidirectional_iterator_tag)
+GLIBMM_USING_STD(forward_iterator_tag)
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Glib
+{
+
+template <class T> class List_Iterator;
+template <class T> class List_ConstIterator;
+template <class T> class List_ReverseIterator;
+
+// Most of these methods in the non-template classes needs to be moved
+// to implementation.
+
+//Daniel Elstner has ideas about generating these per-widget with m4. murrayc.
+
+
+extern GLIBMM_API gpointer glibmm_null_pointer;
+
+template <class T>
+class List_Iterator_Base
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+} ;
+
+///For instance, List_Iterator< Gtk::Widget >
+template <class T>
+class List_Iterator : public List_Iterator_Base<T>
+{
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename List_Iterator_Base<T>::pointer pointer;
+ typedef typename List_Iterator_Base<T>::reference reference;
+
+ GList* const* head_;
+ GList* node_;
+
+ typedef List_Iterator<T> Self;
+
+ List_Iterator(GList* const& head, GList* node)
+ : head_(&head), node_(node)
+ {}
+
+ List_Iterator()
+ : head_(0), node_(0)
+ {}
+
+ List_Iterator(const Self& src)
+ : head_(src.head_), node_(src.node_)
+ {}
+
+ bool operator==(const Self& src) const { return node_ == src.node_; }
+ bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+ Self& operator++()
+ {
+ if (!node_)
+ node_ = g_list_first(*head_);
+ else
+ node_ = (GList*)g_list_next(node_);
+ return *this;
+ }
+
+ Self operator++(int)
+ {
+ Self tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ Self& operator--()
+ {
+ if (!node_)
+ node_ = g_list_last(*head_);
+ else
+ node_ = (GList*)g_list_previous(node_);
+
+ return *this;
+ }
+
+ Self operator--(int)
+ {
+ Self tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ reference operator*() const
+ {
+ return *(pointer)( node_ ? node_->data : glibmm_null_pointer );
+ }
+
+ pointer operator -> () const { return &operator*(); }
+};
+
+///For instance, SList_Iterator< Gtk::Widget >
+template <class T>
+class SList_Iterator : public List_Iterator_Base<T>
+{
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename List_Iterator_Base<T>::pointer pointer;
+ typedef typename List_Iterator_Base<T>::reference reference;
+
+ GSList* node_;
+ typedef SList_Iterator<T> Self;
+
+ SList_Iterator(GSList* node)
+ : node_(node)
+ {}
+
+ SList_Iterator()
+ : node_(0)
+ {}
+
+ SList_Iterator(const Self& src)
+ : node_(src.node_)
+ {}
+
+ bool operator==(const Self& src) const { return node_ == src.node_; }
+ bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+ Self& operator++()
+ {
+ node_ = g_slist_next(node_);
+ return *this;
+ }
+
+ Self operator++(int)
+ {
+ Self tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ reference operator*() const
+ {
+ g_assert(node_);
+ return reinterpret_cast<T&>( node_ ? node_->data : glibmm_null_pointer );
+ }
+
+ pointer operator -> () const { return &operator*(); }
+};
+
+
+// This iterator variation returns T_IFace (wrapped from T_Impl)
+// For instance, List_Cpp_Iterator<GtkWidget, Gtk::Widget> is a little like std::list<Gtk::Widget>::iterator
+template<class T_Impl, class T_IFace>
+class List_Cpp_Iterator : public List_Iterator_Base<T_IFace>
+{
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef typename List_Iterator_Base<T_IFace>::pointer pointer;
+ typedef typename List_Iterator_Base<T_IFace>::reference reference;
+
+ typedef List_Cpp_Iterator<T_Impl, T_IFace> Self;
+
+ GList** head_;
+ GList* node_;
+
+ bool operator==(const Self& src) const { return node_ == src.node_; }
+ bool operator!=(const Self& src) const { return node_ != src.node_; }
+
+ List_Cpp_Iterator(GList*& head, GList* node )
+ : head_(&head), node_(node )
+ {}
+
+ List_Cpp_Iterator()
+ : head_(0), node_(0)
+ {}
+
+ List_Cpp_Iterator(const Self& src)
+ : head_(src.head_), node_(src.node_)
+ {}
+
+ reference operator*() const
+ {
+ if (node_ && node_->data)
+ {
+ //We copy/paste the widget wrap() implementation here,
+ //because we can not use a specific Glib::wrap(T_Impl) overload here,
+ //because that would be "dependent", and g++ 3.4 does not allow that.
+ //The specific Glib::wrap() overloads don't do anything special anyway.
+ GObject* cobj = static_cast<GObject*>( (*node_).data );
+
+ #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
+ return *(dynamic_cast<pointer>(Glib::wrap_auto(cobj, false /* take_copy */)));
+ #else
+ //We really do need to use dynamic_cast<>, so I expect problems if this code is used. murrayc.
+ return *(static_cast<pointer>(Glib::wrap_auto(cobj, false /* take_copy */)));
+ #endif
+
+ }
+
+ return *(pointer)glibmm_null_pointer;
+ }
+
+ pointer operator->() const { return &operator*(); }
+
+ Self& operator++()
+ {
+ if (!node_)
+ node_ = g_list_first(*head_);
+ else
+ node_ = (GList *)g_list_next(node_);
+
+ return *this;
+ }
+
+ Self operator++(int)
+ {
+ Self tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ Self& operator--()
+ {
+ if (!node_)
+ node_ = g_list_last(*head_);
+ else
+ node_ = (GList *)g_list_previous(node_);
+
+ return *this;
+ }
+
+ Self operator--(int)
+ {
+ Self tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+};
+
+template <class T_Base>
+class List_ReverseIterator: private T_Base
+{
+public:
+ typedef typename T_Base::iterator_category iterator_category;
+ typedef typename T_Base::size_type size_type;
+ typedef typename T_Base::difference_type difference_type;
+
+ typedef typename T_Base::value_type value_type;
+ typedef typename T_Base::pointer pointer;
+ typedef typename T_Base::reference reference;
+
+ typedef List_ReverseIterator<T_Base> Self;
+
+ bool operator==(const Self& src) const { return T_Base::operator==(src); }
+ bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
+
+ List_ReverseIterator(GList* const& head, GList* node)
+ : T_Base(head, node)
+ {}
+
+ List_ReverseIterator()
+ : T_Base()
+ {}
+
+ List_ReverseIterator(const Self& src)
+ : T_Base(src)
+ {}
+
+ List_ReverseIterator(const T_Base& src)
+ : T_Base(src)
+ { ++(*this); }
+
+
+ Self& operator++() {T_Base::operator--(); return *this;}
+ Self& operator--() {T_Base::operator++(); return *this;}
+ Self operator++(int) {Self src = *this; T_Base::operator--(); return src;}
+ Self operator--(int) {Self src = *this; T_Base::operator++(); return src;}
+
+ reference operator*() const { return T_Base::operator*(); }
+ pointer operator->() const { return T_Base::operator->(); }
+};
+
+template <class T_Base>
+class List_ConstIterator: public T_Base
+{
+public:
+ typedef typename T_Base::iterator_category iterator_category;
+ typedef typename T_Base::size_type size_type;
+ typedef typename T_Base::difference_type difference_type;
+
+ typedef const typename T_Base::value_type value_type;
+ typedef const typename T_Base::pointer pointer;
+ typedef const typename T_Base::reference reference;
+
+ typedef List_ConstIterator<T_Base> Self;
+
+ bool operator==(const Self& src) const { return T_Base::operator==(src); }
+ bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
+
+ List_ConstIterator(GList* const& head, GList* node)
+ : T_Base(head, node)
+ {}
+
+ List_ConstIterator()
+ : T_Base()
+ {}
+
+ List_ConstIterator(const Self& src)
+ : T_Base(src)
+ {}
+
+ List_ConstIterator(const T_Base& src)
+ : T_Base(src)
+ {}
+
+ Self& operator++() {T_Base::operator++(); return *this;}
+ Self& operator--() {T_Base::operator--(); return *this;}
+ Self operator++(int) {Self src = *this; T_Base::operator++(); return src;}
+ Self operator--(int) {Self src = *this; T_Base::operator--(); return src;}
+
+ reference operator*() const { return T_Base::operator*(); }
+ pointer operator->() const { return T_Base::operator->(); }
+};
+
+} // namespace Glib
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+#endif /* _GLIBMM_CONTAINERS_H */
+