mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
Make slice work on vc6
Revamp/simplify class registration [SVN r23823]
This commit is contained in:
@@ -8,10 +8,11 @@
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
|
||||
# include <boost/noncopyable.hpp>
|
||||
|
||||
# include <boost/python/class_fwd.hpp>
|
||||
# include <boost/python/object/class.hpp>
|
||||
|
||||
# include <boost/python/bases.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/data_members.hpp>
|
||||
@@ -20,12 +21,9 @@
|
||||
# include <boost/python/init.hpp>
|
||||
# include <boost/python/args_fwd.hpp>
|
||||
|
||||
# include <boost/python/object/select_holder.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/object/make_instance.hpp>
|
||||
# include <boost/python/object/class_metadata.hpp>
|
||||
# include <boost/python/object/pickle_support.hpp>
|
||||
# include <boost/python/object/add_to_namespace.hpp>
|
||||
# include <boost/python/object/class_converters.hpp>
|
||||
|
||||
# include <boost/python/detail/overloads_fwd.hpp>
|
||||
# include <boost/python/detail/operator_id.hpp>
|
||||
@@ -33,7 +31,6 @@
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
|
||||
@@ -41,10 +38,7 @@
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
|
||||
@@ -87,52 +81,6 @@ namespace detail
|
||||
type_info** p;
|
||||
};
|
||||
|
||||
template <class T, class Prev = detail::not_specified>
|
||||
struct select_held_type;
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable;
|
||||
|
||||
// Register to_python converters for a class T. The first argument
|
||||
// will be mpl::true_ unless noncopyable was specified as a
|
||||
// class_<...> template parameter. The 2nd argument is a pointer to
|
||||
// the type of holder that must be created. The 3rd argument is a
|
||||
// reference to the Python type object to be created.
|
||||
template <class T, class SelectHolder>
|
||||
inline void register_class_to_python(mpl::true_, SelectHolder, T* = 0)
|
||||
{
|
||||
typedef typename SelectHolder::type holder;
|
||||
force_instantiate(objects::class_cref_wrapper<T, objects::make_instance<T,holder> >());
|
||||
SelectHolder::register_();
|
||||
}
|
||||
|
||||
template <class T, class SelectHolder>
|
||||
inline void register_class_to_python(mpl::false_, SelectHolder, T* = 0)
|
||||
{
|
||||
SelectHolder::register_();
|
||||
}
|
||||
|
||||
//
|
||||
// register_wrapper_class -- register the relationship between a
|
||||
// virtual function callback wrapper class and the class being
|
||||
// wrapped.
|
||||
//
|
||||
template <class T>
|
||||
inline void register_wrapper_class_impl(T*, T*, int) {}
|
||||
|
||||
template <class Wrapper, class T>
|
||||
inline void register_wrapper_class_impl(Wrapper*, T*, ...)
|
||||
{
|
||||
objects::register_class_from_python<Wrapper, mpl::vector1<T> >();
|
||||
objects::copy_class_object(type_id<T>(), type_id<Wrapper>());
|
||||
}
|
||||
|
||||
template <class Held, class T>
|
||||
inline void register_wrapper_class(Held* = 0, T* = 0)
|
||||
{
|
||||
register_wrapper_class_impl((Held*)0, (T*)0, 0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct is_data_member_pointer
|
||||
: mpl::and_<
|
||||
@@ -212,34 +160,18 @@ class class_ : public objects::class_base
|
||||
{
|
||||
public: // types
|
||||
typedef objects::class_base base;
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
typedef typename objects::class_metadata<T,X1,X2,X3> metadata;
|
||||
typedef T wrapped_type;
|
||||
|
||||
typedef class_<T,X1,X2,X3> self;
|
||||
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
|
||||
|
||||
// held_type - either T, a class derived from T or a smart pointer
|
||||
// to a (class derived from) T.
|
||||
typedef typename detail::select_held_type<
|
||||
X1, typename detail::select_held_type<
|
||||
X2, typename detail::select_held_type<
|
||||
X3
|
||||
>::type>::type>::type held_type;
|
||||
|
||||
typedef objects::select_holder<T,held_type> select_holder;
|
||||
|
||||
private: // types
|
||||
|
||||
typedef typename detail::select_bases<X1
|
||||
, typename detail::select_bases<X2
|
||||
, typename boost::python::detail::select_bases<X3>::type
|
||||
>::type
|
||||
>::type bases;
|
||||
|
||||
|
||||
// A helper class which will contain an array of id objects to be
|
||||
// passed to the base class constructor
|
||||
struct id_vector
|
||||
{
|
||||
typedef typename metadata::bases bases;
|
||||
|
||||
id_vector()
|
||||
{
|
||||
// Stick the derived class id into the first element of the array
|
||||
@@ -272,8 +204,7 @@ class class_ : public objects::class_base
|
||||
inline class_(char const* name, init_base<DerivedT> const& i)
|
||||
: base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
this->register_holder();
|
||||
this->def(i);
|
||||
this->initialize(i);
|
||||
}
|
||||
|
||||
// Construct with class name, docstring and init<> function
|
||||
@@ -281,8 +212,7 @@ class class_ : public objects::class_base
|
||||
inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_holder();
|
||||
this->def(i);
|
||||
this->initialize(i);
|
||||
}
|
||||
|
||||
public: // member functions
|
||||
@@ -510,8 +440,22 @@ class class_ : public objects::class_base
|
||||
return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
|
||||
}
|
||||
|
||||
inline void register_() const;
|
||||
inline void register_holder();
|
||||
template <class DefVisitor>
|
||||
inline void initialize(DefVisitor const& i)
|
||||
{
|
||||
metadata::register_(); // set up runtime metadata/conversions
|
||||
|
||||
typedef typename metadata::holder holder;
|
||||
this->set_instance_size( objects::additional_instance_size<holder>::value );
|
||||
|
||||
this->def(i);
|
||||
}
|
||||
|
||||
inline void initialize(no_init_t)
|
||||
{
|
||||
metadata::register_(); // set up runtime metadata/conversions
|
||||
this->def_no_init();
|
||||
}
|
||||
|
||||
//
|
||||
// These two overloads discriminate between def() as applied to a
|
||||
@@ -625,80 +569,26 @@ class class_ : public objects::class_base
|
||||
// implementations
|
||||
//
|
||||
|
||||
// register converters
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline void class_<T,X1,X2,X3>::register_() const
|
||||
{
|
||||
objects::register_class_from_python<T,bases>();
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME select_holder::held_type held_t;
|
||||
detail::register_wrapper_class<held_t,T>();
|
||||
|
||||
detail::register_class_to_python<T>(
|
||||
mpl::bool_<is_copyable>()
|
||||
, select_holder()
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline void class_<T,X1,X2,X3>::register_holder()
|
||||
{
|
||||
this->register_();
|
||||
typedef typename select_holder::type holder;
|
||||
this->set_instance_size(
|
||||
objects::additional_instance_size<holder>::value
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_holder();
|
||||
select_holder::assert_default_constructible();
|
||||
this->def(init<>());
|
||||
this->initialize(init<>());
|
||||
// select_holder::assert_default_constructible();
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, no_init_t)
|
||||
: base(name, id_vector::size, id_vector().ids)
|
||||
{
|
||||
this->register_();
|
||||
this->def_no_init();
|
||||
this->initialize(no_init);
|
||||
}
|
||||
|
||||
template <class T, class X1, class X2, class X3>
|
||||
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
|
||||
: base(name, id_vector::size, id_vector().ids, doc)
|
||||
{
|
||||
this->register_();
|
||||
this->def_no_init();
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T1, class T2, class T3>
|
||||
struct has_noncopyable
|
||||
: mpl::or_<
|
||||
is_same<T1,noncopyable>
|
||||
, is_same<T2,noncopyable>
|
||||
, is_same<T3,noncopyable>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template <class T, class Prev>
|
||||
struct select_held_type
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
specifies_bases<T>
|
||||
, is_same<T,noncopyable>
|
||||
>
|
||||
, Prev
|
||||
, T
|
||||
>
|
||||
{
|
||||
};
|
||||
this->initialize(no_init);
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
# include <boost/python/converter/from_python.hpp>
|
||||
# include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
# include <boost/python/converter/registered.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
|
||||
@@ -328,17 +328,15 @@ namespace detail
|
||||
, detail::keyword_range const& keywords_
|
||||
)
|
||||
{
|
||||
typedef typename ClassT::select_holder selector_t;
|
||||
|
||||
cl.def(
|
||||
"__init__",
|
||||
detail::make_keyword_range_constructor<Signature,NArgs>(
|
||||
policies
|
||||
, keywords_
|
||||
, selector_t::get()
|
||||
)
|
||||
, doc
|
||||
);
|
||||
"__init__"
|
||||
, detail::make_keyword_range_constructor<Signature,NArgs>(
|
||||
policies
|
||||
, keywords_
|
||||
, (typename ClassT::metadata::holder*)0
|
||||
)
|
||||
, doc
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -58,8 +58,6 @@ struct BOOST_PYTHON_DECL class_base : python::api::object
|
||||
void make_method_static(const char *method_name);
|
||||
};
|
||||
|
||||
BOOST_PYTHON_DECL void copy_class_object(type_info const& src, type_info const& dst);
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_DWA20011214_HPP
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright David Abrahams 2002. 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 CLASS_CONVERTERS_DWA2002119_HPP
|
||||
# define CLASS_CONVERTERS_DWA2002119_HPP
|
||||
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/converter/shared_ptr_from_python.hpp>
|
||||
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
|
||||
# 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>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// register_base_of<T> -
|
||||
// A BinaryMetaFunction object which registers a single base
|
||||
// class of T, and the corresponding cast(s)
|
||||
//
|
||||
|
||||
|
||||
// register_downcast/do_nothing -
|
||||
// Helpers for register_base_of<> which take care of registering
|
||||
// down-casts
|
||||
template <class Base, class Derived>
|
||||
struct register_downcast
|
||||
{
|
||||
static void execute()
|
||||
{
|
||||
register_conversion<Base, Derived>(true);
|
||||
}
|
||||
};
|
||||
|
||||
struct do_nothing
|
||||
{
|
||||
static void execute() { }
|
||||
};
|
||||
|
||||
// Here's where the real work gets done:
|
||||
template <class Derived>
|
||||
struct register_base_of
|
||||
{
|
||||
// Here's the runtime part:
|
||||
template <class Base>
|
||||
void operator()(Base*) const
|
||||
{
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
// Register the up-cast
|
||||
register_conversion<Derived,Base>(false);
|
||||
|
||||
// Register the down-cast, if appropriate.
|
||||
mpl::if_<
|
||||
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
mpl::true_
|
||||
# else
|
||||
is_polymorphic<Base>
|
||||
# endif
|
||||
, register_downcast<Base,Derived>
|
||||
, do_nothing
|
||||
>::type::execute();
|
||||
}
|
||||
};
|
||||
|
||||
// Brings into existence all converters associated with a class. Bases
|
||||
// is expected to be an mpl sequence of base types.
|
||||
template <class Derived, class Bases>
|
||||
inline void register_class_from_python(Derived* = 0, Bases* = 0)
|
||||
{
|
||||
// Static object constructor performs registration
|
||||
static converter::shared_ptr_from_python<Derived> shared_ptr_registration;
|
||||
|
||||
// register all up/downcasts here
|
||||
register_dynamic_id<Derived>();
|
||||
|
||||
// register each base in the sequence
|
||||
mpl::for_each(register_base_of<Derived>(), (Bases*)0, (add_pointer<mpl::_>*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // CLASS_CONVERTERS_DWA2002119_HPP
|
||||
249
include/boost/python/object/class_metadata.hpp
Executable file
249
include/boost/python/object/class_metadata.hpp
Executable file
@@ -0,0 +1,249 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef CLASS_METADATA_DWA2004719_HPP
|
||||
# define CLASS_METADATA_DWA2004719_HPP
|
||||
# include <boost/python/converter/shared_ptr_from_python.hpp>
|
||||
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/object/make_instance.hpp>
|
||||
# include <boost/python/object/value_holder.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
# include <boost/python/object/make_ptr_instance.hpp>
|
||||
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
|
||||
# include <boost/python/has_back_reference.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_polymorphic.hpp>
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
# include <boost/mpl/single_view.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/noncopyable.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
BOOST_PYTHON_DECL
|
||||
void copy_class_object(type_info const& src, type_info const& dst);
|
||||
|
||||
//
|
||||
// Support for registering base/derived relationships
|
||||
//
|
||||
template <class Derived>
|
||||
struct register_base_of
|
||||
{
|
||||
template <class Base>
|
||||
inline void operator()(Base*) const
|
||||
{
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
|
||||
// Register the up-cast
|
||||
register_conversion<Derived,Base>(false);
|
||||
|
||||
// Register the down-cast, if appropriate.
|
||||
this->register_downcast((Base*)0, is_polymorphic<Base>());
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void register_downcast(void*, mpl::false_) {}
|
||||
|
||||
template <class Base>
|
||||
static inline void register_downcast(Base*, mpl::true_)
|
||||
{
|
||||
register_conversion<Base, Derived>(true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Preamble of register_class. Also used for callback classes, which
|
||||
// need some registration of their own.
|
||||
//
|
||||
template <class T, class Bases>
|
||||
void register_shared_ptr_from_python_and_casts(T*, Bases)
|
||||
{
|
||||
// Constructor performs registration
|
||||
python::detail::force_instantiate(converter::shared_ptr_from_python<T>());
|
||||
|
||||
//
|
||||
// register all up/downcasts here. We're using the alternate
|
||||
// interface to mpl::for_each to avoid an MSVC 6 bug.
|
||||
//
|
||||
register_dynamic_id<T>();
|
||||
mpl::for_each(register_base_of<T>(), (Bases*)0, (add_pointer<mpl::_>*)0);
|
||||
}
|
||||
|
||||
//
|
||||
// Helper for choosing the unnamed held_type argument
|
||||
//
|
||||
template <class T, class Prev>
|
||||
struct select_held_type
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
python::detail::specifies_bases<T>
|
||||
, is_same<T,noncopyable>
|
||||
>
|
||||
, Prev
|
||||
, T
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <
|
||||
class T // class being wrapped
|
||||
, class X1 // = detail::not_specified
|
||||
, class X2 // = detail::not_specified
|
||||
, class X3 // = detail::not_specified
|
||||
>
|
||||
struct class_metadata
|
||||
{
|
||||
//
|
||||
// Calculate the unnamed template arguments
|
||||
//
|
||||
|
||||
// held_type_arg -- not_specified, [a class derived from] T or a
|
||||
// smart pointer to [a class derived from] T. Preserving
|
||||
// not_specified allows us to give class_<T,T> a back-reference.
|
||||
typedef typename select_held_type<
|
||||
X1
|
||||
, typename select_held_type<
|
||||
X2
|
||||
, typename select_held_type<
|
||||
X3
|
||||
, python::detail::not_specified
|
||||
>::type
|
||||
>::type
|
||||
>::type held_type_arg;
|
||||
|
||||
// bases
|
||||
typedef typename python::detail::select_bases<
|
||||
X1
|
||||
, typename python::detail::select_bases<
|
||||
X2
|
||||
, typename python::detail::select_bases<
|
||||
X3
|
||||
, python::bases<>
|
||||
>::type
|
||||
>::type
|
||||
>::type bases;
|
||||
|
||||
typedef mpl::or_<
|
||||
is_same<X1,noncopyable>
|
||||
, is_same<X2,noncopyable>
|
||||
, is_same<X3,noncopyable>
|
||||
> is_noncopyable;
|
||||
|
||||
//
|
||||
// Holder computation.
|
||||
//
|
||||
|
||||
// Compute the actual type that will be held in the Holder.
|
||||
typedef typename mpl::if_<
|
||||
is_same<held_type_arg,python::detail::not_specified>, T, held_type_arg
|
||||
>::type held_type;
|
||||
|
||||
// Determine if the object will be held by value
|
||||
typedef is_convertible<held_type*,T*> use_value_holder;
|
||||
|
||||
// Compute the "wrapped type", that is, if held_type is a smart
|
||||
// pointer, we're talking about the pointee.
|
||||
typedef typename mpl::apply_if<
|
||||
use_value_holder
|
||||
, mpl::identity<held_type>
|
||||
, pointee<held_type>
|
||||
>::type wrapper;
|
||||
|
||||
// Determine whether wrapper needs to be separately registered
|
||||
typedef is_base_and_derived<T,wrapper> use_callback_class;
|
||||
|
||||
// Determine whether to use a holder with a back-reference
|
||||
typedef mpl::or_<
|
||||
use_callback_class
|
||||
, has_back_reference<T>
|
||||
, is_same<held_type_arg,T>
|
||||
> use_back_reference;
|
||||
|
||||
// Select the holder.
|
||||
typedef typename mpl::apply_if<
|
||||
use_back_reference
|
||||
, mpl::if_<
|
||||
use_value_holder
|
||||
, value_holder_back_reference<T, wrapper>
|
||||
, pointer_holder_back_reference<held_type,T>
|
||||
>
|
||||
, mpl::if_<
|
||||
use_value_holder
|
||||
, value_holder<T>
|
||||
, pointer_holder<held_type,T>
|
||||
>
|
||||
>::type holder;
|
||||
|
||||
inline static void register_() // Register the runtime metadata.
|
||||
{
|
||||
objects::register_shared_ptr_from_python_and_casts((T*)0, bases());
|
||||
|
||||
class_metadata::maybe_register_callback_class(use_callback_class());
|
||||
|
||||
class_metadata::maybe_register_class_to_python(is_noncopyable());
|
||||
|
||||
class_metadata::maybe_register_pointer_to_python(
|
||||
(use_value_holder*)0, (use_back_reference*)0);
|
||||
}
|
||||
|
||||
private:
|
||||
//
|
||||
// Support for converting smart pointers to python
|
||||
//
|
||||
inline static void maybe_register_pointer_to_python(void*,void*) {}
|
||||
|
||||
inline static void maybe_register_pointer_to_python(mpl::false_*, mpl::false_*)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
objects::class_value_wrapper<
|
||||
held_type
|
||||
, make_ptr_instance<T, pointer_holder<held_type, T> >
|
||||
>()
|
||||
);
|
||||
}
|
||||
//
|
||||
// Support for registering to-python converters
|
||||
//
|
||||
inline static void maybe_register_class_to_python(mpl::true_) {}
|
||||
inline static void maybe_register_class_to_python(mpl::false_)
|
||||
{
|
||||
python::detail::force_instantiate(class_cref_wrapper<T, make_instance<T, holder> >());
|
||||
}
|
||||
|
||||
//
|
||||
// Support for registering callback classes
|
||||
//
|
||||
inline static void maybe_register_callback_class(mpl::false_) {}
|
||||
|
||||
inline static void maybe_register_callback_class(mpl::true_)
|
||||
{
|
||||
objects::register_shared_ptr_from_python_and_casts(
|
||||
(wrapper*)0, mpl::single_view<T>());
|
||||
|
||||
// explicit qualification of type_id makes msvc6 happy
|
||||
objects::copy_class_object(python::type_id<T>(), python::type_id<wrapper>());
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // CLASS_METADATA_DWA2004719_HPP
|
||||
@@ -1,195 +0,0 @@
|
||||
// Copyright David Abrahams 2002. 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 SELECT_HOLDER_DWA2002322_HPP
|
||||
# define SELECT_HOLDER_DWA2002322_HPP
|
||||
|
||||
# include <boost/python/has_back_reference.hpp>
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
# include <boost/python/pointee.hpp>
|
||||
# include <boost/python/object/value_holder.hpp>
|
||||
# include <boost/python/object/pointer_holder.hpp>
|
||||
# include <boost/python/object/class_wrapper.hpp>
|
||||
# include <boost/python/object/make_ptr_instance.hpp>
|
||||
# include <boost/python/object/instance.hpp>
|
||||
# include <boost/python/detail/force_instantiate.hpp>
|
||||
|
||||
# include <boost/type.hpp>
|
||||
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/not.hpp>
|
||||
|
||||
# include <boost/type_traits/same_traits.hpp>
|
||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||
# include <boost/type_traits/alignment_traits.hpp>
|
||||
|
||||
# include <cstddef>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// check_default_constructible --
|
||||
//
|
||||
// Used to give a clean error message when the user doesn't specify
|
||||
// any __init__ functions, but when the class being wrapped doesn't
|
||||
// have an appropriate default constructor (or if
|
||||
// has_back_reference<T> is true, a constructor taking PyObject*).
|
||||
|
||||
// A helpful compile-time assertion which gives a reasonable error
|
||||
// message if T can't be default-constructed.
|
||||
template <class T>
|
||||
static int specify_init_arguments_or_no_init_for_class_(T const&);
|
||||
|
||||
// U is expected to take an initial hidden PyObject* in its
|
||||
// constructor. Normally this means U is a virtual function
|
||||
// dispatcher subclass for T.
|
||||
template <class T, class U>
|
||||
void check_default_constructible(T*, U*, mpl::true_)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
sizeof(specify_init_arguments_or_no_init_for_class_<T>(U((::PyObject*)0)))
|
||||
);
|
||||
}
|
||||
|
||||
// Handles the "normal" case where T is held directly and
|
||||
// has_back_reference<T> is not specialized.
|
||||
template <class T>
|
||||
void check_default_constructible(T*, T*, mpl::false_)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
sizeof(specify_init_arguments_or_no_init_for_class_<T>(T()))
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// select_value_holder/select_pointer_holder --
|
||||
//
|
||||
// An instantiation of one of these data-free class templates is
|
||||
// returned by select_holder::execute(), below. Each provides the
|
||||
// following public interface:
|
||||
//
|
||||
// static void assert_default_constructible() -- called when no
|
||||
// init<...> arguments are specified in class_<T, ...>'s
|
||||
// constructor; causes a compile-time error when T has no
|
||||
// corresponding default constructor.
|
||||
//
|
||||
// typedef ... type -- the class derived from instance_holder
|
||||
// which will manage a Held object in Python class instances
|
||||
//
|
||||
// static type* get() { return 0; } -- just a way to access the
|
||||
// computed type at runtime.
|
||||
//
|
||||
// static void register_() -- forces registration of any
|
||||
// to_python converters corresponding to Held.
|
||||
|
||||
template <class T, class Held>
|
||||
struct select_value_holder
|
||||
{
|
||||
private:
|
||||
typedef mpl::or_<
|
||||
mpl::not_<is_same<T,Held> >
|
||||
, has_back_reference<T>
|
||||
> use_back_ref;
|
||||
|
||||
public:
|
||||
static void assert_default_constructible()
|
||||
{
|
||||
detail::check_default_constructible((T*)0,(Held*)0, use_back_ref());
|
||||
}
|
||||
|
||||
typedef typename mpl::if_<
|
||||
use_back_ref
|
||||
, value_holder_back_reference<T,Held>
|
||||
, value_holder<T>
|
||||
>::type type;
|
||||
|
||||
typedef Held held_type;
|
||||
|
||||
static inline void register_() {}
|
||||
|
||||
static type* get() { return 0; }
|
||||
};
|
||||
|
||||
template <class T,class Ptr>
|
||||
struct select_pointer_holder
|
||||
{
|
||||
private:
|
||||
typedef typename python::pointee<Ptr>::type wrapper;
|
||||
typedef mpl::or_<
|
||||
mpl::not_<is_same<T,wrapper> >
|
||||
, has_back_reference<T>
|
||||
> use_back_ref;
|
||||
|
||||
public:
|
||||
static void assert_default_constructible()
|
||||
{
|
||||
detail::check_default_constructible((T*)0,(wrapper*)0, use_back_ref());
|
||||
}
|
||||
|
||||
typedef typename mpl::if_<
|
||||
use_back_ref
|
||||
, pointer_holder_back_reference<Ptr,T>
|
||||
, pointer_holder<Ptr,T>
|
||||
>::type type;
|
||||
|
||||
typedef typename pointee<Ptr>::type held_type;
|
||||
|
||||
static inline void register_()
|
||||
{
|
||||
select_pointer_holder::register_(use_back_ref());
|
||||
}
|
||||
|
||||
static type* get() { return 0; }
|
||||
|
||||
private:
|
||||
static inline void register_(mpl::true_)
|
||||
{
|
||||
}
|
||||
|
||||
struct construct_from_pointer
|
||||
{
|
||||
static type* execute(PyObject*, Ptr x)
|
||||
{
|
||||
return new type(x);
|
||||
}
|
||||
};
|
||||
|
||||
static inline void register_(mpl::false_)
|
||||
{
|
||||
python::detail::force_instantiate(
|
||||
objects::class_value_wrapper<Ptr, make_ptr_instance<T,type> >());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// select_holder<T,Held>::execute((Held*)0)
|
||||
//
|
||||
// Returns an instantiation of
|
||||
// detail::select_value_holder or detail::select_pointer_holder, as
|
||||
// appropriate for class_<T,Held>
|
||||
template <class T, class Held>
|
||||
struct select_holder
|
||||
: mpl::if_<
|
||||
is_same<Held, python::detail::not_specified>
|
||||
, detail::select_value_holder<T,T>
|
||||
, typename mpl::if_<
|
||||
mpl::or_<
|
||||
is_same<T,Held>
|
||||
, is_base_and_derived<T, Held>
|
||||
>
|
||||
, detail::select_value_holder<T,Held>
|
||||
, detail::select_pointer_holder<T, Held>
|
||||
>::type
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // SELECT_HOLDER_DWA2002322_HPP
|
||||
@@ -39,6 +39,8 @@
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# endif
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace converter
|
||||
@@ -297,7 +299,14 @@ namespace api
|
||||
|
||||
// explicit conversion from any C++ object to Python
|
||||
template <class T>
|
||||
explicit object(T const& x)
|
||||
explicit object(
|
||||
T const& x
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
// use some SFINAE to un-confuse MSVC about its
|
||||
// copy-initialization ambiguity claim.
|
||||
, typename mpl::if_<is_proxy<T>,int&,int>::type* = 0
|
||||
# endif
|
||||
)
|
||||
: object_base(object_base_initializer(x))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace detail
|
||||
, options.policies()
|
||||
);
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME C_::select_holder::held_type held_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME C_::metadata::held_type held_type;
|
||||
|
||||
// Add the default implementation which raises the exception
|
||||
c.def(
|
||||
@@ -99,7 +99,7 @@ namespace detail
|
||||
, make_function(
|
||||
detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
|
||||
, default_call_policies()
|
||||
, detail::error_signature<held_t>(detail::get_signature(m_pmf))
|
||||
, detail::error_signature<held_type>(detail::get_signature(m_pmf))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,45 +12,55 @@
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/converter/pytype_object_mgr_traits.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class BOOST_PYTHON_DECL slice : public object
|
||||
namespace detail
|
||||
{
|
||||
private:
|
||||
// Helper function to work around bugs in MSVC 6
|
||||
static object new_slice(PyObject*, PyObject*, PyObject*);
|
||||
class BOOST_PYTHON_DECL slice_base : public object
|
||||
{
|
||||
public:
|
||||
// Get the Python objects associated with the slice. In principle, these
|
||||
// may be any arbitrary Python type, but in practice they are usually
|
||||
// integers. If one or more parameter is ommited in the Python expression
|
||||
// that created this slice, than that parameter is None here, and compares
|
||||
// equal to a default-constructed boost::python::object.
|
||||
// If a user-defined type wishes to support slicing, then support for the
|
||||
// special meaning associated with negative indicies is up to the user.
|
||||
object start() const;
|
||||
object stop() const;
|
||||
object step() const;
|
||||
|
||||
protected:
|
||||
explicit slice_base(PyObject*, PyObject*, PyObject*);
|
||||
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(slice_base, object)
|
||||
};
|
||||
}
|
||||
|
||||
class slice : public detail::slice_base
|
||||
{
|
||||
typedef detail::slice_base base;
|
||||
public:
|
||||
// Equivalent to slice(::)
|
||||
slice();
|
||||
slice() : base(0,0,0) {}
|
||||
|
||||
// Each argument must be slice_nil, or implicitly convertable to object.
|
||||
// They should normally be integers.
|
||||
template<typename Integer1, typename Integer2>
|
||||
slice( Integer1 start, Integer2 stop)
|
||||
: object( new_slice( object(start).ptr(), object(stop).ptr(), NULL))
|
||||
: base( object(start).ptr(), object(stop).ptr(), 0 )
|
||||
{}
|
||||
|
||||
template<typename Integer1, typename Integer2, typename Integer3>
|
||||
slice( Integer1 start, Integer2 stop, Integer3 stride)
|
||||
: object(
|
||||
new_slice( object(start).ptr(), object(stop).ptr(), object(stride).ptr()))
|
||||
: base( object(start).ptr(), object(stop).ptr(), object(stride).ptr() )
|
||||
{}
|
||||
|
||||
// Get the Python objects associated with the slice. In principle, these
|
||||
// may be any arbitrary Python type, but in practice they are usually
|
||||
// integers. If one or more parameter is ommited in the Python expression
|
||||
// that created this slice, than that parameter is None here, and compares
|
||||
// equal to a default-constructed boost::python::object.
|
||||
// If a user-defined type wishes to support slicing, then support for the
|
||||
// special meaning associated with negative indicies is up to the user.
|
||||
object start() const;
|
||||
object stop() const;
|
||||
object step() const;
|
||||
|
||||
// The following algorithm is intended to automate the process of
|
||||
// determining a slice range when you want to fully support negative
|
||||
// indicies and non-singular step sizes. Its functionallity is simmilar to
|
||||
@@ -90,14 +100,12 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
// the case where the user fails to catch the exception, it will simply
|
||||
// be translated to Python by the default exception handling mechanisms.
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATES
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
struct range
|
||||
{
|
||||
RandomAccessIterator start;
|
||||
RandomAccessIterator stop;
|
||||
int step;
|
||||
typename iterator_difference<RandomAccessIterator>::type step;
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
@@ -109,9 +117,10 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
// carefully crafted to ensure that these iterators never fall out of
|
||||
// the range of the container.
|
||||
slice::range<RandomAccessIterator> ret;
|
||||
typename RandomAccessIterator::difference_type max_dist =
|
||||
std::distance( begin, end);
|
||||
|
||||
|
||||
typedef typename iterator_difference<RandomAccessIterator>::type difference_type;
|
||||
difference_type max_dist = boost::detail::distance(begin, end);
|
||||
|
||||
object slice_start = this->start();
|
||||
object slice_stop = this->stop();
|
||||
object slice_step = this->step();
|
||||
@@ -121,7 +130,7 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
ret.step = 1;
|
||||
}
|
||||
else {
|
||||
ret.step = extract<int>( slice_step);
|
||||
ret.step = extract<long>( slice_step);
|
||||
if (ret.step == 0) {
|
||||
PyErr_SetString( PyExc_IndexError, "step size cannot be zero.");
|
||||
throw_error_already_set();
|
||||
@@ -138,7 +147,7 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
ret.start = begin;
|
||||
}
|
||||
else {
|
||||
int i = extract<int>( slice_start);
|
||||
difference_type i = extract<long>( slice_start);
|
||||
if (i >= max_dist && ret.step > 0)
|
||||
throw std::invalid_argument( "Zero-length slice");
|
||||
if (i >= 0) {
|
||||
@@ -167,7 +176,7 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
}
|
||||
}
|
||||
else {
|
||||
int i = extract<int>( slice_stop);
|
||||
difference_type i = extract<long>(slice_stop);
|
||||
// First, branch on which direction we are going with this.
|
||||
if (ret.step < 0) {
|
||||
if (i+1 >= max_dist || i == -1)
|
||||
@@ -188,8 +197,7 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
|
||||
if (i > 0) {
|
||||
ret.stop = begin;
|
||||
BOOST_USING_STD_MIN();
|
||||
std::advance( ret.stop, min BOOST_PREVENT_MACRO_SUBSTITUTION( i-1, max_dist-1));
|
||||
std::advance( ret.stop, (std::min)( i-1, max_dist-1));
|
||||
}
|
||||
else { // i is negative, but not more negative than -max_dist
|
||||
ret.stop = end;
|
||||
@@ -203,8 +211,8 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
// represent the widest possible range that could be traveled
|
||||
// (inclusive), and final_dist is the maximum distance covered by the
|
||||
// slice.
|
||||
typename RandomAccessIterator::difference_type final_dist =
|
||||
std::distance( ret.start, ret.stop);
|
||||
typename iterator_difference<RandomAccessIterator>::type final_dist =
|
||||
boost::detail::distance( ret.start, ret.stop);
|
||||
|
||||
// First case, if both ret.start and ret.stop are equal, then step
|
||||
// is irrelevant and we can return here.
|
||||
@@ -222,24 +230,23 @@ class BOOST_PYTHON_DECL slice : public object
|
||||
// I don't remember all of the oolies surrounding negative modulii,
|
||||
// so I am handling each of these cases separately.
|
||||
if (final_dist < 0) {
|
||||
int remainder = -final_dist % -ret.step;
|
||||
difference_type remainder = -final_dist % -ret.step;
|
||||
std::advance( ret.stop, remainder);
|
||||
}
|
||||
else {
|
||||
int remainder = final_dist % ret.step;
|
||||
difference_type remainder = final_dist % ret.step;
|
||||
std::advance( ret.stop, -remainder);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif // !defined BOOST_NO_MEMBER_TEMPLATES
|
||||
|
||||
public:
|
||||
// This declaration, in conjunction with the specialization of
|
||||
// object_manager_traits<> below, allows C++ functions accepting slice
|
||||
// arguments to be called from from Python. These constructors should never
|
||||
// be used in client code.
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(slice, object)
|
||||
BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(slice, detail::slice_base)
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -6,39 +6,32 @@
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
namespace boost { namespace python {
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
object
|
||||
slice::new_slice(PyObject* start, PyObject* stop, PyObject* step)
|
||||
{
|
||||
return object(detail::new_reference( PySlice_New(start, stop, step)));
|
||||
}
|
||||
|
||||
slice::slice()
|
||||
: object( boost::python::detail::new_reference(
|
||||
PySlice_New( NULL, NULL, NULL)))
|
||||
slice_base::slice_base(PyObject* start, PyObject* stop, PyObject* step)
|
||||
: object(detail::new_reference( PySlice_New(start, stop, step)))
|
||||
{
|
||||
}
|
||||
|
||||
object
|
||||
slice::start() const
|
||||
slice_base::start() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->start));
|
||||
}
|
||||
|
||||
object
|
||||
slice::stop() const
|
||||
slice_base::stop() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->stop));
|
||||
}
|
||||
|
||||
object
|
||||
slice::step() const
|
||||
slice_base::step() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->step));
|
||||
}
|
||||
|
||||
} } // !namespace boost::python
|
||||
} } } // !namespace boost::python::detail
|
||||
|
||||
@@ -158,7 +158,11 @@ bpl-test crossmod_exception
|
||||
[ bpl-test docstring ]
|
||||
|
||||
[ bpl-test vector_indexing_suite ]
|
||||
[ bpl-test map_indexing_suite ]
|
||||
|
||||
[ extension map_indexing_suite_ext
|
||||
: map_indexing_suite.cpp int_map_indexing_suite.cpp <template>../build/extension ]
|
||||
[ boost-python-runtest
|
||||
map_indexing_suite : map_indexing_suite.py <pyd>map_indexing_suite_ext ]
|
||||
|
||||
# if $(TEST_BIENSTMAN_NON_BUGS)
|
||||
# {
|
||||
|
||||
@@ -29,7 +29,7 @@ BOOST_PYTHON_MODULE(injected_ext)
|
||||
class_<X>("X", init<int>())
|
||||
.def("__init__", make_constructor(empty))
|
||||
.def("__init__", make_constructor(sum))
|
||||
.def("__init__", make_constructor(product))
|
||||
.def("__init__", make_constructor(product), "this is product's docstring")
|
||||
.def("value", &X::value)
|
||||
;
|
||||
}
|
||||
|
||||
16
test/int_map_indexing_suite.cpp
Executable file
16
test/int_map_indexing_suite.cpp
Executable file
@@ -0,0 +1,16 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
|
||||
|
||||
void int_map_indexing_suite()
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
// Compile check only...
|
||||
class_<std::map<int, int> >("IntMap")
|
||||
.def(map_indexing_suite<std::map<int, int> >())
|
||||
;
|
||||
}
|
||||
@@ -40,10 +40,15 @@ BOOST_PYTHON_MODULE(map_indexing_suite_ext)
|
||||
.def(map_indexing_suite<std::map<std::string, X> >())
|
||||
;
|
||||
|
||||
void int_map_indexing_suite(); // moved to int_map_indexing_suite.cpp to
|
||||
int_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
|
||||
|
||||
#if 0
|
||||
// Compile check only...
|
||||
class_<std::map<int, int> >("IntMap")
|
||||
.def(map_indexing_suite<std::map<int, int> >())
|
||||
;
|
||||
#endif
|
||||
|
||||
// Compile check only...
|
||||
class_<std::map<std::string, boost::shared_ptr<X> > >("TestMap")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include "test_class.hpp"
|
||||
//#include <boost/python/str.hpp>
|
||||
#if __GNUC__ != 2
|
||||
# include <ostream>
|
||||
#else
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// 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.
|
||||
#include <boost/python/object/select_holder.hpp>
|
||||
#include <boost/python/object/class_metadata.hpp>
|
||||
#include <boost/python/has_back_reference.hpp>
|
||||
#include <boost/python/detail/not_specified.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
@@ -41,7 +41,13 @@ void assert_same(U* = 0, T* = 0)
|
||||
template <class T, class Held, class Holder>
|
||||
void assert_holder(T* = 0, Held* = 0, Holder* = 0)
|
||||
{
|
||||
typedef typename boost::python::objects::select_holder<T,Held>::type h;
|
||||
using namespace boost::python::detail;
|
||||
using namespace boost::python::objects;
|
||||
|
||||
typedef typename class_metadata<
|
||||
T,Held,not_specified,not_specified
|
||||
>::holder h;
|
||||
|
||||
assert_same<Holder>(
|
||||
(h*)0
|
||||
);
|
||||
@@ -55,7 +61,7 @@ int test_main(int, char * [])
|
||||
assert_holder<Base,not_specified,value_holder<Base> >();
|
||||
|
||||
assert_holder<BR,not_specified,value_holder_back_reference<BR,BR> >();
|
||||
assert_holder<Base,Base,value_holder<Base> >();
|
||||
assert_holder<Base,Base,value_holder_back_reference<Base,Base> >();
|
||||
assert_holder<BR,BR,value_holder_back_reference<BR,BR> >();
|
||||
|
||||
assert_holder<Base,Derived
|
||||
|
||||
@@ -76,6 +76,7 @@ bool check_numeric_array_rich_slice()
|
||||
// Verify functions accepting a slice argument can be called
|
||||
bool accept_slice( slice) { return true; }
|
||||
|
||||
int check_slice_get_indicies(slice index);
|
||||
int check_slice_get_indicies(const slice index)
|
||||
{
|
||||
// A vector of integers from [-5, 5].
|
||||
@@ -88,7 +89,7 @@ int check_slice_get_indicies(const slice index)
|
||||
|
||||
slice::range<std::vector<int>::iterator> bounds;
|
||||
try {
|
||||
bounds = index.get_indicies<>(coll.begin(), coll.end());
|
||||
bounds = index.get_indicies(coll.begin(), coll.end());
|
||||
}
|
||||
catch (std::invalid_argument) {
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user