from gen_function import *
import string

def gen_struct_signatures(args):
    result = ''
    for n in range(args, -1, -1):
        result = (
            result + gen_function("""%{template <%(class T%n%:, %)>
%}struct signature%x {};

""", n)
#            + ((n == args) and [""] or
#               [gen_function("""
#    template <class X>
#    static inline signature%1<X%(, T%n%)> prepend(type<X>)
#        { return signature%1<X%(, T%n%)>(); }""",
#                         n, (str(n+1),))
#                ]
#               )[0]
#            
#            + ((n != 0) and [""] or
#               ["""
#    // This one terminates the chain. Prepending void_t to the head of a void_t
#    // signature results in a void_t signature again.
#    static inline signature0 prepend(void_t) { return signature0(); }"""]
#               )[0]
#            + """
#};
#
#"""
 + ((n == args) and [""] or
            [gen_function(
"""template <%(class T%n%, %)class X>
inline signature%1<X%(, T%n%)> prepend(type<X>, signature%x%{<%(T%n%:, %)>%})
    { return signature%1<X%(, T%n%)>(); }

""", n, str(n+1))
             ]
       )[0]
            )
    return result

def gen_signatures(args):
    return (
"""//  (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
//  distribute this software is granted provided this copyright notice appears
//  in all copies. This software is provided "as is" without express or implied
//  warranty, and with no claim as to its suitability for any purpose.
//
//  The author gratefully acknowleges the support of Dragon Systems, Inc., in
//  producing this work.
//
//  This file automatically generated by gen_signatures.python for %d arguments.
#ifndef SIGNATURES_DWA050900_H_
# define SIGNATURES_DWA050900_H_

# include <boost/python/detail/config.hpp>

namespace boost { namespace python {

namespace detail {
// A stand-in for the built-in void. This one can be passed to functions and
// (under MSVC, which has a bug, be used as a default template type parameter).
struct void_t {};
}

// An envelope in which type information can be delivered for the purposes
// of selecting an overloaded from_python() function. This is needed to work
// around MSVC's lack of partial specialiation/ordering. Where normally we'd
// want to form a function call like void f<const T&>(), We instead pass
// type<const T&> as one of the function parameters to select a particular
// overload.
//
// The id typedef helps us deal with the lack of partial ordering by generating
// unique types for constructor signatures. In general, type<T>::id is type<T>,
// but type<void_t>::id is just void_t.
template <class T>
struct type
{
    typedef type id;
};

template <>
struct type<boost::python::detail::void_t>
{
    typedef boost::python::detail::void_t id;
};

namespace detail {
// These basically encapsulate a chain of types, , used to make the syntax of
// add(constructor<T1, ...>()) work. We need to produce a unique type for each number
// of non-default parameters to constructor<>.  Q: why not use a recursive
// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs
// that involve recursive template nesting.
//
// signature chaining
""" % args
        + gen_struct_signatures(args)
        + """
// This one terminates the chain. Prepending void_t to the head of a void_t
// signature results in a void_t signature again.
inline signature0 prepend(void_t, signature0) { return signature0(); }

} // namespace detail
"""
        + gen_function("""
template <%(class A%n% = detail::void_t%:, %)>
struct constructor
{
};
""", args)
        + """
namespace detail {
// Return value extraction:

// This is just another little envelope for carrying a typedef (see type,
// above). I could have re-used type, but that has a very specific purpose. I
// thought this would be clearer.
template <class T>
struct return_value_select { typedef T type; };

// free functions"""
        + gen_functions("""
template <class R%(, class A%n%)>
return_value_select<R> return_value(R (*)(%(A%n%:, %))) { return return_value_select<R>(); }
""", args)

        +
"""
// TODO(?): handle 'const void'

// member functions"""
        + gen_functions("""
template <class R, class T%(, class A%n%)>
return_value_select<R> return_value(R (T::*)(%(A%n%:, %))) { return return_value_select<R>(); }
""", args)

        + gen_functions("""
template <class R, class T%(, class A%n%)>
return_value_select<R> return_value(R (T::*)(%(A%n%:, %)) const) { return return_value_select<R>(); }
""", args)

        + """
}}} // namespace boost::python::detail

#endif
""")

if __name__ == '__main__':
    import sys

    if len(sys.argv) == 1:
        args = 5
    else:
        args = int(sys.argv[1])

    print gen_signatures(args)

