mirror of
https://github.com/boostorg/python.git
synced 2026-01-26 18:52:26 +00:00
Handle non-const reference parameters to constructors.
Correct error-reporting for mismatch in overloaded constructors. [SVN r8049]
This commit is contained in:
164
init_function.h
164
init_function.h
@@ -18,6 +18,82 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -32,28 +108,49 @@ template <class T, class A1, class A2, class A3, class A4, class A5> struct Init
|
||||
template <class T>
|
||||
struct InitFunction
|
||||
{
|
||||
static Init* create(Signature0)
|
||||
{ return new Init0<T>; }
|
||||
static Init* create(Signature0) {
|
||||
return new Init0<T>;
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static Init* create(Signature1<A1>)
|
||||
{ return new Init1<T, A1>; }
|
||||
static Init* create(Signature1<A1>) {
|
||||
return new Init1<T,
|
||||
detail::parameter_traits<A1>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static Init* create(Signature2<A1, A2>)
|
||||
{ return new Init2<T, A1, A2>; }
|
||||
static Init* create(Signature2<A1, A2>) {
|
||||
return new Init2<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static Init* create(Signature3<A1, A2, A3>)
|
||||
{ return new Init3<T, A1, A2, A3>; }
|
||||
static Init* create(Signature3<A1, A2, A3>) {
|
||||
return new Init3<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static Init* create(Signature4<A1, A2, A3, A4>)
|
||||
{ return new Init4<T, A1, A2, A3, A4>; }
|
||||
static Init* create(Signature4<A1, A2, A3, A4>) {
|
||||
return new Init4<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static Init* create(Signature5<A1, A2, A3, A4, A5>)
|
||||
{ return new Init5<T, A1, A2, A3, A4, A5>; }
|
||||
static Init* create(Signature5<A1, A2, A3, A4, A5>) {
|
||||
return new Init5<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference>;
|
||||
}
|
||||
};
|
||||
|
||||
class Init : public Function
|
||||
@@ -76,7 +173,7 @@ struct Init0 : Init
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)()).name(); }
|
||||
{ return typeid(void (*)(T&)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1>
|
||||
@@ -88,11 +185,11 @@ struct Init1 : Init
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &a1))
|
||||
throw ArgumentError();
|
||||
return new T(self,
|
||||
from_python(a1, Type<A1>())
|
||||
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(A1)).name(); }
|
||||
{ return typeid(void (*)(T&, A1)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
@@ -105,12 +202,12 @@ struct Init2 : Init
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
|
||||
throw ArgumentError();
|
||||
return new T(self,
|
||||
from_python(a1, Type<A1>()),
|
||||
from_python(a2, Type<A2>())
|
||||
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
|
||||
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(A1, A2)).name(); }
|
||||
{ return typeid(void (*)(T&, A1, A2)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3>
|
||||
@@ -124,13 +221,13 @@ struct Init3 : Init
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOO"), &a1, &a2, &a3))
|
||||
throw ArgumentError();
|
||||
return new T(self,
|
||||
from_python(a1, Type<A1>()),
|
||||
from_python(a2, Type<A2>()),
|
||||
from_python(a3, Type<A3>())
|
||||
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
|
||||
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
|
||||
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(A1, A2, A3)).name(); }
|
||||
{ return typeid(void (*)(T&, A1, A2, A3)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4>
|
||||
@@ -145,14 +242,14 @@ struct Init4 : Init
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOO"), &a1, &a2, &a3, &a4))
|
||||
throw ArgumentError();
|
||||
return new T(self,
|
||||
from_python(a1, Type<A1>()),
|
||||
from_python(a2, Type<A2>()),
|
||||
from_python(a3, Type<A3>()),
|
||||
from_python(a4, Type<A4>())
|
||||
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
|
||||
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
|
||||
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
|
||||
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(A1, A2, A3, A4)).name(); }
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5>
|
||||
@@ -168,17 +265,18 @@ struct Init5 : Init
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOO"), &a1, &a2, &a3, &a4, &a5))
|
||||
throw ArgumentError();
|
||||
return new T(self,
|
||||
from_python(a1, Type<A1>()),
|
||||
from_python(a2, Type<A2>()),
|
||||
from_python(a3, Type<A3>()),
|
||||
from_python(a4, Type<A4>()),
|
||||
from_python(a5, Type<A5>())
|
||||
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
|
||||
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
|
||||
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
|
||||
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
|
||||
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(A1, A2, A3, A4, A5)).name(); }
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // INIT_FUNCTION_DWA052000_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user