diff --git a/libpwrutils/CMakeLists.txt b/libpwrutils/CMakeLists.txt
index b7e137017971a96234fb7dc87fcf81b176bbeb6b..84cbcc82e00246161e30dfcbe933624669c54daa 100644
--- a/libpwrutils/CMakeLists.txt
+++ b/libpwrutils/CMakeLists.txt
@@ -4,7 +4,7 @@ PROJECT(pwrutils)
 
 set(pwrutils_ver_major "0")
 set(pwrutils_ver_minor "0")
-set(pwrutils_ver_patch "2")
+set(pwrutils_ver_patch "3")
 
 set(LIBPWRUTILS_VERSION
 	"${pwrutils_ver_major}.${pwrutils_ver_minor}.${pwrutils_ver_patch}")
diff --git a/libpwrutils/bitset.h b/libpwrutils/bitset.h
index a0a2be6f47c939cb802b99a35ffcd9888de8eda8..2b5342b8e2aa5c751e763843e15465c20ce32341 100644
--- a/libpwrutils/bitset.h
+++ b/libpwrutils/bitset.h
@@ -58,6 +58,69 @@ inline size_t lowest_bit(const unsigned long& t)
 	return boost::lowest_bit(t);
 }
 
+/// Helper iterator class for iterating through set bits
+template<typename T>
+struct set_bits_iterator
+{
+	typedef T value_type;
+	typedef std::forward_iterator_tag iterator_category;
+	typedef int difference_type;
+	typedef const T *pointer;
+	typedef const T &reference;
+	set_bits_iterator(const set_bits_iterator &i): i_(i.i_), c_(i.c_) {}
+	set_bits_iterator(const T& i) : i_(i), c_(0) {
+		adv();
+	}
+
+	set_bits_iterator &operator++() {
+		adv(); return *this;
+	}
+	set_bits_iterator operator++(int) {
+		set_bits_iterator c(*this);
+		c.adv();
+		return c;
+	}
+	bool operator==(const set_bits_iterator &i) const {
+		return i_ == i.i_ && c_ == i.c_;
+	}
+	bool operator!=(const set_bits_iterator &i) const {
+		return i_ != i.i_ || c_ != i.c_;
+	}
+	const T &operator*() const { return c_; }
+
+private:
+	void adv() {
+		c_.reset();
+		if (i_.any()) {
+			c_.set(lowest_bit(i_));
+			i_ ^= c_;
+		}
+	}
+
+	T i_;
+	T c_;
+};
+
+/**
+ * Function that returns a foreach-compatible iterator range that allows
+ * iterating through the set bits of a bitset. It only makes sense to read
+ * from the returned range.
+ *
+ * Example usage: \code
+ * foreach (const bitset<32>& b, my_bitset) {
+ *    foo_with(b);
+ * }
+ * \endcode
+ */
+template<size_t S>
+boost::iterator_range< set_bits_iterator< std::bitset<S> > > set_bits(
+		const bitset<S>& bs)
+{
+	return boost::iterator_range< set_bits_iterator< std::bitset<S> > >(
+			bs, bitset<S>()
+		);
+}
+
 } /* end ns PwrNlp */
 
 namespace std {
@@ -106,6 +169,6 @@ bool operator<(bitset<PwrNlp::ulong_bits> left, bitset<PwrNlp::ulong_bits> right
 	return left.to_ulong() < right.to_ulong();
 }
 
-}
+} /* end ns std */
 
 #endif // PWRNLP_BITSET_H
diff --git a/tests/tag_split.cpp b/tests/tag_split.cpp
index 1f4ca44dc1bf89e6fed6fd98d8d615b10dc32af0..71976534356a0a78b2d6e9db8578ae63bbc6237d 100644
--- a/tests/tag_split.cpp
+++ b/tests/tag_split.cpp
@@ -1,6 +1,7 @@
 #include <boost/test/unit_test.hpp>
 #include <set>
 #include <libpwrutils/foreach.h>
+#include <libpwrutils/bitset.h>
 #include <libcorpus2/tagset.h>
 #include <libcorpus2/token.h>
 
@@ -196,3 +197,14 @@ BOOST_FIXTURE_TEST_CASE( tag_size, F )
 }
 
 BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_CASE(bs_split)
+{
+	std::bitset<32> x(0xf6543);
+	std::bitset<32> y(0);
+	foreach (std::bitset<32> b, PwrNlp::set_bits(x)) {
+		BOOST_CHECK_EQUAL(b.count(), 1);
+		y |= b;
+	}
+	BOOST_CHECK_EQUAL(x, y);
+}