aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-11-02 08:39:11 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-11-02 08:39:11 +0000
commit7dd876b56e1bce94b46ffd665377a449f2500eea (patch)
tree913675cab2f917dc3443233692a409318289e329
parentd832a1dd9e9718619bfb7bb7d0e3b48e26e65a33 (diff)
downloadpaludis-7dd876b56e1bce94b46ffd665377a449f2500eea.tar.gz
paludis-7dd876b56e1bce94b46ffd665377a449f2500eea.tar.xz
Fix first lot of breakage
-rw-r--r--paludis/util/create_iterator-fwd.hh33
-rw-r--r--paludis/util/create_iterator-impl.hh106
-rw-r--r--paludis/util/create_iterator.hh93
-rw-r--r--paludis/util/indirect_iterator-fwd.hh44
-rw-r--r--paludis/util/indirect_iterator-impl.hh105
-rw-r--r--paludis/util/indirect_iterator.hh128
-rw-r--r--paludis/util/indirect_iterator_TEST.cc140
-rw-r--r--paludis/util/iterator_funcs.hh66
-rw-r--r--paludis/util/iterator_funcs_TEST.cc75
-rw-r--r--paludis/util/member_iterator-fwd.hh48
-rw-r--r--paludis/util/member_iterator-impl.hh115
-rw-r--r--paludis/util/member_iterator.hh129
-rw-r--r--paludis/util/member_iterator_TEST.cc77
-rw-r--r--paludis/util/wrapped_forward_iterator-fwd.hh29
-rw-r--r--paludis/util/wrapped_forward_iterator-impl.hh155
-rw-r--r--paludis/util/wrapped_forward_iterator.hh115
-rw-r--r--paludis/util/wrapped_output_iterator-fwd.hh29
-rw-r--r--paludis/util/wrapped_output_iterator-impl.hh137
-rw-r--r--paludis/util/wrapped_output_iterator.hh119
19 files changed, 1743 insertions, 0 deletions
diff --git a/paludis/util/create_iterator-fwd.hh b/paludis/util/create_iterator-fwd.hh
new file mode 100644
index 0000000..470621e
--- /dev/null
+++ b/paludis/util/create_iterator-fwd.hh
@@ -0,0 +1,33 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_FWD_HH 1
+
+namespace paludis
+{
+ template <typename Value_, typename Iter_>
+ class CreateInsertIterator;
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>
+ create_inserter(const Iter_ &);
+}
+
+#endif
diff --git a/paludis/util/create_iterator-impl.hh b/paludis/util/create_iterator-impl.hh
new file mode 100644
index 0000000..a012f72
--- /dev/null
+++ b/paludis/util/create_iterator-impl.hh
@@ -0,0 +1,106 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_IMPL_HH 1
+
+#include <paludis/util/create_iterator.hh>
+
+namespace paludis
+{
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>::CreateInsertIterator() :
+ _iter()
+ {
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>::~CreateInsertIterator()
+ {
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>::CreateInsertIterator(const CreateInsertIterator & i) :
+ _iter(i._iter)
+ {
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>::CreateInsertIterator(const Iter_ & i) :
+ _iter(i)
+ {
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_> &
+ CreateInsertIterator<Value_, Iter_>::operator= (const CreateInsertIterator & other)
+ {
+ _iter = other._iter;
+ return *this;
+ }
+
+ template <typename Value_, typename Iter_>
+ template <typename T_>
+ CreateInsertIterator<Value_, Iter_> &
+ CreateInsertIterator<Value_, Iter_>::operator= (const T_ & value)
+ {
+ *_iter = Value_(value);
+ return *this;
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_> &
+ CreateInsertIterator<Value_, Iter_>::operator++ ()
+ {
+ ++_iter;
+ return *this;
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>
+ CreateInsertIterator<Value_, Iter_>::operator++ (int)
+ {
+ CreateInsertIterator result(*this);
+ ++_iter;
+ return result;
+ }
+
+ template <typename Value_, typename Iter_>
+ typename CreateInsertIterator<Value_, Iter_>::pointer
+ CreateInsertIterator<Value_, Iter_>::operator-> ()
+ {
+ return this;
+ }
+
+ template <typename Value_, typename Iter_>
+ typename CreateInsertIterator<Value_, Iter_>::reference
+ CreateInsertIterator<Value_, Iter_>::operator* ()
+ {
+ return *this;
+ }
+
+ template <typename Value_, typename Iter_>
+ CreateInsertIterator<Value_, Iter_>
+ create_inserter(const Iter_ & i)
+ {
+ return CreateInsertIterator<Value_, Iter_>(i);
+ }
+}
+
+#endif
diff --git a/paludis/util/create_iterator.hh b/paludis/util/create_iterator.hh
new file mode 100644
index 0000000..0b4636f
--- /dev/null
+++ b/paludis/util/create_iterator.hh
@@ -0,0 +1,93 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CREATE_ITERATOR_HH 1
+
+#include <iterator>
+#include <paludis/util/create_iterator-fwd.hh>
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+# include <concepts>
+#endif
+
+namespace paludis
+{
+ template <typename Value_, typename Iter_>
+ class CreateInsertIterator
+ {
+ private:
+ Iter_ _iter;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ CreateInsertIterator();
+ ~CreateInsertIterator();
+ CreateInsertIterator(const CreateInsertIterator &);
+ CreateInsertIterator(const Iter_ &);
+
+ CreateInsertIterator & operator= (const CreateInsertIterator &);
+
+ template <typename T_>
+ CreateInsertIterator & operator= (const T_ &);
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef CreateInsertIterator value_type;
+ typedef CreateInsertIterator & reference;
+ typedef CreateInsertIterator * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::output_iterator_tag iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ CreateInsertIterator & operator++ ();
+ CreateInsertIterator operator++ (int);
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> ();
+ reference operator* ();
+
+ ///\}
+ };
+}
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+namespace std
+{
+ template <typename Value_, typename Iter_, typename In_>
+ concept_map OutputIterator<paludis::CreateInsertIterator<Value_, Iter_>, In_>
+ {
+ };
+}
+#endif
+
+#endif
diff --git a/paludis/util/indirect_iterator-fwd.hh b/paludis/util/indirect_iterator-fwd.hh
new file mode 100644
index 0000000..271f9e9
--- /dev/null
+++ b/paludis/util/indirect_iterator-fwd.hh
@@ -0,0 +1,44 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_FWD_HH 1
+
+#include <iterator>
+
+namespace paludis
+{
+ template <typename>
+ struct IndirectIteratorValueType;
+
+ template <typename Iter_, typename Value_ = typename IndirectIteratorValueType<
+ typename std::iterator_traits<Iter_>::value_type>::Type>
+ struct IndirectIterator;
+
+ template <typename Iter_>
+ IndirectIterator<Iter_> indirect_iterator(const Iter_ &);
+
+ template <typename Iter_, typename Value_>
+ bool operator== (const IndirectIterator<Iter_, Value_> &, const IndirectIterator<Iter_, Value_> &);
+
+ template <typename Iter_, typename Value_>
+ bool operator< (const IndirectIterator<Iter_, Value_> &, const IndirectIterator<Iter_, Value_> &);
+}
+
+#endif
diff --git a/paludis/util/indirect_iterator-impl.hh b/paludis/util/indirect_iterator-impl.hh
new file mode 100644
index 0000000..cde8380
--- /dev/null
+++ b/paludis/util/indirect_iterator-impl.hh
@@ -0,0 +1,105 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_IMPL_HH 1
+
+#include <paludis/util/indirect_iterator.hh>
+
+namespace paludis
+{
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_>::IndirectIterator() :
+ _iter()
+ {
+ }
+
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_>::IndirectIterator(const IndirectIterator & i) :
+ _iter(i._iter)
+ {
+ }
+
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_>::IndirectIterator(const Iter_ & i) :
+ _iter(i)
+ {
+ }
+
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_> &
+ IndirectIterator<Iter_, Value_>::operator= (const IndirectIterator & i)
+ {
+ _iter = i._iter;
+ return *this;
+ }
+
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_> &
+ IndirectIterator<Iter_, Value_>::operator++ ()
+ {
+ ++_iter;
+ return *this;
+ }
+
+ template <typename Iter_, typename Value_>
+ IndirectIterator<Iter_, Value_>
+ IndirectIterator<Iter_, Value_>::operator++ (int)
+ {
+ IndirectIterator result(*this);
+ ++_iter;
+ return result;
+ }
+
+ template <typename Iter_, typename Value_>
+ typename IndirectIterator<Iter_, Value_>::pointer
+ IndirectIterator<Iter_, Value_>::operator-> () const
+ {
+ return &**_iter;
+ }
+
+ template <typename Iter_, typename Value_>
+ typename IndirectIterator<Iter_, Value_>::reference
+ IndirectIterator<Iter_, Value_>::operator* () const
+ {
+ return **_iter;
+ }
+
+ template <typename Iter_, typename Value_>
+ bool operator== (const IndirectIterator<Iter_, Value_> & lhs, const IndirectIterator<Iter_, Value_> & rhs)
+ {
+ return lhs._iter == rhs._iter;
+ }
+
+ template <typename Iter_, typename Value_>
+ bool operator< (const IndirectIterator<Iter_, Value_> & lhs, const IndirectIterator<Iter_, Value_> & rhs)
+ {
+ return lhs._iter < rhs._iter;
+ }
+
+ template <typename Iter_>
+ IndirectIterator<Iter_>
+ indirect_iterator(const Iter_ & i)
+ {
+ return IndirectIterator<Iter_>(i);
+ }
+
+}
+
+#endif
diff --git a/paludis/util/indirect_iterator.hh b/paludis/util/indirect_iterator.hh
new file mode 100644
index 0000000..6bf5ce0
--- /dev/null
+++ b/paludis/util/indirect_iterator.hh
@@ -0,0 +1,128 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_INDIRECT_ITERATOR_HH 1
+
+#include <paludis/util/indirect_iterator-fwd.hh>
+#include <paludis/util/operators.hh>
+#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/tr1_type_traits.hh>
+
+namespace paludis
+{
+ template <typename T_>
+ struct IndirectIteratorValueType<T_ *>
+ {
+ typedef T_ Type;
+ };
+
+ template <typename T_>
+ struct IndirectIteratorValueType<tr1::shared_ptr<T_> >
+ {
+ typedef T_ Type;
+ };
+
+ template <typename T_>
+ struct IndirectIteratorValueType<tr1::shared_ptr<const T_> >
+ {
+ typedef const T_ Type;
+ };
+
+ template <typename T_>
+ struct IndirectIteratorValueType<const T_>
+ {
+ typedef typename IndirectIteratorValueType<T_>::Type Type;
+ };
+
+ template <typename T_>
+ struct IndirectIteratorValueType<T_ &>
+ {
+ typedef typename IndirectIteratorValueType<T_>::Type Type;
+ };
+
+ /**
+ * An IndirectIterator turns an iterator over T_ * or tr1::shared_ptr<T_> into an iterator
+ * over T_.
+ *
+ * \ingroup g_iterator
+ * \see indirect_iterator
+ */
+ template <typename Iter_, typename Value_>
+ class IndirectIterator :
+ public relational_operators::HasRelationalOperators
+ {
+ friend bool operator== <> (const IndirectIterator &, const IndirectIterator &);
+ friend bool operator< <> (const IndirectIterator &, const IndirectIterator &);
+
+ private:
+ Iter_ _iter;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ IndirectIterator();
+ IndirectIterator(const IndirectIterator &);
+ IndirectIterator(const Iter_ &);
+
+ IndirectIterator & operator= (const IndirectIterator &);
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef typename tr1::remove_reference<Value_>::type & value_type;
+ typedef typename tr1::remove_reference<Value_>::type & reference;
+ typedef typename tr1::remove_reference<Value_>::type * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef typename std::iterator_traits<Iter_>::iterator_category iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ IndirectIterator & operator++ ();
+ IndirectIterator operator++ (int);
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> () const;
+ reference operator* () const;
+
+ ///\}
+ };
+
+ /**
+ * Construct an IndirectIterator from another iterator.
+ *
+ * \see IndirectIterator
+ * \ingroup g_iterator
+ */
+ template <typename Iter_>
+ IndirectIterator<Iter_> indirect_iterator(const Iter_ & t);
+}
+
+#endif
diff --git a/paludis/util/indirect_iterator_TEST.cc b/paludis/util/indirect_iterator_TEST.cc
new file mode 100644
index 0000000..98498a2
--- /dev/null
+++ b/paludis/util/indirect_iterator_TEST.cc
@@ -0,0 +1,140 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <vector>
+#include <list>
+
+using namespace test;
+using namespace paludis;
+
+namespace
+{
+ struct Deleter
+ {
+ template <typename T_>
+ void operator() (T_ t)
+ {
+ delete t;
+ }
+ };
+}
+
+namespace test_cases
+{
+ struct IndirectIteratorVecCPIntTest : TestCase
+ {
+ IndirectIteratorVecCPIntTest() : TestCase("vector<tr1::shared_ptr<int> >") { }
+
+ void run()
+ {
+ std::vector<tr1::shared_ptr<int> > v;
+ v.push_back(tr1::shared_ptr<int>(new int(5)));
+ v.push_back(tr1::shared_ptr<int>(new int(10)));
+ IndirectIterator<std::vector<tr1::shared_ptr<int> >::iterator, int> vi(v.begin()), vi_end(v.end());
+ TEST_CHECK(vi != vi_end);
+ TEST_CHECK(vi < vi_end);
+ TEST_CHECK(! (vi > vi_end));
+ TEST_CHECK_EQUAL(*vi, 5);
+ TEST_CHECK(++vi != vi_end);
+ TEST_CHECK(vi < vi_end);
+ TEST_CHECK(! (vi > vi_end));
+ TEST_CHECK_EQUAL(*vi, 10);
+ TEST_CHECK(++vi == vi_end);
+ }
+ } test_indirect_iterator_vec_cp_int;
+
+ /**
+ * \test Test IndirectIterator over a list of shared_ptr of int.
+ *
+ */
+ struct IndirectIteratorListCPIntTest : TestCase
+ {
+ IndirectIteratorListCPIntTest() : TestCase("list<tr1::shared_ptr<int> >") { }
+
+ void run()
+ {
+ std::list<tr1::shared_ptr<int> > v;
+ v.push_back(tr1::shared_ptr<int>(new int(5)));
+ v.push_back(tr1::shared_ptr<int>(new int(10)));
+ IndirectIterator<std::list<tr1::shared_ptr<int> >::iterator> vi(v.begin()), vi_end(v.end());
+ TEST_CHECK(vi != vi_end);
+ TEST_CHECK_EQUAL(*vi, 5);
+ TEST_CHECK(++vi != vi_end);
+ TEST_CHECK_EQUAL(*vi, 10);
+ TEST_CHECK(++vi == vi_end);
+ }
+ } test_indirect_iterator_list_cp_int;
+
+ /**
+ * \test Test IndirectIterator over a vector of int *.
+ *
+ */
+ struct IndirectIteratorVecPIntTest : TestCase
+ {
+ IndirectIteratorVecPIntTest() : TestCase("vector<int *>") { }
+
+ void run()
+ {
+ std::vector<int *> v;
+ v.push_back(new int(5));
+ v.push_back(new int(10));
+ IndirectIterator<std::vector<int *>::iterator, int> vi(v.begin()), vi_end(v.end());
+ TEST_CHECK(vi != vi_end);
+ TEST_CHECK(vi < vi_end);
+ TEST_CHECK(! (vi > vi_end));
+ TEST_CHECK_EQUAL(*vi, 5);
+ TEST_CHECK(++vi != vi_end);
+ TEST_CHECK(vi < vi_end);
+ TEST_CHECK(! (vi > vi_end));
+ TEST_CHECK_EQUAL(*vi, 10);
+ TEST_CHECK(++vi == vi_end);
+
+ std::for_each(v.begin(), v.end(), Deleter());
+ }
+ } test_indirect_iterator_vec_p_int;
+
+ /**
+ * \test Test IndirectIterator over a list of int *.
+ *
+ */
+ struct IndirectIteratorListPIntTest : TestCase
+ {
+ IndirectIteratorListPIntTest() : TestCase("list<int *>") { }
+
+ void run()
+ {
+ std::list<int *> v;
+ v.push_back(new int(5));
+ v.push_back(new int(10));
+ IndirectIterator<std::list<int *>::iterator, int> vi(v.begin()), vi_end(v.end());
+ TEST_CHECK(vi != vi_end);
+ TEST_CHECK_EQUAL(*vi, 5);
+ TEST_CHECK(++vi != vi_end);
+ TEST_CHECK_EQUAL(*vi, 10);
+ TEST_CHECK(++vi == vi_end);
+
+ std::for_each(v.begin(), v.end(), Deleter());
+ }
+ } test_indirect_iterator_list_p_int;
+}
+
diff --git a/paludis/util/iterator_funcs.hh b/paludis/util/iterator_funcs.hh
new file mode 100644
index 0000000..700e52c
--- /dev/null
+++ b/paludis/util/iterator_funcs.hh
@@ -0,0 +1,66 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_ITERATOR_FUNCS_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_ITERATOR_FUNCS_HH 1
+
+#include <iterator>
+
+namespace paludis
+{
+ /**
+ * Return a new iterator pointing to the item after i.
+ *
+ * \ingroup g_iterator
+ */
+ template <typename T_>
+ T_ next(const T_ & i)
+ {
+ T_ result(i);
+ return ++result;
+ }
+
+ /**
+ * Return a new iterator advanced by a distance of n.
+ *
+ * \ingroup g_iterator
+ */
+ template <typename T_>
+ T_ next(const T_ & i, const int & n)
+ {
+ T_ result(i);
+ std::advance(result, n);
+ return result;
+ }
+
+ /**
+ * Return a new iterator pointing to the item before i.
+ *
+ * \ingroup g_iterator
+ */
+ template <typename T_>
+ T_ previous(const T_ & i)
+ {
+ T_ result(i);
+ return --result;
+ }
+}
+
+#endif
diff --git a/paludis/util/iterator_funcs_TEST.cc b/paludis/util/iterator_funcs_TEST.cc
new file mode 100644
index 0000000..71f3187
--- /dev/null
+++ b/paludis/util/iterator_funcs_TEST.cc
@@ -0,0 +1,75 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/util/iterator_funcs.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <vector>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct IteratorNextTest : public TestCase
+ {
+ IteratorNextTest() : TestCase("iterator next()") { }
+
+ void run()
+ {
+ std::vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ std::vector<int>::iterator iter(v.begin());
+
+ TEST_CHECK(*(next(iter)) == 2);
+ TEST_CHECK(next(next(next(iter))) == v.end());
+ TEST_CHECK(next(iter, 3) == v.end());
+ iter = next(iter);
+ TEST_CHECK(*(next(iter, 1)) == 3);
+ iter = next(iter);
+ TEST_CHECK(++iter == v.end());
+ }
+ } test_iterator_next;
+
+ /**
+ * \test Test iterator_utilities previous()
+ *
+ */
+ struct IteratorpreviousTest : public TestCase
+ {
+ IteratorpreviousTest() : TestCase("iterator previous()") { }
+
+ void run()
+ {
+ std::vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ std::vector<int>::iterator iter(v.end());
+
+ TEST_CHECK(*(previous(iter)) == 2);
+ TEST_CHECK(previous(previous(iter)) == v.begin());
+ iter = previous(iter);
+ TEST_CHECK(--iter == v.begin());
+ }
+ } test_iterator_previous;
+}
+
diff --git a/paludis/util/member_iterator-fwd.hh b/paludis/util/member_iterator-fwd.hh
new file mode 100644
index 0000000..0a4215d
--- /dev/null
+++ b/paludis/util/member_iterator-fwd.hh
@@ -0,0 +1,48 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_FWD_HH 1
+
+#include <iterator>
+#include <paludis/util/tr1_type_traits.hh>
+
+namespace paludis
+{
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ class MemberIterator;
+
+ template <typename Iterator_>
+ struct FirstIteratorTypes;
+
+ template <typename Iterator_>
+ typename FirstIteratorTypes<Iterator_>::Type
+ first_iterator(Iterator_);
+
+ template <typename Iterator_>
+ struct SecondIteratorTypes;
+
+ template <typename Iterator_>
+ typename SecondIteratorTypes<Iterator_>::Type
+ second_iterator(Iterator_);
+}
+
+#endif
diff --git a/paludis/util/member_iterator-impl.hh b/paludis/util/member_iterator-impl.hh
new file mode 100644
index 0000000..ecae303
--- /dev/null
+++ b/paludis/util/member_iterator-impl.hh
@@ -0,0 +1,115 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_IMPL_HH 1
+
+#include <paludis/util/member_iterator.hh>
+
+namespace paludis
+{
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_>::MemberIterator()
+ {
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_>::MemberIterator(const MemberIterator & other) :
+ _iter(other._iter)
+ {
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_>::MemberIterator(const Iterator_ & iter) :
+ _iter(iter)
+ {
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_> &
+ MemberIterator<Value_, Iterator_, member_>::operator= (const MemberIterator & other)
+ {
+ _iter = other._iter;
+ return *this;
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_> &
+ MemberIterator<Value_, Iterator_, member_>::operator++ ()
+ {
+ ++_iter;
+ return *this;
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ MemberIterator<Value_, Iterator_, member_>
+ MemberIterator<Value_, Iterator_, member_>::operator++ (int)
+ {
+ MemberIterator result(*this);
+ ++_iter;
+ return result;
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ typename MemberIterator<Value_, Iterator_, member_>::pointer
+ MemberIterator<Value_, Iterator_, member_>::operator-> () const
+ {
+ return &((*_iter).*member_);
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ typename MemberIterator<Value_, Iterator_, member_>::reference
+ MemberIterator<Value_, Iterator_, member_>::operator* () const
+ {
+ return (*_iter).*member_;
+ }
+
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ bool
+ MemberIterator<Value_, Iterator_, member_>::operator== (const MemberIterator & other) const
+ {
+ return _iter == other._iter;
+ }
+
+ template <typename Iterator_>
+ typename FirstIteratorTypes<Iterator_>::Type
+ first_iterator(Iterator_ i)
+ {
+ return typename FirstIteratorTypes<Iterator_>::Type(i);
+ }
+
+ template <typename Iterator_>
+ typename SecondIteratorTypes<Iterator_>::Type
+ second_iterator(Iterator_ i)
+ {
+ return typename SecondIteratorTypes<Iterator_>::Type(i);
+ }
+}
+
+#endif
diff --git a/paludis/util/member_iterator.hh b/paludis/util/member_iterator.hh
new file mode 100644
index 0000000..dff07c0
--- /dev/null
+++ b/paludis/util/member_iterator.hh
@@ -0,0 +1,129 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_MEMBER_ITERATOR_HH 1
+
+#include <paludis/util/member_iterator-fwd.hh>
+#include <paludis/util/tr1_type_traits.hh>
+#include <paludis/util/operators.hh>
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+# include <concepts>
+#endif
+
+
+namespace paludis
+{
+ template <typename Iterator_>
+ struct FirstIteratorTypes
+ {
+ typedef MemberIterator<
+ typename tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::first_type,
+ Iterator_,
+ &tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::first>
+ Type;
+ };
+
+ template <typename Iterator_>
+ struct SecondIteratorTypes
+ {
+ typedef MemberIterator<
+ typename tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::second_type,
+ Iterator_,
+ &tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::second>
+ Type;
+ };
+
+ /**
+ * A MemberIterator is a wrapper around a forward iterator to a struct,
+ * selecting one particular member of that struct for the value.
+ *
+ * \ingroup g_iterator
+ * \since 0.26
+ */
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ class MemberIterator :
+ public equality_operators::HasEqualityOperators
+ {
+ private:
+ Iterator_ _iter;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ MemberIterator();
+ MemberIterator(const MemberIterator &);
+ MemberIterator(const Iterator_ &);
+
+ MemberIterator & operator= (const MemberIterator &);
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef typename tr1::remove_const<typename tr1::remove_reference<Value_>::type>::type value_type;
+ typedef const typename tr1::remove_reference<Value_>::type & reference;
+ typedef const typename tr1::remove_reference<Value_>::type * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ MemberIterator & operator++ ();
+ MemberIterator operator++ (int);
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> () const;
+ reference operator* () const;
+
+ ///\}
+
+ ///\name Equality
+ ///\{
+
+ bool operator== (const MemberIterator &) const;
+
+ ///\}
+ };
+}
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+namespace std
+{
+ template <typename Value_, typename Iterator_,
+ Value_ tr1::remove_reference<typename std::iterator_traits<Iterator_>::value_type>::type::* member_>
+ concept_map ForwardIterator<paludis::MemberIterator<Value_, Iterator_, member_> >
+ {
+ };
+}
+#endif
+
+#endif
diff --git a/paludis/util/member_iterator_TEST.cc b/paludis/util/member_iterator_TEST.cc
new file mode 100644
index 0000000..30579ee
--- /dev/null
+++ b/paludis/util/member_iterator_TEST.cc
@@ -0,0 +1,77 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2007 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/util/member_iterator-impl.hh>
+#include <paludis/util/join.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <map>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct SecondIteratorTest : TestCase
+ {
+ SecondIteratorTest() : TestCase("second_iterator") {}
+
+ void run()
+ {
+ typedef std::map<std::string, std::string> M;
+
+ M m;
+ m["I"] = "one";
+ m["II"] = "two";
+ m["III"] = "three";
+ m["IV"] = "four";
+ m["V"] = "five";
+
+ SecondIteratorTypes<M::iterator>::Type it = second_iterator(m.begin());
+ TEST_CHECK(it == it);
+ TEST_CHECK(! (it != it));
+ TEST_CHECK_EQUAL(*it, "one");
+ TEST_CHECK_EQUAL(it->length(), 3U);
+
+ SecondIteratorTypes<M::iterator>::Type it2(it);
+ TEST_CHECK(it == it2);
+ TEST_CHECK(! (it != it2));
+ TEST_CHECK_EQUAL(*++it2, "two");
+ TEST_CHECK_EQUAL(*it2, "two");
+ TEST_CHECK_EQUAL(it2->length(), 3U);
+ TEST_CHECK(it != it2);
+ TEST_CHECK(! (it == it2));
+
+ SecondIteratorTypes<M::iterator>::Type it3(it2);
+ TEST_CHECK(it2 == it3++);
+ TEST_CHECK(it2 != it3);
+ TEST_CHECK_EQUAL(*it3, "three");
+ TEST_CHECK_EQUAL(it3->length(), 5U);
+
+ it3 = it2;
+ TEST_CHECK(it2 == it3);
+ TEST_CHECK_EQUAL(*it3, "two");
+ TEST_CHECK_EQUAL(*it3++, "two");
+
+ TEST_CHECK_EQUAL(join(second_iterator(m.begin()), second_iterator(m.end()), " "), "one two three four five");
+ }
+ } second_iterator_test;
+}
+
diff --git a/paludis/util/wrapped_forward_iterator-fwd.hh b/paludis/util/wrapped_forward_iterator-fwd.hh
new file mode 100644
index 0000000..9b3fa5f
--- /dev/null
+++ b/paludis/util/wrapped_forward_iterator-fwd.hh
@@ -0,0 +1,29 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_FWD_HH 1
+
+namespace paludis
+{
+ template <typename Tag_, typename Value_>
+ struct WrappedForwardIterator;
+}
+
+#endif
diff --git a/paludis/util/wrapped_forward_iterator-impl.hh b/paludis/util/wrapped_forward_iterator-impl.hh
new file mode 100644
index 0000000..a54f862
--- /dev/null
+++ b/paludis/util/wrapped_forward_iterator-impl.hh
@@ -0,0 +1,155 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_IMPL_HH 1
+
+#include <paludis/util/wrapped_forward_iterator.hh>
+
+namespace paludis
+{
+ template <typename Tag_, typename Value_>
+ struct WrappedForwardIterator<Tag_, Value_>::Base
+ {
+ virtual Base * clone() const = 0;
+ virtual void increment() = 0;
+ virtual typename WrappedForwardIterator<Tag_, Value_>::pointer pointer() const = 0;
+ virtual typename WrappedForwardIterator<Tag_, Value_>::reference reference() const = 0;
+ virtual bool equal(const Base *) const = 0;
+
+ virtual ~Base()
+ {
+ }
+ };
+
+ template <typename Tag_, typename Value_>
+ template <typename Iter_>
+ struct WrappedForwardIterator<Tag_, Value_>::BaseImpl :
+ WrappedForwardIterator<Tag_, Value_>::Base
+ {
+ Iter_ i;
+
+ BaseImpl(const Iter_ & ii) :
+ i(ii)
+ {
+ }
+
+ Base * clone() const
+ {
+ return new BaseImpl(i);
+ }
+
+ void increment()
+ {
+ ++i;
+ }
+
+ typename WrappedForwardIterator<Tag_, Value_>::reference reference() const
+ {
+ return *i;
+ }
+
+ typename WrappedForwardIterator<Tag_, Value_>::pointer pointer() const
+ {
+ return i.operator-> ();
+ }
+
+ bool equal(const Base * other) const
+ {
+ return i == static_cast<const BaseImpl *>(other)->i;
+ }
+ };
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_>::WrappedForwardIterator() :
+ _base(0)
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_>::~WrappedForwardIterator()
+ {
+ delete _base;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_>::WrappedForwardIterator(const WrappedForwardIterator & other) :
+ _base(other._base ? other._base->clone() : other._base)
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ template <typename T_>
+ WrappedForwardIterator<Tag_, Value_>::WrappedForwardIterator(const T_ & base) :
+ _base(new BaseImpl<T_>(base))
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_> &
+ WrappedForwardIterator<Tag_, Value_>::operator= (const WrappedForwardIterator<Tag_, Value_> & other)
+ {
+ if (this != &other)
+ _base = other._base ? other._base->clone() : other._base;
+ return *this;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_> &
+ WrappedForwardIterator<Tag_, Value_>::operator++ ()
+ {
+ _base->increment();
+ return *this;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedForwardIterator<Tag_, Value_>
+ WrappedForwardIterator<Tag_, Value_>::operator++ (int)
+ {
+ WrappedForwardIterator result(*this);
+ _base->increment();
+ return result;
+ }
+
+ template <typename Tag_, typename Value_>
+ typename WrappedForwardIterator<Tag_, Value_>::pointer
+ WrappedForwardIterator<Tag_, Value_>::operator-> () const
+ {
+ return _base->pointer();
+ }
+
+ template <typename Tag_, typename Value_>
+ typename WrappedForwardIterator<Tag_, Value_>::reference
+ WrappedForwardIterator<Tag_, Value_>::operator* () const
+ {
+ return _base->reference();
+ }
+
+ template <typename Tag_, typename Value_>
+ bool
+ WrappedForwardIterator<Tag_, Value_>::operator== (const WrappedForwardIterator & other) const
+ {
+ if (! _base)
+ return ! other._base;
+
+ return _base->equal(other._base);
+ }
+}
+
+#endif
diff --git a/paludis/util/wrapped_forward_iterator.hh b/paludis/util/wrapped_forward_iterator.hh
new file mode 100644
index 0000000..f793801
--- /dev/null
+++ b/paludis/util/wrapped_forward_iterator.hh
@@ -0,0 +1,115 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_FORWARD_ITERATOR_HH 1
+
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/operators.hh>
+#include <paludis/util/tr1_type_traits.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/attributes.hh>
+
+#include <iterator>
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+# include <concepts>
+#endif
+
+namespace paludis
+{
+ /**
+ * A WrappedForwardIterator is a generic wrapper around a forward iterator,
+ * hiding the underlying base iterator.
+ *
+ * \ingroup g_iterator
+ * \since 0.26
+ */
+ template <typename Tag_, typename Value_>
+ class PALUDIS_VISIBLE WrappedForwardIterator :
+ public equality_operators::HasEqualityOperators
+ {
+ private:
+ struct Base;
+ template <typename T_> struct BaseImpl;
+
+ Base * _base;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ WrappedForwardIterator();
+ ~WrappedForwardIterator();
+ WrappedForwardIterator(const WrappedForwardIterator &);
+
+ template <typename T_>
+ WrappedForwardIterator(const T_ &);
+
+ WrappedForwardIterator & operator= (const WrappedForwardIterator &);
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef typename tr1::remove_reference<Value_>::type & value_type;
+ typedef typename tr1::remove_reference<Value_>::type & reference;
+ typedef typename tr1::remove_reference<Value_>::type * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ WrappedForwardIterator & operator++ ();
+ WrappedForwardIterator operator++ (int);
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> () const;
+ reference operator* () const;
+
+ ///\}
+
+ ///\name Equality
+ ///\{
+
+ bool operator== (const WrappedForwardIterator &) const;
+
+ ///\}
+ };
+}
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+namespace std
+{
+ template <typename Tag_, typename Value_>
+ concept_map ForwardIterator<paludis::WrappedForwardIterator<Tag_, Value_> >
+ {
+ };
+}
+#endif
+
+#endif
diff --git a/paludis/util/wrapped_output_iterator-fwd.hh b/paludis/util/wrapped_output_iterator-fwd.hh
new file mode 100644
index 0000000..9f15449
--- /dev/null
+++ b/paludis/util/wrapped_output_iterator-fwd.hh
@@ -0,0 +1,29 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_FWD_HH 1
+
+namespace paludis
+{
+ template <typename Tag_, typename Value_>
+ struct WrappedOutputIterator;
+}
+
+#endif
diff --git a/paludis/util/wrapped_output_iterator-impl.hh b/paludis/util/wrapped_output_iterator-impl.hh
new file mode 100644
index 0000000..86248cd
--- /dev/null
+++ b/paludis/util/wrapped_output_iterator-impl.hh
@@ -0,0 +1,137 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_IMPL_HH 1
+
+#include <paludis/util/wrapped_output_iterator.hh>
+
+namespace paludis
+{
+ template <typename Tag_, typename Value_>
+ struct WrappedOutputIterator<Tag_, Value_>::Base
+ {
+ virtual Base * clone() const = 0;
+ virtual void increment() = 0;
+ virtual void assign(const Value_ &) = 0;
+ };
+
+ template <typename Tag_, typename Value_>
+ template <typename Iter_>
+ struct WrappedOutputIterator<Tag_, Value_>::BaseImpl :
+ WrappedOutputIterator<Tag_, Value_>::Base
+ {
+ Iter_ i;
+
+ BaseImpl(const Iter_ & ii) :
+ i(ii)
+ {
+ }
+
+ Base * clone() const
+ {
+ return new BaseImpl(i);
+ }
+
+ void increment()
+ {
+ ++i;
+ }
+
+ void assign(const Value_ & v)
+ {
+ *i = v;
+ }
+ };
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_>::WrappedOutputIterator() :
+ _base(0)
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_>::~WrappedOutputIterator()
+ {
+ delete _base;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_>::WrappedOutputIterator(const WrappedOutputIterator & other) :
+ _base(other._base ? other._base->clone() : other._base)
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ template <typename T_>
+ WrappedOutputIterator<Tag_, Value_>::WrappedOutputIterator(const T_ & base) :
+ _base(new BaseImpl<T_>(base))
+ {
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_> &
+ WrappedOutputIterator<Tag_, Value_>::operator= (const WrappedOutputIterator<Tag_, Value_> & other)
+ {
+ if (this != &other)
+ _base = other._base ? other._base->clone() : other._base;
+ return *this;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_> &
+ WrappedOutputIterator<Tag_, Value_>::operator= (const Value_ & value)
+ {
+ _base->assign(value);
+ return *this;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_> &
+ WrappedOutputIterator<Tag_, Value_>::operator++ ()
+ {
+ _base->increment();
+ return *this;
+ }
+
+ template <typename Tag_, typename Value_>
+ WrappedOutputIterator<Tag_, Value_>
+ WrappedOutputIterator<Tag_, Value_>::operator++ (int)
+ {
+ WrappedOutputIterator result(*this);
+ _base->increment();
+ return result;
+ }
+
+ template <typename Tag_, typename Value_>
+ typename WrappedOutputIterator<Tag_, Value_>::pointer
+ WrappedOutputIterator<Tag_, Value_>::operator-> ()
+ {
+ return this;
+ }
+
+ template <typename Tag_, typename Value_>
+ typename WrappedOutputIterator<Tag_, Value_>::reference
+ WrappedOutputIterator<Tag_, Value_>::operator* ()
+ {
+ return *this;
+ }
+}
+
+#endif
diff --git a/paludis/util/wrapped_output_iterator.hh b/paludis/util/wrapped_output_iterator.hh
new file mode 100644
index 0000000..822c77c
--- /dev/null
+++ b/paludis/util/wrapped_output_iterator.hh
@@ -0,0 +1,119 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_WRAPPED_OUTPUT_ITERATOR_HH 1
+
+#include <paludis/util/wrapped_output_iterator-fwd.hh>
+#include <paludis/util/attributes.hh>
+#include <iterator>
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+# include <concepts>
+#endif
+
+namespace paludis
+{
+ /**
+ * A WrappedOutputIterator is a generic wrapper around an output iterator,
+ * hiding the underlying base iterator.
+ *
+ * \ingroup g_iterator
+ * \since 0.26
+ */
+ template <typename Tag_, typename Value_>
+ class PALUDIS_VISIBLE WrappedOutputIterator
+ {
+ private:
+ struct Base;
+ template <typename T_> struct BaseImpl;
+
+ Base * _base;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ WrappedOutputIterator();
+ ~WrappedOutputIterator();
+ WrappedOutputIterator(const WrappedOutputIterator &);
+
+ template <typename T_>
+ WrappedOutputIterator(const T_ &);
+
+ WrappedOutputIterator & operator= (const WrappedOutputIterator &);
+ WrappedOutputIterator & operator= (const Value_ &);
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef WrappedOutputIterator value_type;
+ typedef WrappedOutputIterator & reference;
+ typedef WrappedOutputIterator * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::output_iterator_tag iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ WrappedOutputIterator & operator++ ();
+ WrappedOutputIterator operator++ (int);
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> ();
+ reference operator* ();
+
+ ///\}
+ };
+}
+
+#ifdef PALUDIS_HAVE_CONCEPTS
+namespace std
+{
+ template <typename Tag_, typename Value_>
+ concept_map OutputIterator<paludis::WrappedOutputIterator<Tag_, Value_>, Value_>
+ {
+ };
+
+ template <typename Tag_, typename Value_>
+ concept_map OutputIterator<paludis::WrappedOutputIterator<Tag_, Value_>, Value_ &>
+ {
+ };
+
+ template <typename Tag_, typename Value_>
+ concept_map OutputIterator<paludis::WrappedOutputIterator<Tag_, Value_>, const Value_>
+ {
+ };
+
+ template <typename Tag_, typename Value_>
+ concept_map OutputIterator<paludis::WrappedOutputIterator<Tag_, Value_>, const Value_ &>
+ {
+ };
+}
+#endif
+
+#endif