Skip to content
Snippets Groups Projects
foreach.hpp 3.44 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jan Trávníček's avatar
    Jan Trávníček committed
    /*
     * 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;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    	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 );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		return temp;
    	}
    
    
    	const_tuple_foreach_iterator operator --( int ) {
    		const_tuple_foreach_iterator temp = * this;
    
    		--( * this );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		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 {
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    
    	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 ( ) ... );
    	}
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    
    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 ... );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    }
    
    } /* namespace std */
    
    #endif /* __FOREACH_HPP_ */