text: /*=============================================================================
      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).
  ==============================================================================*/
  
  #if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_GENERIC_HPP_INCLUDED)
  #if !defined(BOOST_PP_IS_ITERATING)
  
  #include <boost/config.hpp>
  #include <boost/detail/workaround.hpp>
  
  #include <boost/preprocessor/cat.hpp>
  #include <boost/preprocessor/iteration/iterate.hpp>
  #include <boost/preprocessor/repetition/enum_params.hpp>
  #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  #include <boost/preprocessor/facilities/intercept.hpp>
  
  #include <boost/fusion/container/vector/vector.hpp>
  
  #include <boost/fusion/functional/adapter/limits.hpp>
  #include <boost/fusion/functional/adapter/detail/access.hpp>
  
  #include <boost/utility/result_of.hpp>
  
  namespace boost { namespace fusion
  {
      template <class Function> class unfused_generic;
  
      //----- ---- --- -- - -  -   -
  
      template <class Function> 
      class unfused_generic
      {
          Function fnc_transformed;
  
          typedef typename detail::qf_c<Function>::type function_c;
          typedef typename detail::qf<Function>::type function;
  
          typedef typename detail::call_param<Function>::type func_const_fwd_t;
  
        public:
  
          inline explicit unfused_generic(func_const_fwd_t f = Function())
              : fnc_transformed(f)
          { }
  
          template <typename Sig>
          struct result;
  
          typedef typename boost::result_of<
              function_c(fusion::vector0 &) >::type call_const_0_result;
  
          inline call_const_0_result operator()() const
          {
              fusion::vector0 arg;
              return this->fnc_transformed(arg);
          }
  
          typedef typename boost::result_of< 
              function (fusion::vector0 &) >::type call_0_result;
  
          inline call_0_result operator()() 
          {
              fusion::vector0 arg;
              return this->fnc_transformed(arg);
          }
  
          #define BOOST_FUSION_CODE(tpl_params,arg_types,params,args)             \
          template <tpl_params>                                                  \
          inline typename boost::result_of<function_c(                           \
              BOOST_PP_CAT(fusion::vector,N)<arg_types> & )>::type               \
          operator()(params) const                                               \
          {                                                                      \
              BOOST_PP_CAT(fusion::vector,N)<arg_types> arg(args);               \
              return this->fnc_transformed(arg);                                 \
          }                                                                      \
          template <tpl_params>                                                  \
          inline typename boost::result_of<function(                             \
              BOOST_PP_CAT(fusion::vector,N)<arg_types> & )>::type               \
          operator()(params)                                                     \
          {                                                                      \
              BOOST_PP_CAT(fusion::vector,N)<arg_types> arg(args);               \
              return this->fnc_transformed(arg);                                 \
          }
  
          #define  BOOST_PP_INDIRECT_SELF                                        \
              <boost/fusion/functional/adapter/unfused_generic.hpp>
          #define  BOOST_PP_FILENAME_1                                           \
              <boost/fusion/functional/adapter/detail/pow2_explode.hpp>
          #define  BOOST_PP_ITERATION_LIMITS                                     \
              (1,BOOST_FUSION_UNFUSED_GENERIC_MAX_ARITY)
          #define  N BOOST_PP_ITERATION_1
          #include BOOST_PP_ITERATE()
          #undef   N
  
          #undef BOOST_FUSION_CODE
      };
  }}
  
  namespace boost 
  {
      template<class F>
      struct result_of<boost::fusion::unfused_generic<F> const ()>
      {
          typedef typename boost::fusion::unfused_generic<F>::call_const_0_result type;
      };
      template<class F>
      struct result_of<boost::fusion::unfused_generic<F>()>
      {
          typedef typename boost::fusion::unfused_generic<F>::call_0_result type;
      };
  }
  
  #define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_GENERIC_HPP_INCLUDED
  #else // defined(BOOST_PP_IS_ITERATING)
  ///////////////////////////////////////////////////////////////////////////////
  //
  //  Preprocessor vertical repetition code
  //
  ///////////////////////////////////////////////////////////////////////////////
  
  #include <boost/fusion/functional/adapter/detail/pt_def.hpp>
  
  #if BOOST_PP_SLOT_1() == 0 
          template <class Self, BOOST_PP_ENUM_PARAMS(N,typename T)>
          struct result
              < Self const (BOOST_PP_ENUM_PARAMS(N,T)) >
              : boost::result_of<function_c(
                  BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N,
                     typename detail::gref<T,>::type BOOST_PP_INTERCEPT) > & )>
          { };
  
          template <class Self, BOOST_PP_ENUM_PARAMS(N,typename T)>
          struct result
              < Self(BOOST_PP_ENUM_PARAMS(N,T)) >
              : boost::result_of<function(
                  BOOST_PP_CAT(fusion::vector,N)< BOOST_PP_ENUM_BINARY_PARAMS(N,
                     typename detail::gref<T,>::type BOOST_PP_INTERCEPT) > & )>
          { };
  #endif
  
  #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) 
          template <BOOST_PP_ENUM_PARAMS(N,typename T)>
          inline typename boost::result_of<function_c(
              BOOST_PP_CAT(fusion::vector,N)<BOOST_PP_ENUM_PARAMS(N,PT)> & )>::type
          operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
          {
              BOOST_PP_CAT(fusion::vector,N)<BOOST_PP_ENUM_PARAMS(N,PT)>
                  arg(BOOST_PP_ENUM_PARAMS(N,a));
              return this->fnc_transformed(arg);
          }
          template <BOOST_PP_ENUM_PARAMS(N,typename T)>
          inline typename boost::result_of<function(
              BOOST_PP_CAT(fusion::vector,N)<BOOST_PP_ENUM_PARAMS(N,PT)> & )>::type
          operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
          {
              BOOST_PP_CAT(fusion::vector,N)<BOOST_PP_ENUM_PARAMS(N,PT)>
                  arg(BOOST_PP_ENUM_PARAMS(N,a));
              return this->fnc_transformed(arg);
          }
  #else
          BOOST_FUSION_CODE(BOOST_PP_ENUM_PARAMS(N,typename T),
              BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
              BOOST_PP_ENUM_PARAMS(N,a) )
          // ...generates uglier code but is faster - it caches ENUM_*
  #endif
  
  #include <boost/fusion/functional/adapter/detail/pt_undef.hpp>
  
  #endif // defined(BOOST_PP_IS_ITERATING)
  #endif
  
  