Skip to content
Snippets Groups Projects
foreach.hpp 3.11 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 Iterator1, class Iterator2>
    class const_pair_foreach_iterator {
    	Iterator1 current1;
    	Iterator2 current2;
    
    public:
    	typedef Iterator1 iterator_type1;
    	typedef typename iterator_traits<Iterator1>::iterator_category iterator_category1;
    	typedef typename iterator_traits<Iterator1>::value_type        value_type1;
    	typedef Iterator1 pointer1;
    	typedef const value_type1& reference1;
    
    	typedef Iterator2 iterator_type2;
    	typedef typename iterator_traits<Iterator2>::iterator_category iterator_category2;
    	typedef typename iterator_traits<Iterator2>::value_type        value_type2;
    	typedef Iterator2 pointer2;
    	typedef const value_type2& reference2;
    
    	explicit const_pair_foreach_iterator() {
    	}
    
    	explicit const_pair_foreach_iterator (Iterator1 it1, Iterator2 it2) : current1(it1), current2(it2) {
    	}
    
    	const_pair_foreach_iterator (const const_pair_foreach_iterator<Iterator1, Iterator2>& it) : current1(it.current1), current2(it.current2) {
    	}
    
    	const_pair_foreach_iterator& operator= (const const_pair_foreach_iterator<Iterator1, Iterator2>& it) {
    		current1 = it.current1;
    		current2 = it.current2;
    	}
    
    	iterator_type1 base1() const {
    		return current1;
    	}
    
    	iterator_type2 base2() const {
    		return current2;
    	}
    
    	std::tuple<reference1, reference2> operator*() const {
    		return std::tie(*current1, *current2);
    	}
    
    	const_pair_foreach_iterator& operator++() {
    		++current1;
    		++current2;
    		return *this;
    	}
    
    	const_pair_foreach_iterator& operator--() {
    		--current1;
    		--current2;
    		return *this;
    	}
    
    
    	const_pair_foreach_iterator operator++(int) {
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		const_pair_foreach_iterator temp = *this;
    		++current1;
    		++current2;
    		return temp;
    	}
    
    
    	const_pair_foreach_iterator operator--(int) {
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		const_pair_foreach_iterator temp = *this;
    		--current1;
    		--current2;
    		return temp;
    	}
    
    	bool operator== (const const_pair_foreach_iterator<Iterator1, Iterator2>& other) {
    		return this->current1 == other.current1 && this->current2 == other.current2;
    	}
    
    	bool operator!= (const const_pair_foreach_iterator<Iterator1, Iterator2>& other) {
    		return ! ( *this == other );
    	}
    
    };
    
    template<class Iterator1, class Iterator2>
    const_pair_foreach_iterator<Iterator1, Iterator2> make_pair_foreach_iterator (Iterator1 it1, Iterator2 it2) {
    	return const_pair_foreach_iterator<Iterator1, Iterator2>(it1, it2);
    }
    
    template<class T, class R>
    class const_pair_foreach {
    
    	const T& first;
    	const R& second;
    
    public:
    	const_pair_foreach(const T& first, const R& second) : first(first), second(second) {}
    
    	const_pair_foreach_iterator<typename T::const_iterator, typename R::const_iterator> begin() const {
    		return make_pair_foreach_iterator(first.begin(), second.begin());
    	}
    
    	const_pair_foreach_iterator<typename T::const_iterator, typename R::const_iterator> end() const {
    		return make_pair_foreach_iterator(first.end(), second.end());
    	}
    
    };
    
    template<class T, class R>
    const_pair_foreach<T, R> make_pair_foreach(const T& first, const R& second) {
    	return const_pair_foreach<T, R>(first, second);
    }
    
    } /* namespace std */
    
    #endif /* __FOREACH_HPP_ */