#ifndef SPROUT_ITERATOR_SET_DIFFERENCE_ITERATOR_HPP #define SPROUT_ITERATOR_SET_DIFFERENCE_ITERATOR_HPP #include #include #include #include #include #include #include #include #include #include #include namespace sprout { // // set_difference_iterator // template< typename LIterator, typename RIterator, typename Compare = sprout::less<> > class set_difference_iterator : public std::iterator< typename sprout::min_iterator_category< typename sprout::common_iterator_category::type, std::forward_iterator_tag >::type, typename sprout::common_iterator_value_type::type, typename sprout::common_iterator_difference_type::type, typename sprout::common_iterator_pointer::type, typename sprout::common_iterator_reference::type > { public: typedef LIterator iterator_type; typedef RIterator iterator2_type; typedef Compare compare_type; typedef typename sprout::min_iterator_category< typename sprout::common_iterator_category::type, std::forward_iterator_tag >::type iterator_category; typedef typename sprout::common_iterator_value_type::type value_type; typedef typename sprout::common_iterator_difference_type::type difference_type; typedef typename sprout::common_iterator_pointer::type pointer; typedef typename sprout::common_iterator_reference::type reference; protected: typedef sprout::pair pair_type; protected: pair_type current; iterator_type lst1; iterator2_type lst2; Compare comp; private: SPROUT_CONSTEXPR set_difference_iterator(set_difference_iterator const& other, pair_type const& next) : current(next) , lst1(other.lst1), lst2(other.lst2) , comp(other.comp) {} public: set_difference_iterator() : current(), lst1(), lst2(), comp() {} set_difference_iterator(set_difference_iterator const&) = default; SPROUT_CONSTEXPR set_difference_iterator( iterator_type it1, iterator_type lst1, iterator2_type it2, iterator2_type lst2, Compare comp = Compare() ) : current(sprout::find_difference(it1, lst1, it2, lst2, comp)) , lst1(lst1), lst2(lst2) , comp(comp) {} template SPROUT_CONSTEXPR set_difference_iterator(set_difference_iterator const& it) : current(it.base(), it.base2()) , lst1(it.last1()), lst2(it.last2()) , comp(it.compare()) {} template set_difference_iterator& operator=(set_difference_iterator const& it) { set_difference_iterator temp(it); temp.swap(*this); return *this; } SPROUT_CONSTEXPR iterator_type base() const { return current.first; } SPROUT_CONSTEXPR iterator_type last1() const { return lst1; } SPROUT_CONSTEXPR iterator2_type base2() const { return current.second; } SPROUT_CONSTEXPR iterator2_type last2() const { return lst2; } SPROUT_CONSTEXPR Compare compare() const { return comp; } SPROUT_CONSTEXPR bool is_in_left() const { return true; } SPROUT_CONSTEXPR reference operator*() const { return *current.first; } SPROUT_CONSTEXPR pointer operator->() const { return &*(*this); } set_difference_iterator& operator++() { current = sprout::next_difference(current.first, lst1, current.second, lst2, comp); return *this; } set_difference_iterator operator++(int) { set_difference_iterator result(*this); current = sprout::next_difference(current.first, lst1, current.second, lst2, comp); return result; } SPROUT_CONSTEXPR set_difference_iterator next() const { return set_difference_iterator( *this, sprout::next_difference(current.first, lst1, current.second, lst2, comp) ); } void swap(set_difference_iterator& other) SPROUT_NOEXCEPT_EXPR( SPROUT_NOEXCEPT_EXPR(sprout::swap(current, other.current)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst1, other.lst1)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst2, other.lst2)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(comp, other.comp)) ) { sprout::swap(current, other.current); sprout::swap(lst1, other.lst1); sprout::swap(lst2, other.lst2); sprout::swap(comp, other.comp); } }; template< typename LIterator1, typename RIterator1, typename Compare1, typename LIterator2, typename RIterator2, typename Compare2 > inline SPROUT_CONSTEXPR bool operator==( sprout::set_difference_iterator const& lhs, sprout::set_difference_iterator const& rhs ) { return lhs.base() == rhs.base() && lhs.base2() == rhs.base2(); } template< typename LIterator1, typename RIterator1, typename Compare1, typename LIterator2, typename RIterator2, typename Compare2 > inline SPROUT_CONSTEXPR bool operator!=( sprout::set_difference_iterator const& lhs, sprout::set_difference_iterator const& rhs ) { return !(lhs == rhs); } // // make_set_difference_iterator // template inline SPROUT_CONSTEXPR sprout::set_difference_iterator make_set_difference_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2, Compare comp) { return sprout::set_difference_iterator(it1, lst1, it2, lst2, comp); } template inline SPROUT_CONSTEXPR sprout::set_difference_iterator make_set_difference_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2) { return sprout::set_difference_iterator(it1, lst1, it2, lst2); } // // swap // template inline void swap( sprout::set_difference_iterator& lhs, sprout::set_difference_iterator& rhs ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { lhs.swap(rhs); } // // iterator_next // template inline SPROUT_CONSTEXPR sprout::set_difference_iterator iterator_next(sprout::set_difference_iterator const& it) { return it.next(); } } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_SET_DIFFERENCE_ITERATOR_HPP