// Copyright David Abrahams 2006. Distributed under 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 BOOST_PP_IS_ITERATING

# ifndef NEW_DWA2006324_HPP
#  define NEW_DWA2006324_HPP

#  include "forward.hpp"

#  include <boost/preprocessor/iteration/iterate.hpp>
#  include <boost/preprocessor/repetition/enum_params.hpp>
#  include <boost/preprocessor/seq/for_each.hpp>

#  include <memory>

#  ifndef BOOST_NEW_MAX_ARITY
#   define BOOST_NEW_MAX_ARITY 5
#  endif 

template <class T>
std::auto_ptr<T> new_()
{
    return std::auto_ptr<T>(new T);
}

# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_NEW_MAX_ARITY, "new.hpp"))
# include BOOST_PP_ITERATE()

# endif // NEW_DWA2006324_HPP

#elif BOOST_PP_ITERATION_DEPTH() == 1

// Generate the first few iterations using vertical repetition.  This
// method is about twice as slow on G++ as using horizontal
// repetition, but more debuggable.
# if BOOST_PP_ITERATION() < 4

# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, (1 << BOOST_PP_ITERATION()) - 1, "new.hpp"))
# include BOOST_PP_ITERATE()

# else

// Generate later iterations using horizontal repetition.
#  define NEW_arity BOOST_PP_ITERATION()
#  define BOOST_FORWARD_new(r, ignored, constness_seq)                          \
template <class T, BOOST_PP_ENUM_PARAMS_Z(1, NEW_arity, class A) >            \
std::auto_ptr<T> new_( BOOST_FORWARD_ENUM_BINARY_PARAM_SEQ_R(r, constness_seq, A, x) )  \
{                                                                               \
    return std::auto_ptr<T>(new T(BOOST_PP_ENUM_PARAMS_Z(1, NEW_arity, x)));  \
}

BOOST_PP_SEQ_FOR_EACH(BOOST_FORWARD_new, ~, BOOST_FORWARD_BINARY_SEQ(BOOST_PP_ITERATION()))
#  undef NEW_arity
    
# endif 

#elif BOOST_PP_ITERATION_DEPTH() == 2

# define NEW_arity BOOST_PP_FRAME_ITERATION(1)
# define NEW_binary BOOST_FORWARD_BINARY_SEQ(NEW_arity)

# define NEW_constness BOOST_PP_SEQ_ELEM(BOOST_PP_ITERATION(), NEW_binary)

template <class T, BOOST_PP_ENUM_PARAMS_Z(1, NEW_arity, class A) >
std::auto_ptr<T> new_( BOOST_FORWARD_ENUM_BINARY_PARAM_SEQ_R(1, NEW_constness, A, x) )
{
    return std::auto_ptr<T>(new T(BOOST_PP_ENUM_PARAMS_Z(1, NEW_arity, x)));
}

# undef NEW_arity
# undef NEW_binary
# undef NEW_constness

#endif 

