// Copyright Daniel Wallin, David Abrahams 2005. 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)

#ifndef ARG_LIST_050329_HPP
#define ARG_LIST_050329_HPP

#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/result_of0.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/parameter/aux_/is_maybe.hpp>
#include <boost/parameter/config.hpp>

#include <boost/mpl/apply.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/iterator_tags.hpp>

#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>

namespace boost { namespace parameter {

// Forward declaration for aux::arg_list, below.
template<class T> struct keyword;

namespace aux {

// Tag type passed to MPL lambda.
struct lambda_tag;

//
// Structures used to build the tuple of actual arguments.  The
// tuple is a nested cons-style list of arg_list specializations
// terminated by an empty_arg_list.
//
// Each specialization of arg_list is derived from its successor in
// the list type.  This feature is used along with using
// declarations to build member function overload sets that can
// match against keywords.
//

// MPL sequence support
struct arg_list_tag;

// Terminates arg_list<> and represents an empty list.  Since this
// is just the terminating case you might want to look at arg_list
// first, to get a feel for what's really happening here.

struct empty_arg_list
{
    empty_arg_list() {}

    // Constructor taking BOOST_PARAMETER_MAX_ARITY empty_arg_list
    // arguments; this makes initialization
    empty_arg_list(
        BOOST_PP_ENUM_PARAMS(
            BOOST_PARAMETER_MAX_ARITY, void_ BOOST_PP_INTERCEPT
        ))
    {}

    // A metafunction class that, given a keyword and a default
    // type, returns the appropriate result type for a keyword
    // lookup given that default
    struct binding
    {
        template<class KW, class Default, class Reference>
        struct apply
        {
            typedef Default type;
        };
    };

#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    // Terminator for has_key, indicating that the keyword is unique
    template <class KW>
    static no_tag has_key(KW*);
#endif

#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
    || (BOOST_WORKAROUND(__GNUC__, < 3)) \
    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))

    // The overload set technique doesn't work with these older
    // compilers, so they need some explicit handholding.

    // A metafunction class that, given a keyword, returns the type
    // of the base sublist whose get() function can produce the
    // value for that key
    struct key_owner
    {
        template<class KW>
        struct apply
        {
            typedef empty_arg_list type;
        };
    };

    template <class K, class T>
    T& get(default_<K,T> x) const
    {
        return x.value;
    }

    template <class K, class F>
    typename result_of0<F>::type
    get(lazy_default<K,F> x) const
    {
        return x.compute_default();
    }
#endif

    // If this function is called, it means there is no argument
    // in the list that matches the supplied keyword. Just return
    // the default value.
    template <class K, class Default>
    Default& operator[](default_<K, Default> x) const
    {
        return x.value;
    }

    // If this function is called, it means there is no argument
    // in the list that matches the supplied keyword. Just evaluate
    // and return the default value.
    template <class K, class F>
    typename result_of0<F>::type
    operator[](
        BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
    {
        return x.compute_default();
    }

    // No argument corresponding to ParameterRequirements::key_type
    // was found if we match this overload, so unless that parameter
    // has a default, we indicate that the actual arguments don't
    // match the function's requirements.
    template <class ParameterRequirements, class ArgPack>
    static typename ParameterRequirements::has_default
    satisfies(ParameterRequirements*, ArgPack*);

    // MPL sequence support
    typedef empty_arg_list type;   // convenience
    typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};

#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<class KW>
no_tag operator*(empty_arg_list, KW*);
#endif

// Forward declaration for arg_list::operator,
template <class KW, class T>
struct tagged_argument;

template <class T>
struct get_reference
{
    typedef typename T::reference type;
};

// A tuple of tagged arguments, terminated with empty_arg_list.
// Every TaggedArg is an instance of tagged_argument<>.
template <class TaggedArg, class Next = empty_arg_list>
struct arg_list : Next
{
    typedef arg_list<TaggedArg,Next> self;
    typedef typename TaggedArg::key_type key_type;

    typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;

    typedef typename mpl::eval_if<
        holds_maybe
      , get_reference<typename TaggedArg::value_type>
      , get_reference<TaggedArg>
    >::type reference;

    typedef typename mpl::if_<
        holds_maybe
      , reference
      , typename TaggedArg::value_type
    >::type value_type;

    TaggedArg arg;      // Stores the argument

    // Store the arguments in successive nodes of this list
    template< // class A0, class A1, ...
        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
    >
    arg_list( // A0& a0, A1& a1, ...
        BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & a)
    )
      : Next( // a1, a2, ...
            BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
          , void_reference()
        )
      , arg(a0)
    {}

    // Create a new list by prepending arg to a copy of tail.  Used
    // when incrementally building this structure with the comma
    // operator.
    arg_list(TaggedArg head, Next const& tail)
      : Next(tail)
      , arg(head)
    {}

    // A metafunction class that, given a keyword and a default
    // type, returns the appropriate result type for a keyword
    // lookup given that default
    struct binding
    {
        template <class KW, class Default, class Reference>
        struct apply
        {
          typedef typename mpl::eval_if<
                boost::is_same<KW, key_type>
              , mpl::if_<Reference, reference, value_type>
              , mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
          >::type type;
        };
    };

#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !BOOST_WORKAROUND(__GNUC__, == 2)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    friend yes_tag operator*(arg_list, key_type*);
#  define BOOST_PARAMETER_CALL_HAS_KEY(next, key) (*(next*)0 * (key*)0)
# else
    // Overload for key_type, so the assert below will fire if the
    // same keyword is used again
    static yes_tag has_key(key_type*);
    using Next::has_key;

#  define BOOST_PARAMETER_CALL_HAS_KEY(next, key) next::has_key((key*)0)
# endif

    BOOST_MPL_ASSERT_MSG(
        sizeof(BOOST_PARAMETER_CALL_HAS_KEY(Next,key_type)) == sizeof(no_tag)
      , duplicate_keyword, (key_type)
    );

# undef BOOST_PARAMETER_CALL_HAS_KEY
#endif
    //
    // Begin implementation of indexing operators for looking up
    // specific arguments by name
    //

    // Helpers that handle the case when TaggedArg is
    // empty<T>.
    template <class D>
    reference get_default(D const&, mpl::false_) const
    {
        return arg.value;
    }

    template <class D>
    reference get_default(D const& d, mpl::true_) const
    {
        return arg.value ? arg.value.get() : arg.value.construct(d.value);
    }

#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
    || BOOST_WORKAROUND(__GNUC__, < 3) \
    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
    // These older compilers don't support the overload set creation
    // idiom well, so we need to do all the return type calculation
    // for the compiler and dispatch through an outer function template

    // A metafunction class that, given a keyword, returns the base
    // sublist whose get() function can produce the value for that
    // key.
    struct key_owner
    {
        template<class KW>
        struct apply
        {
          typedef typename mpl::eval_if<
                boost::is_same<KW, key_type>
              , mpl::identity<arg_list<TaggedArg,Next> >
              , mpl::apply_wrap1<typename Next::key_owner,KW>
          >::type type;
        };
    };

    // Outer indexing operators that dispatch to the right node's
    // get() function.
    template <class KW>
    typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
    operator[](keyword<KW> const& x) const
    {
        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
        return sublist.get(x);
    }

    template <class KW, class Default>
    typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
    operator[](default_<KW, Default> x) const
    {
        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
        return sublist.get(x);
    }

    template <class KW, class F>
    typename mpl::apply_wrap3<
        binding,KW
      , typename result_of0<F>::type
      , mpl::true_
    >::type
    operator[](lazy_default<KW,F> x) const
    {
        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
        return sublist.get(x);
    }

    // These just return the stored value; when empty_arg_list is
    // reached, indicating no matching argument was passed, the
    // default is returned, or if no default_ or lazy_default was
    // passed, compilation fails.
    reference get(keyword<key_type> const&) const
    {
        BOOST_MPL_ASSERT_NOT((holds_maybe));
        return arg.value;
    }

    template <class Default>
    reference get(default_<key_type,Default> const& d) const
    {
        return get_default(d, holds_maybe());
    }

    template <class Default>
    reference get(lazy_default<key_type, Default>) const
    {
        return arg.value;
    }

#else

    reference operator[](keyword<key_type> const&) const
    {
        BOOST_MPL_ASSERT_NOT((holds_maybe));
        return arg.value;
    }

    template <class Default>
    reference operator[](default_<key_type, Default> const& d) const
    {
        return get_default(d, holds_maybe());
    }

    template <class Default>
    reference operator[](lazy_default<key_type, Default>) const
    {
        return arg.value;
    }

    // Builds an overload set including operator[]s defined in base
    // classes.
    using Next::operator[];

    //
    // End of indexing support
    //


    //
    // For parameter_requirements matching this node's key_type,
    // return a bool constant wrapper indicating whether the
    // requirements are satisfied by TaggedArg.  Used only for
    // compile-time computation and never really called, so a
    // declaration is enough.
    //
    template <class HasDefault, class Predicate, class ArgPack>
    static typename mpl::apply_wrap2<
        typename mpl::lambda<Predicate, lambda_tag>::type
      , value_type, ArgPack
    >::type
    satisfies(
        parameter_requirements<key_type,Predicate,HasDefault>*
      , ArgPack*
    );

    // Builds an overload set including satisfies functions defined
    // in base classes.
    using Next::satisfies;
#endif

    // Comma operator to compose argument list without using parameters<>.
    // Useful for argument lists with undetermined length.
    template <class KW, class T2>
    arg_list<tagged_argument<KW, T2>, self>
    operator,(tagged_argument<KW,T2> x) const
    {
        return arg_list<tagged_argument<KW,T2>, self>(x, *this);
    }

    // MPL sequence support
    typedef self type;             // Convenience for users
    typedef Next tail_type;        // For the benefit of iterators
    typedef arg_list_tag tag; // For dispatching to sequence intrinsics
};

#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)  // ETI workaround
template <> struct arg_list<int,int> {};
#endif

// MPL sequence support
template <class ArgumentPack>
struct arg_list_iterator
{
    typedef mpl::forward_iterator_tag category;

    // The incremented iterator
    typedef arg_list_iterator<typename ArgumentPack::tail_type> next;

    // dereferencing yields the key type
    typedef typename ArgumentPack::key_type type;
};

template <>
struct arg_list_iterator<empty_arg_list> {};

}} // namespace parameter::aux

// MPL sequence support
namespace mpl
{
  template <>
  struct begin_impl<parameter::aux::arg_list_tag>
  {
      template <class S>
      struct apply
      {
          typedef parameter::aux::arg_list_iterator<S> type;
      };
  };

  template <>
  struct end_impl<parameter::aux::arg_list_tag>
  {
      template <class>
      struct apply
      {
          typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
      };
  };
}

} // namespace boost

#endif // ARG_LIST_050329_HPP

