// (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 5 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 template struct Signature5 {}; template struct Signature4 {}; template inline Signature5 prepend(Type, Signature4) { return Signature5(); } template struct Signature3 {}; template inline Signature4 prepend(Type, Signature3) { return Signature4(); } template struct Signature2 {}; template inline Signature3 prepend(Type, Signature2) { return Signature3(); } template struct Signature1 {}; template inline Signature2 prepend(Type, Signature1) { return Signature2(); } struct Signature0 {}; template inline Signature1 prepend(Type, Signature0) { return Signature1(); } // 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(); } template struct Constructor { }; // 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 template ReturnValue return_value(R (*)()) { return ReturnValue(); } template ReturnValue return_value(R (*)(A1)) { return ReturnValue(); } template ReturnValue return_value(R (*)(A1, A2)) { return ReturnValue(); } template ReturnValue return_value(R (*)(A1, A2, A3)) { return ReturnValue(); } template ReturnValue return_value(R (*)(A1, A2, A3, A4)) { return ReturnValue(); } template ReturnValue return_value(R (*)(A1, A2, A3, A4, A5)) { return ReturnValue(); } // TODO(?): handle 'const void' // member functions template ReturnValue return_value(R (T::*)()) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1)) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2)) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3)) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3, A4)) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3, A4, A5)) { return ReturnValue(); } template ReturnValue return_value(R (T::*)() const) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1) const) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2) const) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3) const) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3, A4) const) { return ReturnValue(); } template ReturnValue return_value(R (T::*)(A1, A2, A3, A4, A5) const) { return ReturnValue(); } } #endif