aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-19 20:34:41 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-19 20:34:41 +0100
commit673b696a13c3cf7049df4b8810397aedaa1c3d14 (patch)
tree5c6240b0954b25146ebb5cc18eed7912c910cf44
parenta436158492bc800e1e588b96f3e00037bfe45f10 (diff)
downloadpaludis-673b696a13c3cf7049df4b8810397aedaa1c3d14.tar.gz
paludis-673b696a13c3cf7049df4b8810397aedaa1c3d14.tar.xz
EnumIterator
-rw-r--r--.gitignore1
-rw-r--r--paludis/ndbam_merger.cc11
-rw-r--r--paludis/repositories/e/vdb_merger.cc11
-rw-r--r--paludis/util/enum_iterator-fwd.hh34
-rw-r--r--paludis/util/enum_iterator.cc21
-rw-r--r--paludis/util/enum_iterator.hh151
-rw-r--r--paludis/util/enum_iterator_TEST.cc65
-rw-r--r--paludis/util/files.m41
8 files changed, 285 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore
index 2db0290..088a49b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -369,6 +369,7 @@ paludis-*.*.*.tar.bz2
/paludis/util/destringify_TEST
/paludis/util/dir_iterator_TEST
/paludis/util/echo_functions.bash
+/paludis/util/enum_iterator_TEST
/paludis/util/fast_unique_copy_TEST
/paludis/util/forward_parallel_for_each_TEST
/paludis/util/fs_entry_TEST
diff --git a/paludis/ndbam_merger.cc b/paludis/ndbam_merger.cc
index 3b60761..166468c 100644
--- a/paludis/ndbam_merger.cc
+++ b/paludis/ndbam_merger.cc
@@ -28,6 +28,7 @@
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/options.hh>
#include <paludis/util/make_named_values.hh>
+#include <paludis/util/enum_iterator.hh>
#include <paludis/output_manager.hh>
#include <paludis/util/safe_ofstream.hh>
#include <paludis/util/safe_ifstream.hh>
@@ -283,13 +284,13 @@ std::string
NDBAMMerger::make_arrows(const MergeStatusFlags & flags) const
{
std::string result(">>>");
- for (MergeStatusFlag m(static_cast<MergeStatusFlag>(0)), m_end(last_msi) ; m != m_end ;
- m = static_cast<MergeStatusFlag>(static_cast<long>(m) + 1))
+ for (EnumIterator<MergeStatusFlag> m, m_end(last_msi) ;
+ m != m_end ; ++m)
{
- if (! flags[m])
+ if (! flags[*m])
continue;
- switch (m)
+ switch (*m)
{
case msi_unlinked_first:
result[0] = '<';
@@ -327,7 +328,7 @@ NDBAMMerger::make_arrows(const MergeStatusFlags & flags) const
break;
}
- throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(m)) + "'");
+ throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(*m)) + "'");
}
return result;
diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc
index 3acbd94..60e309c 100644
--- a/paludis/repositories/e/vdb_merger.cc
+++ b/paludis/repositories/e/vdb_merger.cc
@@ -29,6 +29,7 @@
#include <paludis/util/strip.hh>
#include <paludis/util/options.hh>
#include <paludis/util/make_named_values.hh>
+#include <paludis/util/enum_iterator.hh>
#include <paludis/output_manager.hh>
#include <paludis/util/safe_ofstream.hh>
#include <paludis/util/safe_ifstream.hh>
@@ -331,13 +332,13 @@ std::string
VDBMerger::make_arrows(const MergeStatusFlags & flags) const
{
std::string result(">>>");
- for (MergeStatusFlag m(static_cast<MergeStatusFlag>(0)), m_end(last_msi) ; m != m_end ;
- m = static_cast<MergeStatusFlag>(static_cast<long>(m) + 1))
+ for (EnumIterator<MergeStatusFlag> m, m_end(last_msi) ;
+ m != m_end ; ++m)
{
- if (! flags[m])
+ if (! flags[*m])
continue;
- switch (m)
+ switch (*m)
{
case msi_unlinked_first:
result[0] = '<';
@@ -374,7 +375,7 @@ VDBMerger::make_arrows(const MergeStatusFlags & flags) const
case last_msi:
break;
}
- throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(m)) + "'");
+ throw InternalError(PALUDIS_HERE, "Unhandled MergeStatusFlag '" + stringify(static_cast<long>(*m)) + "'");
}
return result;
diff --git a/paludis/util/enum_iterator-fwd.hh b/paludis/util/enum_iterator-fwd.hh
new file mode 100644
index 0000000..39e0b05
--- /dev/null
+++ b/paludis/util/enum_iterator-fwd.hh
@@ -0,0 +1,34 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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_ENUM_ITERATOR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_ENUM_ITERATOR_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ template <typename E_>
+ struct EnumIterator;
+
+ template <typename E_>
+ EnumIterator<E_> enum_iterator(const E_) PALUDIS_ATTRIBUTE((warn_unused_result));
+}
+
+#endif
diff --git a/paludis/util/enum_iterator.cc b/paludis/util/enum_iterator.cc
new file mode 100644
index 0000000..e1b068e
--- /dev/null
+++ b/paludis/util/enum_iterator.cc
@@ -0,0 +1,21 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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
+ */
+
+#include <paludis/util/enum_iterator.hh>
+
diff --git a/paludis/util/enum_iterator.hh b/paludis/util/enum_iterator.hh
new file mode 100644
index 0000000..3214c9e
--- /dev/null
+++ b/paludis/util/enum_iterator.hh
@@ -0,0 +1,151 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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
+ */
+
+#include <paludis/util/enum_iterator-fwd.hh>
+#include <paludis/util/operators.hh>
+#include <iterator>
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_ENUM_ITERATOR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_ENUM_ITERATOR_HH 1
+
+namespace paludis
+{
+ /**
+ * An iterator for iterating over enums.
+ *
+ * \since 0.41
+ * \ingroup g_iterator
+ */
+ template <typename E_>
+ class EnumIterator :
+ public relational_operators::HasRelationalOperators
+ {
+ private:
+ E_ _value;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ EnumIterator() :
+ _value(static_cast<E_>(0))
+ {
+ }
+
+ EnumIterator(const EnumIterator & other) :
+ _value(other._value)
+ {
+ }
+
+ explicit EnumIterator(const E_ e) :
+ _value(e)
+ {
+ }
+
+
+ EnumIterator & operator= (const EnumIterator & other)
+ {
+ _value = other._value;
+ return *this;
+ }
+
+ ///\}
+
+ ///\name Standard library typedefs
+ ///\{
+
+ typedef E_ & value_type;
+
+ typedef E_ & reference;
+ typedef const E_ & const_reference;
+
+ typedef E_ * pointer;
+ typedef const E_ * const_pointer;
+
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ ///\}
+
+ ///\name Increment
+ ///\{
+
+ EnumIterator & operator++ ()
+ {
+ _value = static_cast<E_>(_value + 1);
+ return *this;
+ }
+
+ EnumIterator operator++ (int)
+ {
+ EnumIterator result(*this);
+ ++result;
+ return result;
+ }
+
+ ///\}
+
+ ///\name Dereference
+ ///\{
+
+ pointer operator-> ()
+ {
+ return &_value;
+ }
+
+ reference operator* ()
+ {
+ return _value;
+ }
+
+ const_pointer operator-> () const
+ {
+ return &_value;
+ }
+
+ const_reference operator* () const
+ {
+ return _value;
+ }
+
+ ///\}
+
+ ///\name Comparisons
+
+ bool operator== (const EnumIterator & other) const
+ {
+ return **this == *other;
+ }
+
+ bool operator< (const EnumIterator & other) const
+ {
+ return **this < *other;
+ }
+
+ ///\}
+ };
+
+ template <typename E_>
+ EnumIterator<E_> enum_iterator(const E_ e)
+ {
+ return EnumIterator<E_>(e);
+ }
+}
+
+#endif
diff --git a/paludis/util/enum_iterator_TEST.cc b/paludis/util/enum_iterator_TEST.cc
new file mode 100644
index 0000000..5cf4509
--- /dev/null
+++ b/paludis/util/enum_iterator_TEST.cc
@@ -0,0 +1,65 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 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
+ */
+
+#include <paludis/util/enum_iterator.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ enum Numbers
+ {
+ one,
+ two,
+ three,
+ last_number
+ };
+}
+
+namespace test_cases
+{
+ struct EnumIteratorTest : TestCase
+ {
+ EnumIteratorTest() : TestCase("enum iterator") { }
+
+ void run()
+ {
+ EnumIterator<Numbers> n, n_end(last_number);
+
+ TEST_CHECK(n != n_end);
+ TEST_CHECK_EQUAL(*n, one);
+ ++n;
+
+ TEST_CHECK(n != n_end);
+ TEST_CHECK_EQUAL(*n, two);
+ ++n;
+
+ TEST_CHECK(n != n_end);
+ TEST_CHECK_EQUAL(*n, three);
+ ++n;
+
+ TEST_CHECK(n == n_end);
+ TEST_CHECK_EQUAL(*n, last_number);
+ }
+ } test_enum_iterator;
+}
+
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index a2ac7f0..5b39280 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -24,6 +24,7 @@ add(`destringify', `hh', `cc', `test')
add(`deferred_construction_ptr', `hh', `cc', `fwd', `test')
add(`dir_iterator', `hh', `cc', `fwd', `se', `test', `testscript')
add(`discard_output_stream', `hh', `cc')
+add(`enum_iterator', `hh', `cc', `fwd', `test')
add(`exception', `hh', `cc')
add(`fast_unique_copy', `hh', `test')
add(`forward_parallel_for_each', `hh', `test')