/*============================================================================= Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #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 las1; iterator2_type las2; Compare comp; private: SPROUT_CONSTEXPR set_difference_iterator(set_difference_iterator const& other, pair_type const& next) : current(next) , las1(other.las1), las2(other.las2) , comp(other.comp) {} public: SPROUT_CONSTEXPR set_difference_iterator() : current(), las1(), las2(), comp() {} set_difference_iterator(set_difference_iterator const&) = default; SPROUT_CONSTEXPR set_difference_iterator( iterator_type it1, iterator_type las1, iterator2_type it2, iterator2_type las2, Compare comp = Compare() ) : current(sprout::find_difference(it1, las1, it2, las2, comp)) , las1(las1), las2(las2) , comp(comp) {} template SPROUT_CONSTEXPR set_difference_iterator(set_difference_iterator const& it) : current(it.base(), it.base2()) , las1(it.last1()), las2(it.last2()) , comp(it.compare()) {} template SPROUT_CXX14_CONSTEXPR 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 las1; } SPROUT_CONSTEXPR iterator2_type base2() const { return current.second; } SPROUT_CONSTEXPR iterator2_type last2() const { return las2; } 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); } SPROUT_CXX14_CONSTEXPR set_difference_iterator& operator++() { current = sprout::next_difference(current.first, las1, current.second, las2, comp); return *this; } SPROUT_CXX14_CONSTEXPR set_difference_iterator operator++(int) { set_difference_iterator result(*this); current = sprout::next_difference(current.first, las1, current.second, las2, comp); return result; } SPROUT_CONSTEXPR set_difference_iterator next() const { return set_difference_iterator( *this, sprout::next_difference(current.first, las1, current.second, las2, comp) ); } SPROUT_CXX14_CONSTEXPR void swap(set_difference_iterator& other) SPROUT_NOEXCEPT_IF( SPROUT_NOEXCEPT_EXPR(sprout::swap(current, other.current)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(las1, other.las1)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(las2, other.las2)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(comp, other.comp)) ) { sprout::swap(current, other.current); sprout::swap(las1, other.las1); sprout::swap(las2, other.las2); 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 las1, RIterator it2, RIterator las2, Compare comp) { return sprout::set_difference_iterator(it1, las1, it2, las2, comp); } template inline SPROUT_CONSTEXPR sprout::set_difference_iterator make_set_difference_iterator(LIterator it1, LIterator las1, RIterator it2, RIterator las2) { return sprout::set_difference_iterator(it1, las1, it2, las2); } // // swap // template inline SPROUT_CXX14_CONSTEXPR void swap( sprout::set_difference_iterator& lhs, sprout::set_difference_iterator& rhs ) SPROUT_NOEXCEPT_IF_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