/* * foreach.hpp * * Created on: Apr 1, 2013 * Author: Jan Travnicek */ #ifndef __FOREACH_HPP_ #define __FOREACH_HPP_ namespace std { template < class ... Iterators > class const_tuple_foreach_iterator { std::tuple < Iterators ... > current; template < size_t ... I > std::tuple < const typename Iterators::value_type & ... > callDerefOperator ( const std::index_sequence < I ... > & ) const { return std::tie ( * std::get < I > ( current ) ... ); } template < size_t ... I > void callIncOperator ( const std::index_sequence < I ... > & ) { std::tie ( ++std::get < I > ( current ) ... ); } template < size_t ... I > void callDecOperator ( const std::index_sequence < I ... > & ) { std::tie ( --std::get < I > ( current ) ... ); } public: explicit const_tuple_foreach_iterator ( ) { } explicit const_tuple_foreach_iterator ( Iterators ... it ) : current ( it ... ) { } template < int number > decltype ( std::get < number > ( current ) )base ( ) const { return std::get < number > ( current ); } template < size_t ... I > std::tuple < const typename Iterators::value_type & ... > operator *( ) const { return callDerefOperator ( std::index_sequence_for < Iterators ... > { } ); } template < size_t ... I > const_tuple_foreach_iterator & operator ++( ) { callIncOperator ( std::index_sequence_for < Iterators ... > { } ); return * this; } template < size_t ... I > const_tuple_foreach_iterator & operator --( ) { callDecOperator ( std::index_sequence_for < Iterators ... > { } ); return * this; } const_tuple_foreach_iterator operator ++( int ) { const_tuple_foreach_iterator temp = * this; ++( * this ); return temp; } const_tuple_foreach_iterator operator --( int ) { const_tuple_foreach_iterator temp = * this; --( * this ); return temp; } bool operator ==( const const_tuple_foreach_iterator < Iterators ... > & other ) { return this->current == other.current; } bool operator !=( const const_tuple_foreach_iterator < Iterators ... > & other ) { return !( * this == other ); } }; template < class ... Iterators > const_tuple_foreach_iterator < Iterators ... > make_tuple_foreach_iterator ( Iterators ... its ) { return const_tuple_foreach_iterator < Iterators ... > ( its ... ); } template < class ... Types > class const_tuple_foreach { const std::tuple < const Types & ... > data; template < size_t ... I > const_tuple_foreach_iterator < typename Types::const_iterator ... > callBegin ( const std::index_sequence < I ... > & ) const { return make_tuple_foreach_iterator ( std::get < I > ( data ).cbegin ( ) ... ); } template < size_t ... I > const_tuple_foreach_iterator < typename Types::const_iterator ... > callEnd ( const std::index_sequence < I ... > & ) const { return make_tuple_foreach_iterator ( std::get < I > ( data ).cend ( ) ... ); } public: const_tuple_foreach ( const Types & ... args ) : data ( args ... ) { } template < int ... I > const_tuple_foreach_iterator < typename Types::const_iterator ... > begin ( ) const { return callBegin ( std::index_sequence_for < Types ... > { } ); } template < int ... I > const_tuple_foreach_iterator < typename Types::const_iterator ... > end ( ) const { return callEnd ( std::index_sequence_for < Types ... > { } ); } }; template < class ... Types > const_tuple_foreach < Types ... > make_tuple_foreach ( const Types & ... args ) { return const_tuple_foreach < Types ... > ( args ... ); } } /* namespace std */ #endif /* __FOREACH_HPP_ */