mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 05:02:17 +00:00
Handle non-const reference parameters in constructors
[SVN r8048]
This commit is contained in:
@@ -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 <bool is_ref>
|
||||
struct const_ref_selector
|
||||
{
|
||||
template <class T>
|
||||
struct const_ref
|
||||
{
|
||||
typedef const T& type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct const_ref_selector<true>
|
||||
{
|
||||
template <class T>
|
||||
struct const_ref
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4181)
|
||||
# endif // BOOST_MSVC
|
||||
template <class T>
|
||||
struct parameter_traits
|
||||
{
|
||||
private:
|
||||
typedef const_ref_selector<boost::is_reference<T>::value> selector;
|
||||
public:
|
||||
typedef typename selector::const_ref<T>::type const_reference;
|
||||
};
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
# endif // BOOST_MSVC
|
||||
|
||||
#else
|
||||
template <class T>
|
||||
struct parameter_traits
|
||||
{
|
||||
typedef const T& const_reference;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct parameter_traits<T&>
|
||||
{
|
||||
typedef T& const_reference;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct parameter_traits<void>
|
||||
{
|
||||
typedef void const_reference;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class reference_parameter
|
||||
{
|
||||
typedef typename parameter_traits<T>::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<T%(, A%n%)>; }
|
||||
%} static Init* create(Signature%x%{<%(A%n%:, %)>%}) {
|
||||
return new Init%x<T%(,
|
||||
detail::parameter_traits<A%n>::const_reference%)>;
|
||||
}
|
||||
""", args)+"""};
|
||||
|
||||
class Init : public Function
|
||||
@@ -58,11 +136,11 @@ struct Init%x : Init
|
||||
%)if (!PyArg_ParseTuple(args, const_cast<char*>("%(O%)")%(, &a%n%)))
|
||||
throw ArgumentError();
|
||||
return new T(self%(,
|
||||
from_python(a%n, Type<A%n>())%)
|
||||
py::detail::reference_parameter<A%n>(from_python(a%n, Type<A%n>()))%)
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(%(A%n%:, %))).name(); }
|
||||
{ return typeid(void (*)(T&%(, A%n%%))).name(); }
|
||||
};""", args) + """
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user