//  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/
//
#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED

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

namespace boost
{
    namespace range_test
    {
        // check the results of an algorithm that returns
        // a range_return.
        //
        // This version is the general version. It should never be called.
        // All calls should invoke specialized implementations.
        template< range_return_value return_type >
        struct check_results
        {
            template< class Container, class Iterator >
            static void check(
                Container&          test,
                Container&          reference,
                Iterator            test_it,
                Iterator            reference_it
                )
            {
                BOOST_ASSERT( false );
            }
        };

        // check the results of an algorithm that returns
        // a 'found' iterator
        template< >
        struct check_results<return_found>
        {
            template< class Container, class Iterator >
            static void check(
                Container&          test,
                Container&          reference,
                Iterator            test_it,
                Iterator            reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
                    test.begin(), test.end() );

                BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
                   std::distance(reference.begin(), reference_it) );
            }
        };

        // check the results of an algorithm that returns
        // a 'next(found)' iterator
        template< >
        struct check_results<return_next>
        {
            template< class Container, class Iterator >
            static void check(
                Container&          test,
                Container&          reference,
                Iterator            test_it,
                Iterator            reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
                    test.begin(), test.end() );

                if (reference_it == reference.end())
                {
                    BOOST_CHECK( test_it == test.end() );
                }
                else
                {
                    BOOST_CHECK_EQUAL(
                        std::distance(test.begin(), test_it),
                        std::distance(reference.begin(), reference_it) + 1);
                }
            }
        };

        // check the results of an algorithm that returns
        // a 'prior(found)' iterator
        template< >
        struct check_results<return_prior>
        {
            template< class Container, class Iterator >
            static void check(
                Container&          test,
                Container&          reference,
                Iterator            test_it,
                Iterator            reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
                    test.begin(), test.end() );

                if (reference_it == reference.begin())
                {
                    BOOST_CHECK( test_it == test.begin() );
                }
                else
                {
                    BOOST_CHECK_EQUAL(
                        std::distance(test.begin(), test_it) + 1,
                        std::distance(reference.begin(), reference_it));
                }
            }
        };

        // check the results of an algorithm that returns
        // a '[begin, found)' range
        template< >
        struct check_results<return_begin_found>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference.end(),
                    test.begin(), test.end()
                    );

                BOOST_CHECK( test_rng.begin() == test.begin() );

                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference_it,
                    boost::begin(test_rng), boost::end(test_rng)
                    );
            }
        };

        // check the results of an algorithm that returns
        // a '[begin, next(found))' range
        template< >
        struct check_results<return_begin_next>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference.end(),
                    test.begin(), test.end()
                    );

                BOOST_CHECK( test_rng.begin() == test.begin() );

                if (reference_it == reference.end())
                {
                    BOOST_CHECK( test_rng.end() == test.end() );
                }
                else
                {
                    BOOST_CHECK_EQUAL_COLLECTIONS(
                        reference.begin(), boost::next(reference_it),
                        test_rng.begin(), test_rng.end());
                }
            }
        };

        // check the results of an algorithm that returns
        // a '[begin, prior(found))' range
        template< >
        struct check_results<return_begin_prior>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
                    test.begin(), test.end() );

                BOOST_CHECK( test_rng.begin() == test.begin() );

                if (reference_it == reference.begin())
                {
                    BOOST_CHECK( boost::end(test_rng) == test.begin() );
                }
                else
                {
                    BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1,
                                       std::distance(reference.begin(), reference_it) );
                }
            }
        };

        // check the results of an algorithm that returns
        // a '[found, end)' range
        template< >
        struct check_results<return_found_end>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
                    test.begin(), test.end() );

                BOOST_CHECK_EQUAL(
                    std::distance(test.begin(), boost::begin(test_rng)),
                    std::distance(reference.begin(), reference_it));

                BOOST_CHECK( boost::end(test_rng) == test.end() );
            }
        };

        // check the results of an algorithm that returns
        // a '[next(found), end)' range
        template< >
        struct check_results<return_next_end>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference.end(),
                    test.begin(), test.end()
                    );

                BOOST_CHECK( test_rng.end() == test.end() );

                if (reference_it == reference.end())
                {
                    BOOST_CHECK( test_rng.begin() == test.end() );
                }
                else
                {
                    BOOST_CHECK_EQUAL_COLLECTIONS(
                        boost::next(reference_it), reference.end(),
                        test_rng.begin(), test_rng.end()
                        );
                }
            }
        };

        // check the results of an algorithm that returns
        // a 'prior(found), end)' range
        template< >
        struct check_results<return_prior_end>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference.end(),
                    test.begin(), test.end()
                    );

                BOOST_CHECK( test_rng.end() == test.end() );

                if (reference_it == reference.begin())
                {
                    BOOST_CHECK( test_rng.begin() == test.begin() );
                }
                else
                {
                    BOOST_CHECK_EQUAL_COLLECTIONS(
                        boost::prior(reference_it), reference.end(),
                        test_rng.begin(), test_rng.end()
                        );
                }
            }
        };

        // check the results of an algorithm that returns
        // a '[begin, end)' range
        template< >
        struct check_results<return_begin_end>
        {
            template< class Container, class Iterator >
            static void check(
                Container&                  test,
                Container&                  reference,
                iterator_range<Iterator>    test_rng,
                Iterator                    reference_it
                )
            {
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    reference.begin(), reference.end(),
                    test.begin(), test.end()
                    );

                BOOST_CHECK( test_rng.begin() == test.begin() );
                BOOST_CHECK( test_rng.end() == test.end() );
            }
        };

        // A test driver to exercise a test through all of the range_return
        // combinations.
        //
        // The test driver also contains the code required to check the
        // return value correctness.
        //
        // The TestPolicy needs to implement two functions:
        //
        // - perform the boost range version of the algorithm that returns
        //   a range_return<Container,return_type>::type
        // template<range_return_value return_type, class Container>
        // BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type
        // test(Container& cont);
        //
        // - perform the reference std version of the algorithm that
        //   returns the standard iterator result
        // template<class Container>
        // BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
        // reference(Container& cont);
        class range_return_test_driver
        {
        public:
            template< class Container,
                      class TestPolicy >
            void operator()(Container& cont, TestPolicy policy)
            {
                test_range_iter               (cont, policy);
                test_range<return_found,Container,TestPolicy>      ()(cont, policy);
                test_range<return_next,Container,TestPolicy>       ()(cont, policy);
                test_range<return_prior,Container,TestPolicy>      ()(cont, policy);
                test_range<return_begin_found,Container,TestPolicy>()(cont, policy);
                test_range<return_begin_next,Container,TestPolicy> ()(cont, policy);
                test_range<return_begin_prior,Container,TestPolicy>()(cont, policy);
                test_range<return_found_end,Container,TestPolicy>  ()(cont, policy);
                test_range<return_next_end,Container,TestPolicy>   ()(cont, policy);
                test_range<return_prior_end,Container,TestPolicy>  ()(cont, policy);
                test_range<return_begin_end,Container,TestPolicy>  ()(cont, policy);
            }

        private:
            template< class Container, class TestPolicy >
            void test_range_iter(
                Container&          cont,
                TestPolicy          policy
                )
            {
                typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;

                Container reference(cont);
                Container test(cont);
                
                iterator_t range_result = policy.test_iter(test);
                iterator_t reference_it = policy.reference(reference);

                check_results<return_found>::check(test, reference,
                                                   range_result, reference_it);
            }

            template< range_return_value result_type, class Container, class TestPolicy >
            struct test_range
            {
                void operator()(Container& cont, TestPolicy policy)
                {
                    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
                    typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
                    typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t;

                    Container reference(cont);
                    Container test_cont(cont);

                    range_return_t range_result = test_range_t()(policy, test_cont);
                    iterator_t reference_it = policy.reference(reference);

                    check_results<result_type>::check(test_cont, reference,
                                                         range_result, reference_it);
                }
            };
        };
    }
}

#endif // include guard
