=== modified file 'src/Makefile.am'
--- src/Makefile.am	2015-08-06 13:43:31 +0000
+++ src/Makefile.am	2015-08-12 14:14:47 +0000
@@ -906,6 +906,7 @@
 	tests/testCharacterSet \
 	tests/testDiskIO \
 	tests/testDns \
+	tests/testEnumIterator \
 	tests/testEvent \
 	tests/testEventLoop \
 	tests/test_http_range \
@@ -3787,6 +3788,20 @@
 	$(XTRA_LIBS)
 tests_testLookupTable_DEPENDENCIES = $(SQUID_CPPUNIT_LA)
 
+tests_testEnumIterator_SOURCES = \
+	tests/testEnumIterator.h \
+	tests/testEnumIterator.cc \
+	base/EnumIterator.h \
+	tests/stub_debug.cc
+nodist_tests_testEnumIterator_SOURCES = $(TESTSOURCES)
+tests_testEnumIterator_LDFLAGS = $(LIBADD_DL)
+tests_testEnumIterator_LDADD = \
+	base/libbase.la \
+	$(SQUID_CPPUNIT_LIBS) \
+	$(COMPAT_LIB) \
+	$(XTRA_LIBS)
+tests_testEnumIterator_DEPENDENCIES = $(SQUID_CPPUNIT_LA)
+
 TESTS += testHeaders
 
 ## Special Universal .h dependency test script

=== added file 'src/base/EnumIterator.h'
--- src/base/EnumIterator.h	1970-01-01 00:00:00 +0000
+++ src/base/EnumIterator.h	2015-08-12 15:26:59 +0000
@@ -0,0 +1,150 @@
+#ifndef SQUID_BASE_ENUMITERATOR_H
+#define SQUID_BASE_ENUMITERATOR_H
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include <iterator>
+#include <type_traits>
+
+/* code shared between forward and reverse iterators */
+template <typename Enum>
+class EnumIteratorBase : public std::iterator<std::bidirectional_iterator_tag, Enum>
+{
+public:
+    explicit EnumIteratorBase(Enum e) : current_value(static_cast<value_t>(e)) {}
+
+    bool operator==(const EnumIteratorBase &i) const {
+        return current_value == i.current_value;
+    }
+
+    bool operator!=(const EnumIteratorBase &i) const {
+        return current_value != i.current_value;
+    }
+
+    Enum operator*() const {
+        return static_cast<Enum>(current_value);
+    }
+
+protected:
+    typedef typename std::underlying_type<Enum>::type value_t;
+    value_t current_value;
+};
+
+/** iterator over an enum type
+ *
+ */
+template <typename Enum>
+class EnumIterator : public EnumIteratorBase<Enum>
+{
+public:
+    explicit EnumIterator(Enum e) : EnumIteratorBase<Enum>(e) {}
+
+    // prefix increment
+    EnumIterator& operator++() {
+        ++ EnumIteratorBase<Enum>::current_value;
+        return *this;
+    }
+
+    // postfix increment
+    EnumIterator& operator++(int) {
+        EnumIterator rv(*this);
+        ++ EnumIteratorBase<Enum>::current_value;
+        return rv;
+    }
+
+    // prefix decrement
+    EnumIterator& operator--() {
+        -- EnumIteratorBase<Enum>::current_value;
+        return *this;
+    }
+
+    // postfix decrement
+    EnumIterator& operator--(int) {
+        EnumIterator rv(*this);
+        -- EnumIteratorBase<Enum>::current_value;
+        return rv;
+    }
+};
+
+template <typename Enum>
+class ReverseEnumIterator : public EnumIteratorBase<Enum>
+{
+public:
+    explicit ReverseEnumIterator(Enum e) : EnumIteratorBase<Enum>(e) {}
+
+    // prefix increment
+    ReverseEnumIterator& operator++() {
+        -- EnumIteratorBase<Enum>::current_value;
+        return *this;
+    }
+
+    // postfix increment
+    ReverseEnumIterator& operator++(int) {
+        ReverseEnumIterator rv(*this);
+        -- EnumIteratorBase<Enum>::current_value;
+        return rv;
+    }
+
+    // prefix decrement
+    ReverseEnumIterator& operator--() {
+        ++ EnumIteratorBase<Enum>::current_value;
+        return *this;
+    }
+
+    // postfix decrement
+    ReverseEnumIterator& operator--(int) {
+        ReverseEnumIterator rv(*this);
+        ++ EnumIteratorBase<Enum>::current_value;
+        return rv;
+    }
+};
+
+/** Class expressing a range of an enum
+ *
+ * This class is suited to use range-for over a continuous portion of an enum.
+ * This class requires that the underlying enum values be represented by
+ * continuous values of an integral type.
+ * Typical use:
+ * for ( auto enumvalue : EnumRange<EnumType>(EnumType::somevalue,
+ *                        EnumType::someOtherValue) )
+ * { do_stuff(); }
+ */
+template <typename Enum>
+class EnumRange
+{
+public:
+    typedef EnumIterator<Enum> iterator;
+    typedef ReverseEnumIterator<Enum> reverse_iterator;
+    EnumRange(Enum first, Enum one_past_last) : begin_(first), end_(one_past_last) { }
+    iterator begin() const { return iterator(begin_);}
+    iterator end() const { return iterator(end_);}
+    reverse_iterator rbegin() const { auto i = reverse_iterator(end_); ++i; return i; }
+    reverse_iterator rend() const { auto i = reverse_iterator(begin_); ++i; return i; }
+private:
+    Enum begin_;
+    Enum end_;
+};
+
+/** Class expressing a range of an enum.
+ *
+ * This class is suited to use range-for over a continuous portion of an enum.
+ * This class requires that the underlying enum values be represented by
+ * continuous values of an integral type.
+ * Enum must have two service values named Enum::enumBegin_ (it MUST have the
+ * same integral value as the first member of the enum) and enumEnd_ (which MUST
+ * have as value one more than the last valid symbol of the enum).
+ * Typical use: for( auto enumvalue : WholeEnum<EnumType>() ) { do_stuff(); }
+ */
+template <typename Enum>
+class WholeEnum : public EnumRange<Enum>
+{
+public:
+    WholeEnum() : EnumRange<Enum>(Enum::enumBegin_, Enum::enumEnd_) {}
+};
+
+#endif /* SQUID_BASE_ENUMITERATOR_H */

=== modified file 'src/base/Makefile.am'
--- src/base/Makefile.am	2015-08-03 02:08:22 +0000
+++ src/base/Makefile.am	2015-08-12 13:30:50 +0000
@@ -35,4 +35,5 @@
 	Subscription.h \
 	TextException.cc \
 	TextException.h \
-	TidyPointer.h
+	TidyPointer.h \
+	EnumIterator.h

=== added file 'src/tests/testEnumIterator.cc'
--- src/tests/testEnumIterator.cc	1970-01-01 00:00:00 +0000
+++ src/tests/testEnumIterator.cc	2015-08-12 15:26:59 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "testEnumIterator.h"
+#include "unitTestMain.h"
+
+#include <cppunit/TestAssert.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( testEnumIterator );
+
+enum class TestEnum {
+    enumBegin_ = 0,
+    zero = 0,
+    one,
+    two,
+    three,
+    four,
+    enumEnd_
+};
+
+void
+testEnumIterator::testForwardIter()
+{
+    WholeEnum<TestEnum>::iterator i = WholeEnum<TestEnum>().begin();
+    CPPUNIT_ASSERT(*i == TestEnum::zero);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::one);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::two);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::three);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::four);
+    ++i;
+    CPPUNIT_ASSERT(i == WholeEnum<TestEnum>().end());
+}
+
+void
+testEnumIterator::testReverseIter()
+{
+    WholeEnum<TestEnum>::reverse_iterator i = WholeEnum<TestEnum>().rbegin();
+    CPPUNIT_ASSERT(*i == TestEnum::four);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::three);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::two);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::one);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::zero);
+    ++i;
+    CPPUNIT_ASSERT(i == WholeEnum<TestEnum>().rend());
+}
+
+void
+testEnumIterator::testBidirectionalIter()
+{
+    WholeEnum<TestEnum>::iterator i = WholeEnum<TestEnum>().begin();
+    CPPUNIT_ASSERT(*i == TestEnum::zero);
+    ++i;
+    CPPUNIT_ASSERT(*i == TestEnum::one);
+    --i;
+    CPPUNIT_ASSERT(*i == TestEnum::zero);
+}
+
+void
+testEnumIterator::testRangeFor()
+{
+    int j = 0;
+    for (auto e : WholeEnum<TestEnum>()) {
+        (void)e;
+        ++j;
+    }
+    CPPUNIT_ASSERT_EQUAL(5,j);
+}
+
+void
+testEnumIterator::testRangeForRange()
+{
+    int j = 0;
+    for (auto e : EnumRange<TestEnum>(TestEnum::one, TestEnum::three)) {
+        (void)e;
+        ++j;
+    }
+    CPPUNIT_ASSERT_EQUAL(2,j);
+
+}

=== added file 'src/tests/testEnumIterator.h'
--- src/tests/testEnumIterator.h	1970-01-01 00:00:00 +0000
+++ src/tests/testEnumIterator.h	2015-08-12 13:41:09 +0000
@@ -0,0 +1,33 @@
+#ifndef SQUID_TESTENUMITERATOR_H_
+#define SQUID_TESTENUMITERATOR_H_
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "base/EnumIterator.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class testEnumIterator : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE( testEnumIterator );
+    CPPUNIT_TEST( testForwardIter );
+    CPPUNIT_TEST( testReverseIter );
+    CPPUNIT_TEST( testBidirectionalIter );
+    CPPUNIT_TEST( testRangeFor );
+    CPPUNIT_TEST( testRangeForRange );
+    CPPUNIT_TEST_SUITE_END();
+
+protected:
+    void testForwardIter();
+    void testReverseIter();
+    void testBidirectionalIter();
+    void testRangeFor();
+    void testRangeForRange();
+};
+
+#endif /* SQUID_TESTENUMITERATOR_H_ */

