From ce2e4cb0b3509bf338cb9f855323a5ad8bed9900 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 28 Oct 2000 21:45:46 +0000 Subject: [PATCH] Handle non-const reference parameters in constructors [SVN r8048] --- gen_init_function.py | 86 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/gen_init_function.py b/gen_init_function.py index 3dd66aa9..a34e8ba3 100644 --- a/gen_init_function.py +++ b/gen_init_function.py @@ -24,6 +24,82 @@ def gen_init_function(args): namespace py { +namespace detail { + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // parameter_traits - so far, this is a way to pass a const T& when we can be + // sure T is not a reference type, and a raw T otherwise. This should be + // rolled into boost::call_traits. + template + struct const_ref_selector + { + template + struct const_ref + { + typedef const T& type; + }; + }; + + template <> + struct const_ref_selector + { + template + struct const_ref + { + typedef T type; + }; + }; + +# ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4181) +# endif // BOOST_MSVC + template + struct parameter_traits + { + private: + typedef const_ref_selector::value> selector; + public: + typedef typename selector::const_ref::type const_reference; + }; +# ifdef BOOST_MSVC +# pragma warning(pop) +# endif // BOOST_MSVC + +#else + template + struct parameter_traits + { + typedef const T& const_reference; + }; + + template + struct parameter_traits + { + typedef T& const_reference; + }; +#endif + + template <> + struct parameter_traits + { + typedef void const_reference; + }; + + template + class reference_parameter + { + typedef typename parameter_traits::const_reference const_reference; + public: + reference_parameter(const_reference value) + : value(value) {} + operator const_reference() { return value; } + private: + const_reference value; + }; +} + class ExtensionInstance; class InstanceHolderBase; @@ -36,8 +112,10 @@ struct InitFunction { """ + gen_functions("""%{ template <%(class A%n%:, %)> -%} static Init* create(Signature%x%{<%(A%n%:, %)>%}) - { return new Init%x; } +%} static Init* create(Signature%x%{<%(A%n%:, %)>%}) { + return new Init%x::const_reference%)>; + } """, args)+"""}; class Init : public Function @@ -58,11 +136,11 @@ struct Init%x : Init %)if (!PyArg_ParseTuple(args, const_cast("%(O%)")%(, &a%n%))) throw ArgumentError(); return new T(self%(, - from_python(a%n, Type())%) + py::detail::reference_parameter(from_python(a%n, Type()))%) ); } const char* description() const - { return typeid(void (*)(%(A%n%:, %))).name(); } + { return typeid(void (*)(T&%(, A%n%%))).name(); } };""", args) + """ }