//  Copyright Neil Groves 2009. Use, modification and
//  distribution is subject to 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)
//
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range/algorithm/set_algorithm.hpp>

#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>

#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <functional>
#include <list>
#include <numeric>
#include <deque>
#include <vector>

namespace boost
{
    namespace
    {
        template<class Container1, class Iterator, class Container2>
        void check_result(
            Container1& reference,
            Iterator    reference_result,
            Container2& test_cont,
            Iterator    test_result
            )
        {
            BOOST_CHECK_EQUAL(
                std::distance<Iterator>(reference.begin(), reference_result),
                std::distance<Iterator>(test_cont.begin(), test_result)
                );

            BOOST_CHECK_EQUAL_COLLECTIONS(
                reference.begin(), reference.end(),
                test_cont.begin(), test_cont.end()
                );
        }

        template<class Container1, class Container2>
        void test(Container1& cont1, Container2& cont2)
        {
            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;

            std::vector<value_t> reference(cont1.size() + cont2.size());
            std::vector<value_t> test_cont(reference);

            iterator_t reference_result
                = std::set_symmetric_difference(cont1.begin(), cont1.end(),
                                                cont2.begin(), cont2.end(),
                                                reference.begin());

            iterator_t test_result
                = boost::set_symmetric_difference(cont1, cont2,
                                                  test_cont.begin());

            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            boost::make_iterator_range(cont1), cont2,
                            test_cont.begin());
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            cont1, boost::make_iterator_range(cont2),
                            test_cont.begin());
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            boost::make_iterator_range(cont1),
                            boost::make_iterator_range(cont2),
                            test_cont.begin());
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
        }

        template<class Container, class BinaryPredicate>
        void sort_container(Container& cont, BinaryPredicate pred)
        {
            typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;

            std::vector<value_t> temp(cont.begin(), cont.end());
            std::sort(temp.begin(), temp.end(), pred);
            cont.assign(temp.begin(), temp.end());
        }

        template<class Container1,
                 class Container2,
                 class BinaryPredicate>
        void test_pred(Container1 cont1, Container2 cont2,
                       BinaryPredicate pred)
        {
            typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t;
            typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t;

            sort_container(cont1, pred);
            sort_container(cont2, pred);

            std::vector<value_t> reference(cont1.size() + cont2.size());
            std::vector<value_t> test_cont(reference);

            iterator_t reference_result
                = std::set_symmetric_difference(cont1.begin(), cont1.end(),
                                                cont2.begin(), cont2.end(),
                                                reference.begin(),
                                                pred);

            iterator_t test_result
                = boost::set_symmetric_difference(cont1, cont2,
                                                  test_cont.begin(), pred);

            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            boost::make_iterator_range(cont1), cont2,
                            test_cont.begin(), pred);
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            cont1, boost::make_iterator_range(cont2),
                            test_cont.begin(), pred);
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
                         
            test_result = boost::set_symmetric_difference(
                            boost::make_iterator_range(cont1),
                            boost::make_iterator_range(cont2),
                            test_cont.begin(), pred);
                            
            check_result(reference, reference_result,
                         test_cont, test_result);
        }

        template<class Container1, class Container2>
        void test_set_symmetric_difference_impl(
            Container1& cont1,
            Container2& cont2
            )
        {
            test(cont1, cont2);
            test_pred(cont1, cont2, std::less<int>());
            test_pred(cont1, cont2, std::greater<int>());
        }

        template<class Container1, class Container2>
        void test_set_symmetric_difference_impl()
        {
            using namespace boost::assign;

            Container1 cont1;
            Container2 cont2;

            test_set_symmetric_difference_impl(cont1, cont2);

            cont1.clear();
            cont2.clear();
            cont1 += 1;
            test_set_symmetric_difference_impl(cont1, cont2);

            cont1.clear();
            cont2.clear();
            cont2 += 1;
            test_set_symmetric_difference_impl(cont1, cont2);

            cont1.clear();
            cont2.clear();
            cont1 += 1,2,3,4,5,6,7,8,9;
            cont2 += 2,3,4;
            test_set_symmetric_difference_impl(cont1, cont2);

            cont1.clear();
            cont2.clear();
            cont1 += 2,3,4;
            cont2 += 1,2,3,4,5,6,7,8,9;
            test_set_symmetric_difference_impl(cont1, cont2);
        }

        void test_set_symmetric_difference()
        {
            test_set_symmetric_difference_impl< std::vector<int>, std::vector<int> >();
            test_set_symmetric_difference_impl< std::list<int>, std::list<int> >();
            test_set_symmetric_difference_impl< std::deque<int>, std::deque<int> >();
            test_set_symmetric_difference_impl< std::vector<int>, std::list<int> >();
            test_set_symmetric_difference_impl< std::list<int>, std::vector<int> >();
        }
    }
}


boost::unit_test::test_suite*
init_unit_test_suite(int argc, char* argv[])
{
    boost::unit_test::test_suite* test
        = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_symmetric_difference" );

    test->add( BOOST_TEST_CASE( &boost::test_set_symmetric_difference ) );

    return test;
}
