#ifndef SPROUT_ALGORITHM_FIND_SYMMETRIC_DIFFERENCE_HPP #define SPROUT_ALGORITHM_FIND_SYMMETRIC_DIFFERENCE_HPP #include #include #include #include #include #include #include #include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR sprout::pair find_symmetric_difference_impl_check(sprout::tuples::tuple const& current) { return sprout::pair( sprout::tuples::get<0>(current), sprout::tuples::get<1>(current) ); } template inline SPROUT_CONSTEXPR sprout::tuples::tuple find_symmetric_difference_impl_1( sprout::tuples::tuple const& current, InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits::difference_type n ) { typedef sprout::tuples::tuple type; return sprout::tuples::get<2>(current) || sprout::tuples::get<0>(current) == last1 || sprout::tuples::get<1>(current) == last2 ? current : n == 1 ? comp(*sprout::tuples::get<0>(current), *sprout::tuples::get<1>(current)) || comp(*sprout::tuples::get<1>(current), *sprout::tuples::get<0>(current)) ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true) : type(sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)), false) : sprout::detail::find_symmetric_difference_impl_1( sprout::detail::find_symmetric_difference_impl_1( current, last1, last2, comp, n / 2 ), last1, last2, comp, n - n / 2 ) ; } template inline SPROUT_CONSTEXPR sprout::tuples::tuple find_symmetric_difference_impl( sprout::tuples::tuple const& current, InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits::difference_type n ) { return sprout::tuples::get<2>(current) || sprout::tuples::get<0>(current) == last1 ? current : sprout::detail::find_symmetric_difference_impl( sprout::detail::find_symmetric_difference_impl_1( current, last1, last2, comp, n ), last1, last2, comp, n * 2 ) ; } template inline SPROUT_CONSTEXPR sprout::pair find_symmetric_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp ) { typedef sprout::tuples::tuple type; return sprout::detail::find_symmetric_difference_impl_check( sprout::detail::find_symmetric_difference_impl(type(first1, first2, false), last1, last2, comp, 1) ); } } // namespace detail // // find_symmetric_difference // // recursion depth: // O(log N) // template inline SPROUT_CONSTEXPR sprout::pair find_symmetric_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp ) { return sprout::detail::find_symmetric_difference(first1, last1, first2, last2, comp); } template inline SPROUT_CONSTEXPR sprout::pair find_symmetric_difference( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 ) { return sprout::find_symmetric_difference(first1, last1, first2, last2, sprout::less<>()); } } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_FIND_SYMMETRIC_DIFFERENCE_HPP