Skip to content
Snippets Groups Projects
foreach.hpp 4.83 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 ... );
    
    template < class IntegralType >
    class virtual_pointer_to_integer {
    	IntegralType m_data;
    
    public:
    	virtual_pointer_to_integer ( IntegralType data ) : m_data ( data ) {
    	}
    
    	IntegralType operator * ( ) const {
    		return m_data;
    	}
    
    	virtual_pointer_to_integer & operator ++( ) {
    		m_data ++;
    		return * this;
    	}
    
    	virtual_pointer_to_integer & operator --( ) {
    		m_data --;
    		return * this;
    	}
    
    	virtual_pointer_to_integer operator ++( int ) {
    		virtual_pointer_to_integer temp = * this;
    
    		++( * this );
    		return temp;
    	}
    
    	virtual_pointer_to_integer operator --( int ) {
    		virtual_pointer_to_integer temp = * this;
    
    		--( * this );
    		return temp;
    	}
    
    	bool operator ==( const virtual_pointer_to_integer < IntegralType > & other ) {
    		return this->m_data == other.m_data;
    	}
    
    	bool operator !=( const virtual_pointer_to_integer < IntegralType > & other ) {
    		return !( * this == other );
    	}
    };
    
    template < class IntegralType >
    class sequence {
    	IntegralType m_first;
    	IntegralType m_last;
    
    public:
    	sequence ( IntegralType first, IntegralType last ) : m_first ( first ), m_last ( last ) {
    	}
    
    	sequence ( IntegralType size ) : m_first ( 0 ), m_last ( size ) {
    	}
    
    	virtual_pointer_to_integer < IntegralType > begin ( ) {
    		return virtual_pointer_to_integer < IntegralType > ( m_first );
    	}
    
    	virtual_pointer_to_integer < IntegralType > end ( ) {
    		return virtual_pointer_to_integer < IntegralType > ( m_last );
    	}
    };
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    } /* namespace std */
    
    #endif /* __FOREACH_HPP_ */