/*=============================================================================
    Copyright (c) 2005-2006 Joao Abecasis
    Copyright (c) 2006-2007 Tobias Schwinger

    Use modification and distribution are 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).
==============================================================================*/

#include <boost/fusion/functional/invocation/invoke_function_object.hpp>
#include <boost/detail/lightweight_test.hpp>

#include <boost/type_traits/is_same.hpp>

#include <memory>
#include <boost/noncopyable.hpp>

#include <boost/mpl/int.hpp>

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/container/list.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/begin.hpp>
#include <boost/fusion/view/single_view.hpp>
#include <boost/fusion/view/iterator_range.hpp>
#include <boost/fusion/iterator/advance.hpp>
#include <boost/fusion/algorithm/transformation/join.hpp>

namespace mpl = boost::mpl;
namespace fusion = boost::fusion;

template <typename T>
inline T const & const_(T const & t)
{
    return t;
}

struct object {};
struct object_nc : boost::noncopyable {};

struct fobj
{
    // Handle nullary separately to exercise result_of support
    template <typename Sig>
    struct result;

    template <class Self, typename T0>
    struct result< Self(T0) >
    {
        typedef int type;
    };

    template <class Self, typename T0, typename T1>
    struct result< Self(T0, T1) >
    {
        typedef int type;
    };

    template <class Self, typename T0, typename T1, typename T2>
    struct result< Self(T0, T1, T2) >
    {
        typedef int type;
    };

    int operator()()       { return 0; }
    int operator()() const { return 1; }

    int operator()(int i)       { return 2 + i; }
    int operator()(int i) const { return 3 + i; }

    int operator()(int i, object &)             { return 4 + i; }
    int operator()(int i, object &) const       { return 5 + i; }
    int operator()(int i, object const &)       { return 6 + i; }
    int operator()(int i, object const &) const { return 7 + i; }

    int operator()(int i, object &, object_nc &)       { return 10 + i; }
    int operator()(int i, object &, object_nc &) const { return 11 + i; }
};

struct nullary_fobj
{
    typedef int result_type;

    int operator()()       { return 0; }
    int operator()() const { return 1; }
};

struct fobj_nc
      : boost::noncopyable
{
    // Handle nullary separately to exercise result_of support
    template <typename T>
    struct result;

    template <class Self, typename T0>
    struct result< Self(T0) >
    {
        typedef int type;
    };

    int operator()(int i)       { return 14 + i; }
    int operator()(int i) const { return 15 + i; }
};

struct nullary_fobj_nc
      : boost::noncopyable
{
    typedef int result_type;

    int operator()()       { return 12; }
    int operator()() const { return 13; }
};


typedef int         element1_type;
typedef object      element2_type;
typedef object_nc & element3_type;

int         element1 = 100;
object      element2 = object();
object_nc   element3;

template <class Sequence>
void test_sequence_n(Sequence & seq, mpl::int_<0>)
{
    // Function Objects

    nullary_fobj f;
    BOOST_TEST(f () == fusion::invoke_function_object(f ,        seq ));
    BOOST_TEST(f () == fusion::invoke_function_object(f , const_(seq)));

    // Note: The function object is taken by value, so we request the copy
    // to be const with an explicit template argument. We can also request
    // the function object to be pased by reference...
    BOOST_TEST(const_(f)() == fusion::invoke_function_object<nullary_fobj const  >(const_(f),        seq ));
    BOOST_TEST(const_(f)() == fusion::invoke_function_object<nullary_fobj const &>(const_(f), const_(seq)));

    nullary_fobj_nc nc_f;
    // ...and we further ensure there is no copying in this case, using a
    // noncopyable function object.
    BOOST_TEST(nc_f () == fusion::invoke_function_object<nullary_fobj_nc &>(nc_f ,        seq ));
    BOOST_TEST(nc_f () == fusion::invoke_function_object<nullary_fobj_nc &>(nc_f , const_(seq)));
    BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<nullary_fobj_nc const &>(const_(nc_f),        seq ));
    BOOST_TEST(const_(nc_f)() == fusion::invoke_function_object<nullary_fobj_nc const &>(const_(nc_f), const_(seq)));
}

template <class Sequence>
void test_sequence_n(Sequence & seq, mpl::int_<1>)
{
    fobj f;
    BOOST_TEST(f(element1) == fusion::invoke_function_object(f , seq ));
    BOOST_TEST(f(element1) == fusion::invoke_function_object(f , const_(seq)));
    BOOST_TEST(const_(f)(element1) == fusion::invoke_function_object<fobj const  >(const_(f), seq ));
    BOOST_TEST(const_(f)(element1) == fusion::invoke_function_object<fobj const &>(const_(f), const_(seq)));

    fobj_nc nc_f;
    BOOST_TEST(nc_f(element1) == fusion::invoke_function_object<fobj_nc &>(nc_f, seq ));
    BOOST_TEST(nc_f(element1) == fusion::invoke_function_object<fobj_nc &>(nc_f, const_(seq)));
    BOOST_TEST(const_(nc_f)(element1) == fusion::invoke_function_object<fobj_nc const &>(const_(nc_f), seq ));
    BOOST_TEST(const_(nc_f)(element1) == fusion::invoke_function_object<fobj_nc const &>(const_(nc_f), const_(seq)));
}

template <class Sequence>
void test_sequence_n(Sequence & seq, mpl::int_<2>)
{
    fobj f;
    BOOST_TEST(f (element1, element2) == fusion::invoke_function_object(f , seq));
    BOOST_TEST(f (element1, const_(element2)) == fusion::invoke_function_object(f , const_(seq)));
    BOOST_TEST(const_(f)(element1, element2) == fusion::invoke_function_object<fobj const>(const_(f), seq));
    BOOST_TEST(const_(f)(element1, const_(element2)) == fusion::invoke_function_object<fobj const>(const_(f), const_(seq)));
}

template <class Sequence>
void test_sequence_n(Sequence & seq, mpl::int_<3>)
{
    fobj f;

    BOOST_TEST(f(element1, element2, element3) == fusion::invoke_function_object(f, seq));
    BOOST_TEST(const_(f)(element1, element2, element3) == fusion::invoke_function_object<fobj const>(const_(f), seq));
}

template <class Sequence>
void test_sequence(Sequence & seq)
{
    test_sequence_n(seq, mpl::int_<fusion::result_of::size<Sequence>::value>());
}

void result_type_tests()
{
    using boost::is_same;

    BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< nullary_fobj, fusion::vector<> >::type, int >::value ));
    BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type> >::type, int >::value ));
    BOOST_TEST(( is_same< fusion::result_of::invoke_function_object< fobj, fusion::vector<element1_type,element2_type> >::type, int >::value ));
}


int main()
{
    result_type_tests();

    typedef fusion::vector<> vector0;
    typedef fusion::vector<element1_type> vector1;
    typedef fusion::vector<element1_type, element2_type> vector2;
    typedef fusion::vector<element1_type, element2_type, element3_type> vector3;

    vector0 v0;
    vector1 v1(element1);
    vector2 v2(element1, element2);
    vector3 v3(element1, element2, element3);

    test_sequence(v0);
    test_sequence(v1);
    test_sequence(v2);
    test_sequence(v3);

    typedef fusion::list<> list0;
    typedef fusion::list<element1_type> list1;
    typedef fusion::list<element1_type, element2_type> list2;
    typedef fusion::list<element1_type, element2_type, element3_type> list3;

    list0 l0;
    list1 l1(element1);
    list2 l2(element1, element2);
    list3 l3(element1, element2, element3);

    test_sequence(l0);
    test_sequence(l1);
    test_sequence(l2);
    test_sequence(l3);

    return boost::report_errors();
}

