// // unkeyed_iterator.hpp // iterator // // Created by Sam Jaffe on 2/20/17. // #pragma once #include namespace iterator { /** * At first glance, this class seems like it acts as an iterator that would be * used in the C++ equivalent of Java's Map::values() function. However, * notices that we do not assume that the input iterator is a map iterator. * The useful feature of this iterator - and the source of its name - is its * ability to be composed with recursive_iterator. This means that you can * have something crazy like a four-level map and then do: * \code * std::map>> object; * auto const rit = make_recursive_iterator(object); * for (unkeyed_iterator it = rit, end = {}; it != end; ++it) { * // Process only BigType, discarding all of the keys that we need to walk * } * \endcode */ template class unkeyed_iterator { private: using impl_value_type = typename std::iterator_traits::value_type; using impl_reference = typename std::iterator_traits::reference; static constexpr std::size_t const value_index = std::tuple_size::value - 1; public: using value_type = typename std::remove_reference(std::declval()))>::type; using reference = decltype(std::get(std::declval())); using pointer = value_type *; using difference_type = typename std::iterator_traits::difference_type; using iterator_category = typename std::iterator_traits::iterator_category; unkeyed_iterator() = default; unkeyed_iterator(Iterator it) : base(it) {} reference operator*() const { return std::get(*base); } pointer operator->() const { return std::addressof(operator*()); } unkeyed_iterator & operator++() { ++base; return *this; } unkeyed_iterator operator++(int) { unkeyed_iterator tmp{*this}; operator++(); return tmp; } unkeyed_iterator & operator--() { --base; return *this; } unkeyed_iterator operator--(int) { unkeyed_iterator tmp{*this}; operator--(); return tmp; } bool operator==(unkeyed_iterator const & other) const { return base == other.base; } bool operator!=(unkeyed_iterator const & other) const { return base != other.base; } private: Iterator base; }; }