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 # static inline Signature%1 prepend(Type) # { return Signature%1(); }""", # n, (str(n+1),)) # ] # )[0] # # + ((n != 0) and [""] or # [""" # // This one terminates the chain. Prepending Void to the head of a Void # // signature results in a Void signature again. # static inline Signature0 prepend(Void) { return Signature0(); }"""] # )[0] # + """ #}; # #""" + ((n == args) and [""] or [gen_function( """template <%(class T%n%, %)class X> inline Signature%1 prepend(Type, Signature%x%{<%(T%n%:, %)>%}) { return Signature%1(); } """, 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.py for %d arguments. #ifndef SIGNATURES_DWA050900_H_ # define SIGNATURES_DWA050900_H_ # include "pyconfig.h" namespace py { // 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 {}; // 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(), We instead pass // Type 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::Id is Type, // but Type::Id is just Void. template struct Type { typedef Type Id; }; template <> struct Type { typedef Void Id; }; // These basically encapsulate a chain of types, , used to make the syntax of // add(Constructor()) 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 to the head of a Void // signature results in a Void signature again. inline Signature0 prepend(Void, Signature0) { return Signature0(); } """ + gen_function(""" template <%(class A%n% = Void%:, %)> struct Constructor { }; """, args) + """ // 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 struct ReturnValue { typedef T Type; }; // free functions""" + gen_functions(""" template ReturnValue return_value(R (*)(%(A%n%:, %))) { return ReturnValue(); } """, args) + """ // TODO(?): handle 'const void' // member functions""" + gen_functions(""" template ReturnValue return_value(R (T::*)(%(A%n%:, %))) { return ReturnValue(); } """, args) + gen_functions(""" template ReturnValue return_value(R (T::*)(%(A%n%:, %)) const) { return ReturnValue(); } """, args) + """ } #endif """) if __name__ == '__main__': import sys if len(sys.argv) == 1: args = 5 else: args = int(sys.argv[1]) print gen_signatures(args)