mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 18:12:43 +00:00
object_core.hpp - allow wrapping of objects which take object managers in their constructors.
forward.hpp
pointer_holder.hpp
value_holder.hpp
test/long.[py/cpp]
pointee.hpp, - begin making borland work.
cv_category.hpp,
referent_storage.hpp
instance.hpp
self.hpp - removed flotsam
signature.hpp - use vector instead of list
destroy.hpp - removed needless complication
make_keyword_range_fn.hpp - support for simpler init using vectors
class_converters.hpp - workaround for pro7
inheritance.hpp - simplified; took out pro7 workarounds; factored out
inheritance_query.hpp to reduce recompilation
dependencies
make_ptr_instance.hpp - add missing typename
registry.cpp - add a little invariant checking for metrowerks
class.cpp - stopped relying on class_id typedef
test/data_members.cpp - added a few more tests to make sure things compile at least.
test/destroy_test.cpp - removed cheating has_trivial_destructor tests
test/enum.cpp - added some pro7 workarounds
test/virtual_functions.[py/cpp] - added _some_ tests for callbacks which return by reference.
[SVN r18489]
This commit is contained in:
@@ -24,9 +24,12 @@ typedef cv_tag<true,true> const_volatile_;
|
||||
template <class T>
|
||||
struct cv_category
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
typedef cv_tag<c,v> type;
|
||||
// BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
|
||||
// BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
|
||||
typedef cv_tag<
|
||||
::boost::is_const<T>::value
|
||||
, ::boost::is_volatile<T>::value
|
||||
> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -6,15 +6,14 @@
|
||||
#ifndef DESTROY_DWA2002221_HPP
|
||||
# define DESTROY_DWA2002221_HPP
|
||||
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/type_traits/is_array.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <bool array, bool trivial_destructor> struct value_destroyer;
|
||||
|
||||
template <bool array> struct value_destroyer;
|
||||
|
||||
template <>
|
||||
struct value_destroyer<false,false>
|
||||
struct value_destroyer<false>
|
||||
{
|
||||
template <class T>
|
||||
static void execute(T const volatile* p)
|
||||
@@ -24,16 +23,17 @@ struct value_destroyer<false,false>
|
||||
};
|
||||
|
||||
template <>
|
||||
struct value_destroyer<true,false>
|
||||
struct value_destroyer<true>
|
||||
{
|
||||
template <class A, class T>
|
||||
static void execute(A*, T const volatile* const first)
|
||||
{
|
||||
for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
|
||||
{
|
||||
value_destroyer<
|
||||
boost::is_array<T>::value
|
||||
,boost::has_trivial_destructor<T>::value
|
||||
>::execute(p);
|
||||
>::execute(p);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -43,24 +43,6 @@ struct value_destroyer<true,false>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct value_destroyer<true,true>
|
||||
{
|
||||
template <class T>
|
||||
static void execute(T const volatile*)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct value_destroyer<false,true>
|
||||
{
|
||||
template <class T>
|
||||
static void execute(T const volatile*)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void destroy_referent_impl(void* p, T& (*)())
|
||||
{
|
||||
@@ -68,8 +50,7 @@ inline void destroy_referent_impl(void* p, T& (*)())
|
||||
// must come *before* T for metrowerks
|
||||
value_destroyer<
|
||||
(boost::is_array<T>::value)
|
||||
,(boost::has_trivial_destructor<T>::value)
|
||||
>::execute((const volatile T*)p);
|
||||
>::execute((const volatile T*)p);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -34,17 +34,15 @@ object make_keyword_range_function(F f, Policies const& policies, keyword_range
|
||||
// constructor.
|
||||
//
|
||||
// Holder and ArgList are intended to be explicitly specified.
|
||||
template <class ArgList, class Holder, class CallPolicies>
|
||||
template <class ArgList, class Arity, class Holder, class CallPolicies>
|
||||
object make_keyword_range_constructor(
|
||||
CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor
|
||||
, detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords
|
||||
, Holder* = 0
|
||||
, ArgList* = 0)
|
||||
, ArgList* = 0, Arity* = 0)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, arity = mpl::size<ArgList>::value);
|
||||
|
||||
return detail::make_keyword_range_function(
|
||||
objects::make_holder<arity>
|
||||
objects::make_holder<Arity::value>
|
||||
::template apply<Holder,ArgList>::execute
|
||||
, policies
|
||||
, kw);
|
||||
|
||||
@@ -67,7 +67,9 @@ union aligned_storage
|
||||
template <class T>
|
||||
struct referent_storage
|
||||
{
|
||||
typedef aligned_storage<referent_size<T>::value> type;
|
||||
typedef aligned_storage<
|
||||
::boost::python::detail::referent_size<T>::value
|
||||
> type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
|
||||
@@ -58,11 +59,15 @@ struct register_base_of
|
||||
register_conversion<Derived,Base>(false);
|
||||
|
||||
// Register the down-cast, if appropriate.
|
||||
mpl::if_c<
|
||||
is_polymorphic<Base>::value
|
||||
, register_downcast<Base,Derived>
|
||||
, do_nothing
|
||||
>::type::execute();
|
||||
mpl::if_<
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
mpl::true_
|
||||
# else
|
||||
is_polymorphic<Base>
|
||||
# endif
|
||||
, register_downcast<Base,Derived>
|
||||
, do_nothing
|
||||
>::type::execute();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
# define FORWARD_DWA20011215_HPP
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/type_traits/is_scalar.hpp>
|
||||
# include <boost/type_traits/add_const.hpp>
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# include <boost/ref.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
@@ -24,7 +23,7 @@ struct reference_to_value
|
||||
typedef typename add_reference<typename add_const<T>::type>::type reference;
|
||||
|
||||
reference_to_value(reference x) : m_value(x) {}
|
||||
operator reference() const { return m_value; }
|
||||
reference get() const { return m_value; }
|
||||
private:
|
||||
reference m_value;
|
||||
};
|
||||
@@ -34,27 +33,43 @@ struct reference_to_value
|
||||
// is T.
|
||||
template <class T>
|
||||
struct forward
|
||||
: mpl::if_c<
|
||||
is_scalar<T>::value
|
||||
: mpl::if_<
|
||||
is_scalar<T>
|
||||
, T
|
||||
, reference_to_value<T> >
|
||||
, reference_to_value<T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class unforward
|
||||
struct unforward
|
||||
{
|
||||
public:
|
||||
typedef typename unwrap_reference<T>::type& type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unforward<reference_to_value<T> >
|
||||
struct unforward<reference_to_value<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unforward_cref
|
||||
: add_reference<
|
||||
typename add_const<
|
||||
typename unwrap_reference<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct unforward_cref<reference_to_value<T> >
|
||||
: add_reference<typename add_const<T>::type>
|
||||
{
|
||||
};
|
||||
|
||||
# else // no partial specialization
|
||||
|
||||
namespace detail
|
||||
@@ -87,26 +102,81 @@ namespace detail
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_reference_to_value
|
||||
template<bool wrapped = false>
|
||||
struct cref_unforwarder
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
: add_reference<
|
||||
typename add_const<
|
||||
typename unwrap_reference<T>::type
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cref_unforwarder<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
: add_reference<
|
||||
typename add_const<
|
||||
typename T::reference
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_to_value
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(is_reference_to_value_test(boost::type<T>()))
|
||||
== sizeof(yes_reference_to_value_t)));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class unforward
|
||||
struct unforward
|
||||
: public detail::unforwarder<
|
||||
detail::is_reference_to_value<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct unforward_cref
|
||||
: public detail::cref_unforwarder<
|
||||
detail::is_reference_to_value<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class T>
|
||||
typename reference_to_value<T>::reference
|
||||
do_unforward(reference_to_value<T> const& x, int)
|
||||
{
|
||||
return x.get();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename reference_wrapper<T>::type&
|
||||
do_unforward(reference_wrapper<T> const& x, int)
|
||||
{
|
||||
return x.get();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const& do_unforward(T const& x, ...)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FORWARD_DWA20011215_HPP
|
||||
|
||||
@@ -26,11 +26,7 @@ BOOST_PYTHON_DECL void register_dynamic_id_aux(
|
||||
class_id static_id, dynamic_id_function get_dynamic_id);
|
||||
|
||||
BOOST_PYTHON_DECL void add_cast(
|
||||
class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic);
|
||||
|
||||
BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst);
|
||||
|
||||
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst);
|
||||
class_id src_t, class_id dst_t, void* (*cast)(void*), bool is_downcast);
|
||||
|
||||
//
|
||||
// a generator with an execute() function which, given a source type
|
||||
@@ -62,12 +58,12 @@ struct non_polymorphic_id_generator
|
||||
// Now the generalized selector
|
||||
template <class T>
|
||||
struct dynamic_id_generator
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
is_polymorphic<T>::value
|
||||
, polymorphic_id_generator<T>
|
||||
, non_polymorphic_id_generator<T> >::type type;
|
||||
};
|
||||
: mpl::if_<
|
||||
boost::is_polymorphic<T>
|
||||
, boost::python::objects::polymorphic_id_generator<T>
|
||||
, boost::python::objects::non_polymorphic_id_generator<T>
|
||||
>
|
||||
{};
|
||||
|
||||
// Register the dynamic id function for T with the type-conversion
|
||||
// system.
|
||||
@@ -108,45 +104,28 @@ struct implicit_cast_generator
|
||||
|
||||
template <class Source, class Target>
|
||||
struct cast_generator
|
||||
: mpl::if_<
|
||||
is_base_and_derived<Target,Source>
|
||||
, implicit_cast_generator<Source,Target>
|
||||
, dynamic_cast_generator<Source,Target>
|
||||
>
|
||||
{
|
||||
// It's OK to return false, since we can always cast up with
|
||||
// dynamic_cast<> if neccessary.
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
BOOST_STATIC_CONSTANT(bool, is_upcast = false);
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_upcast = (
|
||||
is_base_and_derived<Target,Source>::value
|
||||
));
|
||||
# endif
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
is_upcast
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
// grab a few more implicit_cast cases for CodeWarrior
|
||||
|| !is_polymorphic<Source>::value
|
||||
|| !is_polymorphic<Target>::value
|
||||
# endif
|
||||
, implicit_cast_generator<Source,Target>
|
||||
, dynamic_cast_generator<Source,Target>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
inline void register_conversion(
|
||||
// We need this parameter because CWPro7 can't determine
|
||||
// which is the base reliably.
|
||||
bool is_downcast = !cast_generator<Source,Target>::is_upcast
|
||||
|
||||
// These parameters shouldn't be used, they're an MSVC bug workaround
|
||||
bool is_downcast = ::boost::is_base_and_derived<Source,Target>::value
|
||||
// These parameters shouldn't be used; they're an MSVC bug workaround
|
||||
, Source* = 0, Target* = 0)
|
||||
{
|
||||
typedef typename cast_generator<Source,Target>::type generator;
|
||||
|
||||
add_cast(python::type_id<Source>()
|
||||
, python::type_id<Target>()
|
||||
, &generator::execute
|
||||
, is_downcast);
|
||||
|
||||
add_cast(
|
||||
python::type_id<Source>()
|
||||
, python::type_id<Target>()
|
||||
, &generator::execute
|
||||
, is_downcast
|
||||
);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
18
include/boost/python/object/inheritance_query.hpp
Executable file
18
include/boost/python/object/inheritance_query.hpp
Executable file
@@ -0,0 +1,18 @@
|
||||
// Copyright David Abrahams 2003. 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.
|
||||
#ifndef INHERITANCE_QUERY_DWA2003520_HPP
|
||||
# define INHERITANCE_QUERY_DWA2003520_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
BOOST_PYTHON_DECL void* find_static_type(void* p, type_info src, type_info dst);
|
||||
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, type_info src, type_info dst);
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // INHERITANCE_QUERY_DWA2003520_HPP
|
||||
@@ -26,8 +26,9 @@ struct instance
|
||||
PyObject* weakrefs;
|
||||
instance_holder* objects;
|
||||
|
||||
BOOST_STATIC_CONSTANT(std::size_t, alignment = alignment_of<Data>::value);
|
||||
typedef typename type_with_alignment<alignment>::type align_t;
|
||||
typedef typename type_with_alignment<
|
||||
::boost::alignment_of<Data>::value
|
||||
>::type align_t;
|
||||
|
||||
union
|
||||
{
|
||||
|
||||
@@ -37,7 +37,9 @@ struct make_ptr_instance
|
||||
if (p == 0)
|
||||
return 0;
|
||||
|
||||
PyTypeObject* derived = get_derived_class_object(is_polymorphic<U>::type(), p);
|
||||
PyTypeObject* derived = get_derived_class_object(
|
||||
BOOST_DEDUCED_TYPENAME is_polymorphic<U>::type(), p);
|
||||
|
||||
if (derived)
|
||||
return derived;
|
||||
return converter::registered<T>::converters.get_class_object();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
# include <boost/python/instance_holder.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/object/inheritance_query.hpp>
|
||||
# include <boost/python/object/forward.hpp>
|
||||
# include <boost/python/pointee.hpp>
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
@@ -43,7 +43,11 @@ bool is_null(T* p, int)
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)(a##n)
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
|
||||
# else
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
# endif
|
||||
|
||||
template <class Pointer, class Value>
|
||||
struct pointer_holder : instance_holder
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# include <boost/python/instance_holder.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/object/inheritance_query.hpp>
|
||||
# include <boost/python/object/forward.hpp>
|
||||
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
@@ -31,7 +31,11 @@
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)(a##n)
|
||||
# if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
|
||||
# else
|
||||
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0)
|
||||
# endif
|
||||
|
||||
template <class Held>
|
||||
struct value_holder : instance_holder
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
# include <boost/python/handle_fwd.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/slice_nil.hpp>
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/python/refcount.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/tag.hpp>
|
||||
|
||||
# include <boost/python/detail/raw_pyobject.hpp>
|
||||
# include <boost/python/detail/dependent.hpp>
|
||||
|
||||
# include <boost/python/object/forward.hpp>
|
||||
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/debug/line.hpp>
|
||||
|
||||
@@ -81,7 +84,7 @@ namespace api
|
||||
};
|
||||
# endif
|
||||
|
||||
template <bool is_proxy, bool is_object_manager> struct object_initializer;
|
||||
template <class T> struct object_initializer;
|
||||
|
||||
class object;
|
||||
typedef PyObject* (object::*bool_type)() const;
|
||||
@@ -211,19 +214,35 @@ namespace api
|
||||
public:
|
||||
// default constructor creates a None object
|
||||
object();
|
||||
|
||||
// explicit conversion from any C++ object to Python
|
||||
template <class T>
|
||||
explicit object(T const& x)
|
||||
: object_base(
|
||||
object_initializer<
|
||||
is_proxy<T>::value
|
||||
, converter::is_object_manager<T>::value
|
||||
>::get(&x, detail::convertible<object const*>::check(&x)))
|
||||
: object_base(
|
||||
object_initializer<
|
||||
BOOST_DEDUCED_TYPENAME unwrap_reference<T>::type
|
||||
>::get(
|
||||
do_unforward(x)
|
||||
, detail::convertible<object const*>::check(
|
||||
to_ptr(
|
||||
do_unforward(x)
|
||||
)
|
||||
)
|
||||
))
|
||||
{
|
||||
}
|
||||
|
||||
// Throw error_already_set() if the handle is null.
|
||||
BOOST_PYTHON_DECL explicit object(handle<> const&);
|
||||
private:
|
||||
template <class T>
|
||||
static T const* to_ptr(T const&) { return 0; }
|
||||
|
||||
template <class T>
|
||||
typename objects::unforward_cref<T>::type do_unforward(T const& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public: // implementation detail -- for internal use only
|
||||
explicit object(detail::borrowed_reference);
|
||||
@@ -264,47 +283,55 @@ namespace api
|
||||
// based on whether T is a proxy or derived from object
|
||||
//
|
||||
template <bool is_proxy = false, bool is_object_manager = false>
|
||||
struct object_initializer
|
||||
struct object_initializer_impl
|
||||
{
|
||||
static PyObject*
|
||||
get(object const* x, detail::yes_convertible)
|
||||
get(object const& x, detail::yes_convertible)
|
||||
{
|
||||
return python::incref(x->ptr());
|
||||
return python::incref(x.ptr());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static PyObject*
|
||||
get(T const* x, detail::no_convertible)
|
||||
get(T const& x, detail::no_convertible)
|
||||
{
|
||||
return python::incref(converter::arg_to_python<T>(*x).get());
|
||||
return python::incref(converter::arg_to_python<T>(x).get());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct object_initializer<true, false>
|
||||
struct object_initializer_impl<true, false>
|
||||
{
|
||||
template <class Policies>
|
||||
static PyObject*
|
||||
get(proxy<Policies> const* x, detail::no_convertible)
|
||||
get(proxy<Policies> const& x, detail::no_convertible)
|
||||
{
|
||||
return python::incref(x->operator object().ptr());
|
||||
return python::incref(x.operator object().ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct object_initializer<false, true>
|
||||
struct object_initializer_impl<false, true>
|
||||
{
|
||||
template <class T>
|
||||
static PyObject*
|
||||
get(T const* x, ...)
|
||||
get(T const& x, ...)
|
||||
{
|
||||
return python::incref(get_managed_object(*x, tag));
|
||||
return python::incref(get_managed_object(x, tag));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct object_initializer<true, true>
|
||||
struct object_initializer_impl<true, true>
|
||||
{}; // empty implementation should cause an error
|
||||
|
||||
template <class T>
|
||||
struct object_initializer : object_initializer_impl<
|
||||
is_proxy<T>::value
|
||||
, converter::is_object_manager<T>::value
|
||||
>
|
||||
{};
|
||||
|
||||
}
|
||||
using api::object;
|
||||
template <class T> struct extract;
|
||||
|
||||
@@ -31,7 +31,9 @@ namespace detail
|
||||
|
||||
template <class T>
|
||||
struct pointee
|
||||
: detail::pointee_impl<is_pointer<T>::value>::template apply<T>
|
||||
: detail::pointee_impl<
|
||||
::boost::is_pointer<T>::value
|
||||
>::template apply<T>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
//# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||
# define BOOST_PYTHON_SELF_IS_CLASS
|
||||
//# endif
|
||||
#define BOOST_PYTHON_SELF_IS_CLASS
|
||||
|
||||
// Sink self_t into its own namespace so that we have a safe place to
|
||||
// put the completely general operator templates which operate on
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
|
||||
# define BOOST_PYTHON_LIST_INC(n) \
|
||||
BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n))
|
||||
BOOST_PP_CAT(mpl::vector, BOOST_PP_INC(n))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
@@ -92,10 +92,16 @@ namespace // <unnamed>
|
||||
std::cout << "looking up " << type
|
||||
<< (p == entries().end() || p->target_type != type
|
||||
? "...NOT found\n" : "...found\n");
|
||||
# endif
|
||||
return const_cast<entry*>(
|
||||
&*entries().insert(entry(type)).first
|
||||
);
|
||||
# endif
|
||||
std::pair<registry_t::const_iterator,bool> pos_ins
|
||||
= entries().insert(entry(type));
|
||||
|
||||
# if __MWERKS__ >= 0x3000
|
||||
// do a little invariant checking if a change was made
|
||||
if ( pos_ins.second )
|
||||
assert(entries().invariants());
|
||||
# endif
|
||||
return const_cast<entry*>(&*pos_ins.first);
|
||||
}
|
||||
} // namespace <unnamed>
|
||||
|
||||
|
||||
@@ -437,7 +437,7 @@ namespace objects
|
||||
{
|
||||
// Find a registered class object corresponding to id. Return a
|
||||
// null handle if no such class is registered.
|
||||
inline type_handle query_class(class_id id)
|
||||
inline type_handle query_class(type_info id)
|
||||
{
|
||||
converter::registration const* p = converter::registry::query(id);
|
||||
return type_handle(
|
||||
@@ -448,7 +448,7 @@ namespace objects
|
||||
|
||||
// Find a registered class corresponding to id. If not found,
|
||||
// throw an appropriate exception.
|
||||
type_handle get_class(class_id id)
|
||||
type_handle get_class(type_info id)
|
||||
{
|
||||
type_handle result(query_class(id));
|
||||
|
||||
@@ -473,7 +473,7 @@ namespace objects
|
||||
// rest corresponding to its declared bases.
|
||||
//
|
||||
inline object
|
||||
new_class(char const* name, std::size_t num_types, class_id const* const types, char const* doc)
|
||||
new_class(char const* name, std::size_t num_types, type_info const* const types, char const* doc)
|
||||
{
|
||||
assert(num_types >= 1);
|
||||
|
||||
@@ -510,7 +510,7 @@ namespace objects
|
||||
}
|
||||
|
||||
class_base::class_base(
|
||||
char const* name, std::size_t num_types, class_id const* const types, char const* doc)
|
||||
char const* name, std::size_t num_types, type_info const* const types, char const* doc)
|
||||
: object(new_class(name, num_types, types, doc))
|
||||
{
|
||||
// Insert the new class object in the registry
|
||||
@@ -630,7 +630,7 @@ namespace objects
|
||||
));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL type_handle registered_class_object(class_id id)
|
||||
BOOST_PYTHON_DECL type_handle registered_class_object(type_info id)
|
||||
{
|
||||
return query_class(id);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,35 @@ struct Var : VarBase
|
||||
int Var::static1 = 0;
|
||||
Y Var::static2(0);
|
||||
|
||||
// Compilability regression tests
|
||||
namespace
|
||||
{
|
||||
struct trivial
|
||||
{
|
||||
trivial() : value(123) {}
|
||||
double value;
|
||||
};
|
||||
|
||||
struct Color3
|
||||
{
|
||||
static const Color3 black;
|
||||
};
|
||||
|
||||
const Color3 Color3::black;
|
||||
|
||||
void compilability_test()
|
||||
{
|
||||
class_<trivial>("trivial")
|
||||
.add_property("property", make_getter(&trivial::value, return_value_policy<return_by_value>()))
|
||||
.def_readonly("readonly", &trivial::value)
|
||||
;
|
||||
|
||||
class_< Color3 >("Color3", init< const Color3 & >())
|
||||
.def_readonly("BLACK", &Color3::black) // line 17
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(data_members_ext)
|
||||
{
|
||||
class_<X>("X", init<int>())
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
#include <boost/python/detail/destroy.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct bar;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// lie to the library about bar so we can show that its destructor is optimized away.
|
||||
template <>
|
||||
struct has_trivial_destructor<bar>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
int count;
|
||||
int marks[] = {
|
||||
-1
|
||||
@@ -33,8 +20,6 @@ struct foo
|
||||
int n;
|
||||
};
|
||||
|
||||
struct bar : foo {};
|
||||
|
||||
void assert_destructions(int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
@@ -62,20 +47,5 @@ int main()
|
||||
boost::python::detail::destroy_referent<y&>(f3);
|
||||
assert_destructions(7);
|
||||
|
||||
bar* b1 = new bar;
|
||||
boost::python::detail::destroy_referent<bar&>(b1);
|
||||
assert_destructions(7);
|
||||
|
||||
bar* b2 = new bar[2];
|
||||
typedef bar xb[2];
|
||||
|
||||
boost::python::detail::destroy_referent<xb&>(b2);
|
||||
assert_destructions(7);
|
||||
|
||||
typedef bar yb[2][2];
|
||||
xb* b3 = new yb;
|
||||
boost::python::detail::destroy_referent<yb&>(b3);
|
||||
assert_destructions(7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,9 +40,16 @@ BOOST_PYTHON_MODULE(enum_ext)
|
||||
|
||||
def("identity", identity_);
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
color colorized::*px = &colorized::x;
|
||||
class_<colorized>("colorized")
|
||||
.def_readwrite("x", px)
|
||||
;
|
||||
#else
|
||||
class_<colorized>("colorized")
|
||||
.def_readwrite("x", &colorized::x)
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/long.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <cassert>
|
||||
|
||||
using namespace boost::python;
|
||||
@@ -39,6 +40,14 @@ int is_long2(char const*)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// tests for accepting objects (and derived classes) in constructors
|
||||
// from "Milind Patil" <milind_patil-at-hotmail.com>
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y(boost::python::long_) {}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(long_ext)
|
||||
{
|
||||
def("new_long", new_long);
|
||||
@@ -46,6 +55,8 @@ BOOST_PYTHON_MODULE(long_ext)
|
||||
def("longify_string", longify_string);
|
||||
def("is_long", is_long1);
|
||||
def("is_long", is_long2);
|
||||
|
||||
class_< Y >("Y", init< boost::python::long_ >())
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
'yes'
|
||||
>>> is_long('20')
|
||||
0
|
||||
|
||||
>>> x = Y(4294967295)
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
@@ -39,6 +40,8 @@ struct abstract : X
|
||||
abstract(int x) : X(x) {};
|
||||
int call_f(Y const& y) { return f(y); }
|
||||
virtual int f(Y const& y) = 0;
|
||||
abstract& call_g(Y const& y) { return g(y); }
|
||||
virtual abstract& g(Y const& y) = 0;
|
||||
};
|
||||
|
||||
struct concrete : X
|
||||
@@ -59,6 +62,11 @@ struct abstract_callback : abstract
|
||||
return call_method<int>(self, "f", boost::ref(y));
|
||||
}
|
||||
|
||||
abstract& g(Y const& y)
|
||||
{
|
||||
return call_method<abstract&>(self, "g", boost::ref(y));
|
||||
}
|
||||
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
@@ -101,6 +109,7 @@ BOOST_PYTHON_MODULE(virtual_functions_ext)
|
||||
|
||||
.def("value", &abstract::value)
|
||||
.def("call_f", &abstract::call_f)
|
||||
.def("call_g", &abstract::call_g, return_internal_reference<>())
|
||||
.def("set", &abstract::set)
|
||||
;
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
>>> class A1(abstract):
|
||||
... def f(self, y):
|
||||
... return y.value() * 2
|
||||
... def g(self, y):
|
||||
... return self
|
||||
|
||||
>>> class A2(abstract):
|
||||
... pass
|
||||
@@ -22,15 +24,16 @@
|
||||
|
||||
|
||||
#
|
||||
# Test abstract with f overridden
|
||||
# Test abstract with f,g overridden
|
||||
#
|
||||
>>> a1 = A1(42)
|
||||
>>> a1.value()
|
||||
42
|
||||
|
||||
# Call f indirectly from C++
|
||||
# Call f,g indirectly from C++
|
||||
>>> a1.call_f(y1)
|
||||
32
|
||||
>>> assert type(a1.call_g(y1)) is abstract
|
||||
|
||||
# Call f directly from Python
|
||||
>>> a1.f(y2)
|
||||
|
||||
Reference in New Issue
Block a user