mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
This commit was manufactured by cvs2svn to create branch 'mpl_v2'.
[SVN r14323]
This commit is contained in:
52
include/boost/python/arg_from_python.hpp
Executable file
52
include/boost/python/arg_from_python.hpp
Executable file
@@ -0,0 +1,52 @@
|
||||
// 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 ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
# define ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
|
||||
# include <boost/python/converter/arg_from_python.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
struct arg_from_python
|
||||
: converter::select_arg_from_python<T>::type
|
||||
{
|
||||
typedef typename converter::select_arg_from_python<T>::type base;
|
||||
arg_from_python(PyObject*);
|
||||
};
|
||||
|
||||
// specialization for PyObject*
|
||||
template <>
|
||||
struct arg_from_python<PyObject*>
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
arg_from_python(PyObject*) {}
|
||||
bool convertible() const { return true; }
|
||||
PyObject* operator()(PyObject* source) const { return source; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_from_python<PyObject* const&>
|
||||
{
|
||||
typedef PyObject* const& result_type;
|
||||
arg_from_python(PyObject*) {}
|
||||
bool convertible() const { return true; }
|
||||
PyObject*const& operator()(PyObject*const& source) const { return source; }
|
||||
};
|
||||
|
||||
//
|
||||
// implementations
|
||||
//
|
||||
template <class T>
|
||||
inline arg_from_python<T>::arg_from_python(PyObject* source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // ARG_FROM_PYTHON_DWA2002128_HPP
|
||||
36
include/boost/python/base_type_traits.hpp
Executable file
36
include/boost/python/base_type_traits.hpp
Executable file
@@ -0,0 +1,36 @@
|
||||
// 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 BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
# define BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct unspecialized {};
|
||||
}
|
||||
|
||||
// Derive from unspecialized so we can detect whether traits are
|
||||
// specialized
|
||||
template <class T> struct base_type_traits
|
||||
: detail::unspecialized
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct base_type_traits<PyObject>
|
||||
{
|
||||
typedef PyObject type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct base_type_traits<PyTypeObject>
|
||||
{
|
||||
typedef PyObject type;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP
|
||||
30
include/boost/python/class_fwd.hpp
Normal file
30
include/boost/python/class_fwd.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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_FWD_DWA200222_HPP
|
||||
# define CLASS_FWD_DWA200222_HPP
|
||||
# include <boost/python/detail/not_specified.hpp>
|
||||
# include <boost/python/args.hpp>
|
||||
# include <boost/python/bases.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct empty_list;
|
||||
}
|
||||
|
||||
template <
|
||||
class T // class being wrapped
|
||||
// arbitrarily-ordered optional arguments. Full qualification needed for MSVC6
|
||||
, class X1 = ::boost::python::detail::not_specified
|
||||
, class X2 = ::boost::python::detail::not_specified
|
||||
, class X3 = ::boost::python::detail::not_specified
|
||||
>
|
||||
class class_;
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_FWD_DWA200222_HPP
|
||||
69
include/boost/python/converter/pointer_type_id.hpp
Normal file
69
include/boost/python/converter/pointer_type_id.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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 POINTER_TYPE_ID_DWA2002222_HPP
|
||||
# define POINTER_TYPE_ID_DWA2002222_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool is_ref = false>
|
||||
struct pointer_typeid_select
|
||||
{
|
||||
template <class T>
|
||||
static inline type_info execute(T*(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pointer_typeid_select<true>
|
||||
{
|
||||
template <class T>
|
||||
static inline type_info execute(T* const volatile&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*volatile&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*const&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline type_info execute(T*&(*)() = 0)
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Usage: pointer_type_id<T>()
|
||||
//
|
||||
// Returns a type_info associated with the type pointed
|
||||
// to by T, which may be a pointer or a reference to a pointer.
|
||||
template <class T>
|
||||
type_info pointer_type_id(T(*)() = 0)
|
||||
{
|
||||
return detail::pointer_typeid_select<
|
||||
is_reference<T>::value
|
||||
>::execute((T(*)())0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
#endif // POINTER_TYPE_ID_DWA2002222_HPP
|
||||
109
include/boost/python/detail/config.hpp
Normal file
109
include/boost/python/detail/config.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// (C) Copyright David Abrahams 2000. 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.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
// Revision History:
|
||||
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
|
||||
|
||||
#ifndef CONFIG_DWA052200_H_
|
||||
# define CONFIG_DWA052200_H_
|
||||
|
||||
# include <boost/config.hpp>
|
||||
|
||||
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
// A gcc bug forces some symbols into the global namespace
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
# define BOOST_PYTHON_CONVERSION
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x
|
||||
# else
|
||||
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
|
||||
# define BOOST_PYTHON_CONVERSION boost::python
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_MSVC)
|
||||
# if _MSC_VER <= 1200
|
||||
# define BOOST_MSVC6_OR_EARLIER 1
|
||||
# endif
|
||||
|
||||
# pragma warning (disable : 4786)
|
||||
|
||||
# elif defined(__ICL) && __ICL < 600 // Intel C++ 5
|
||||
|
||||
# pragma warning(disable: 985) // identifier was truncated in debug information
|
||||
|
||||
# endif
|
||||
|
||||
// The STLport puts all of the standard 'C' library names in std (as far as the
|
||||
// user is concerned), but without it you need a fix if you're using MSVC or
|
||||
// Intel C++
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
# define BOOST_CSTD_
|
||||
# else
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Set up dll import/export options:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
// backwards compatibility:
|
||||
#ifdef BOOST_PYTHON_STATIC_LIB
|
||||
# define BOOST_PYTHON_STATIC_LINK
|
||||
# elif !defined(BOOST_PYTHON_DYNAMIC_LIB)
|
||||
# define BOOST_PYTHON_DYNAMIC_LIB
|
||||
#endif
|
||||
|
||||
#if defined(__MWERKS__) \
|
||||
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
|
||||
# if defined(BOOST_PYTHON_SOURCE)
|
||||
# define BOOST_PYTHON_DECL __declspec(dllexport)
|
||||
# define BOOST_PYTHON_BUILD_DLL
|
||||
# else
|
||||
# define BOOST_PYTHON_DECL __declspec(dllimport)
|
||||
# endif
|
||||
|
||||
// MinGW, at least, has some problems exporting template instantiations
|
||||
# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_DECL
|
||||
# define BOOST_PYTHON_DECL
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_PYTHON_EXPORT
|
||||
# define BOOST_PYTHON_EXPORT extern
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT)
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation
|
||||
#else
|
||||
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
|
||||
// Work around a compiler bug.
|
||||
// boost::python::detail::function has to be seen by the compiler before the
|
||||
// boost::function class template.
|
||||
namespace boost { namespace python { namespace detail {
|
||||
class function;
|
||||
}}}
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
39
include/boost/python/detail/convertible.hpp
Executable file
39
include/boost/python/detail/convertible.hpp
Executable file
@@ -0,0 +1,39 @@
|
||||
// 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 CONVERTIBLE_DWA2002614_HPP
|
||||
# define CONVERTIBLE_DWA2002614_HPP
|
||||
|
||||
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/conversion_traits.hpp>
|
||||
# endif
|
||||
|
||||
// Supplies a runtime is_convertible check which can be used with tag
|
||||
// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
typedef char* yes_convertible;
|
||||
typedef int* no_convertible;
|
||||
|
||||
template <class Target>
|
||||
struct convertible
|
||||
{
|
||||
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238
|
||||
static inline no_convertible check(...) { return 0; }
|
||||
static inline yes_convertible check(Target) { return 0; }
|
||||
# else
|
||||
template <class X>
|
||||
static inline typename mpl::select_type<
|
||||
is_convertible<X,Target>::value
|
||||
, yes_convertible
|
||||
, no_convertible
|
||||
>::type check(X const&) { return 0; }
|
||||
# endif
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CONVERTIBLE_DWA2002614_HPP
|
||||
100
include/boost/python/detail/msvc_typeinfo.hpp
Normal file
100
include/boost/python/detail/msvc_typeinfo.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// 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 MSVC_TYPEINFO_DWA200222_HPP
|
||||
# define MSVC_TYPEINFO_DWA200222_HPP
|
||||
|
||||
#include <boost/type.hpp>
|
||||
#include <typeinfo>
|
||||
#include <boost/type_traits/array_traits.hpp>
|
||||
#include <boost/type_traits/reference_traits.hpp>
|
||||
//
|
||||
// Fix for MSVC's broken typeid() implementation which doesn't strip
|
||||
// decoration. This fix doesn't handle cv-qualified array types. It
|
||||
// could probably be done, but I haven't figured it out yet.
|
||||
//
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
typedef std::type_info const& typeinfo;
|
||||
|
||||
template<int>struct value_id_accessor;
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<0>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<1>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<2>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_id_accessor<3>
|
||||
{
|
||||
template <class T>
|
||||
static typeinfo get(T const volatile*) { return typeid(T); }
|
||||
};
|
||||
|
||||
template <bool> struct bool_t{};
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_nonref(boost::type<T>* = 0)
|
||||
{
|
||||
bool const c = is_const<T>::value;
|
||||
bool const v = is_volatile<T>::value;
|
||||
return value_id_accessor<(2 * v + c)>::get((T*)0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo typeid_ref(T&(*)())
|
||||
{
|
||||
return typeid_nonref<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo array_ref_typeid(bool_t<true>, bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_ref((T&(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo array_ref_typeid(bool_t<false>, bool_t<true>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_ref((T(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo array_ref_typeid(bool_t<false>, bool_t<false>, boost::type<T>* = 0)
|
||||
{
|
||||
return typeid_ref((T&(*)())0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typeinfo msvc_typeid(boost::type<T>* = 0)
|
||||
{
|
||||
typedef bool_t<is_array<T>::value> array_tag;
|
||||
typedef bool_t<is_reference<T>::value> ref_tag;
|
||||
return array_ref_typeid(array_tag(), ref_tag(), (boost::type<T>*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
# endif // BOOST_MSVC
|
||||
#endif // MSVC_TYPEINFO_DWA200222_HPP
|
||||
55
include/boost/python/detail/operator_id.hpp
Executable file
55
include/boost/python/detail/operator_id.hpp
Executable file
@@ -0,0 +1,55 @@
|
||||
// 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 OPERATOR_ID_DWA2002531_HPP
|
||||
# define OPERATOR_ID_DWA2002531_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
enum operator_id
|
||||
{
|
||||
op_add,
|
||||
op_sub,
|
||||
op_mul,
|
||||
op_div,
|
||||
op_mod,
|
||||
op_divmod,
|
||||
op_pow,
|
||||
op_lshift,
|
||||
op_rshift,
|
||||
op_and,
|
||||
op_xor,
|
||||
op_or,
|
||||
op_neg,
|
||||
op_pos,
|
||||
op_abs,
|
||||
op_invert,
|
||||
op_int,
|
||||
op_long,
|
||||
op_float,
|
||||
op_str,
|
||||
op_cmp,
|
||||
op_gt,
|
||||
op_ge,
|
||||
op_lt,
|
||||
op_le,
|
||||
op_eq,
|
||||
op_ne,
|
||||
op_iadd,
|
||||
op_isub,
|
||||
op_imul,
|
||||
op_idiv,
|
||||
op_imod,
|
||||
op_ilshift,
|
||||
op_irshift,
|
||||
op_iand,
|
||||
op_ixor,
|
||||
op_ior,
|
||||
op_complex
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // OPERATOR_ID_DWA2002531_HPP
|
||||
36
include/boost/python/detail/pointee.hpp
Normal file
36
include/boost/python/detail/pointee.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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 POINTEE_DWA2002323_HPP
|
||||
# define POINTEE_DWA2002323_HPP
|
||||
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <bool is_ptr = true>
|
||||
struct pointee_impl
|
||||
{
|
||||
template <class T> struct apply : remove_pointer<T> {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pointee_impl<false>
|
||||
{
|
||||
template <class T> struct apply
|
||||
{
|
||||
typedef typename T::element_type type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct pointee
|
||||
: pointee_impl<is_pointer<T>::value>::template apply<T>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // POINTEE_DWA2002323_HPP
|
||||
151
include/boost/python/detail/unwind_type.hpp
Normal file
151
include/boost/python/detail/unwind_type.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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 UNWIND_TYPE_DWA200222_HPP
|
||||
# define UNWIND_TYPE_DWA200222_HPP
|
||||
|
||||
# include <boost/python/detail/cv_category.hpp>
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U* p, cv_unqualified, Generator* = 0)
|
||||
{
|
||||
return Generator::execute(p);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U const* p, const_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U volatile* p, volatile_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0)
|
||||
{
|
||||
return unwind_type(const_cast<U*>(p), (Generator*)0);
|
||||
}
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_ptr_type(U* p, Generator* = 0)
|
||||
{
|
||||
typedef typename cv_category<U>::type tag;
|
||||
return unwind_type_cv<Generator>(p, tag());
|
||||
}
|
||||
|
||||
template <bool is_ptr>
|
||||
struct unwind_helper
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U p, Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(p, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper<false>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U& p, Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(&p, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type(U const& p, Generator* = 0)
|
||||
{
|
||||
return unwind_helper<is_pointer<U>::value>::execute(p, (Generator*)0);
|
||||
}
|
||||
|
||||
enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 };
|
||||
template <int indirection> struct unwind_helper2;
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<direct_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<pointer_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U*(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<reference_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U&(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type((U*)0, (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unwind_helper2<reference_to_pointer_>
|
||||
{
|
||||
template <class Generator, class U>
|
||||
static typename Generator::result_type
|
||||
execute(U&(*)(), Generator* = 0)
|
||||
{
|
||||
return unwind_ptr_type(U(0), (Generator*)0);
|
||||
}
|
||||
};
|
||||
|
||||
// Call this one with both template parameters explicitly specified
|
||||
// and no function arguments:
|
||||
//
|
||||
// return unwind_type<my_generator,T>();
|
||||
//
|
||||
// Doesn't work if T is an array type; we could handle that case, but
|
||||
// why bother?
|
||||
template <class Generator, class U>
|
||||
inline typename Generator::result_type
|
||||
unwind_type(boost::type<U>*p = 0, Generator* = 0)
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, indirection
|
||||
= (is_pointer<U>::value ? pointer_ : 0)
|
||||
+ (is_reference_to_pointer<U>::value
|
||||
? reference_to_pointer_
|
||||
: is_reference<U>::value
|
||||
? reference_
|
||||
: 0));
|
||||
|
||||
return unwind_helper2<indirection>::execute((U(*)())0,(Generator*)0);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // UNWIND_TYPE_DWA200222_HPP
|
||||
17
include/boost/python/handle_fwd.hpp
Executable file
17
include/boost/python/handle_fwd.hpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// 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 HANDLE_FWD_DWA2002615_HPP
|
||||
# define HANDLE_FWD_DWA2002615_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T = PyObject> class handle;
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // HANDLE_FWD_DWA2002615_HPP
|
||||
28
include/boost/python/implicit.hpp
Normal file
28
include/boost/python/implicit.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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 IMPLICIT_DWA2002325_HPP
|
||||
# define IMPLICIT_DWA2002325_HPP
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/python/converter/implicit.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class Source, class Target>
|
||||
void implicitly_convertible(boost::type<Source>* = 0, boost::type<Target>* = 0)
|
||||
{
|
||||
typedef converter::implicit<Source,Target> functions;
|
||||
|
||||
converter::registry::push_back(
|
||||
&functions::convertible
|
||||
, &functions::construct
|
||||
, type_id<Target>());
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // IMPLICIT_DWA2002325_HPP
|
||||
104
include/boost/python/lvalue_from_pytype.hpp
Executable file
104
include/boost/python/lvalue_from_pytype.hpp
Executable file
@@ -0,0 +1,104 @@
|
||||
// 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 LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||||
# define LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/detail/void_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Given a pointer-to-function of 1 parameter returning a reference
|
||||
// type, return the type_id of the function's return type.
|
||||
template <class T, class U>
|
||||
inline type_info extractor_type_id(T&(*)(U))
|
||||
{
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
// A function generator whose static execute() function is an lvalue
|
||||
// from_python converter using the given Extractor. U is expected to
|
||||
// be the actual type of the PyObject instance from which the result
|
||||
// is being extracted.
|
||||
template <class Extractor, class U>
|
||||
struct normalized_extractor
|
||||
{
|
||||
static inline void* execute(PyObject* op)
|
||||
{
|
||||
typedef typename boost::add_reference<U>::type param;
|
||||
return &Extractor::execute(
|
||||
boost::python::detail::void_ptr_to_reference(
|
||||
op, (param(*)())0 )
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Given an Extractor type and a pointer to its execute function,
|
||||
// return a new object whose static execute function does the same
|
||||
// job but is a conforming lvalue from_python conversion function.
|
||||
//
|
||||
// usage: normalize<Extractor>(&Extractor::execute)
|
||||
template <class Extractor, class T, class U>
|
||||
inline normalized_extractor<Extractor,U>
|
||||
normalize(T(*)(U), Extractor* = 0)
|
||||
{
|
||||
return normalized_extractor<Extractor, U>();
|
||||
}
|
||||
}
|
||||
|
||||
// An Extractor which extracts the given member from a Python object
|
||||
// whose instances are stored as InstanceType.
|
||||
template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
|
||||
struct extract_member
|
||||
{
|
||||
static MemberType& execute(InstanceType& c)
|
||||
{
|
||||
(void)c.ob_type; // static assertion
|
||||
return c.*member;
|
||||
}
|
||||
};
|
||||
|
||||
// An Extractor which simply extracts the entire python object
|
||||
// instance of InstanceType.
|
||||
template <class InstanceType>
|
||||
struct extract_identity
|
||||
{
|
||||
static InstanceType& execute(InstanceType& c)
|
||||
{
|
||||
(void)c.ob_type; // static assertion
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
// Registers a from_python conversion which extracts lvalues using
|
||||
// Extractor's static execute function from Python objects whose type
|
||||
// object is python_type.
|
||||
template <class Extractor, PyTypeObject const* python_type>
|
||||
struct lvalue_from_pytype
|
||||
{
|
||||
lvalue_from_pytype()
|
||||
{
|
||||
converter::registry::insert(
|
||||
&extract, detail::extractor_type_id(&Extractor::execute));
|
||||
}
|
||||
private:
|
||||
static void* extract(PyObject* op)
|
||||
{
|
||||
return PyObject_TypeCheck(op, const_cast<PyTypeObject*>(python_type))
|
||||
? const_cast<void*>(
|
||||
static_cast<void const volatile*>(
|
||||
detail::normalize<Extractor>(&Extractor::execute).execute(op)))
|
||||
: 0
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP
|
||||
40
include/boost/python/manage_new_object.hpp
Normal file
40
include/boost/python/manage_new_object.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
# define MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/python/to_python_indirect.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class R>
|
||||
struct manage_new_object_requires_a_pointer_return_type
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
|
||||
{}
|
||||
# endif
|
||||
;
|
||||
}
|
||||
|
||||
struct manage_new_object
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
boost::is_pointer<T>::value
|
||||
, to_python_indirect<T, detail::make_owning_holder>
|
||||
, detail::manage_new_object_requires_a_pointer_return_type<T>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // MANAGE_NEW_OBJECT_DWA200222_HPP
|
||||
76
include/boost/python/module_builder.hpp
Normal file
76
include/boost/python/module_builder.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// (C) Copyright David Abrahams 2000. 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.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef MODULE_DWA051000_H_
|
||||
# define MODULE_DWA051000_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
# include <boost/python/detail/module_init.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class BOOST_PYTHON_DECL module_builder_base
|
||||
{
|
||||
public:
|
||||
// Create a module. REQUIRES: only one module_builder is created per module.
|
||||
module_builder_base(const char* name);
|
||||
~module_builder_base();
|
||||
|
||||
// Add elements to the module
|
||||
void add(detail::function* x, const char* name);
|
||||
void add(PyTypeObject* x, const char* name = 0);
|
||||
void add(ref x, const char*name);
|
||||
|
||||
// Return true iff a module is currently being built.
|
||||
static bool initializing();
|
||||
|
||||
// Return the name of the module currently being built.
|
||||
// REQUIRES: initializing() == true
|
||||
static string name();
|
||||
|
||||
// Return a pointer to the Python module object being built
|
||||
PyObject* module() const;
|
||||
|
||||
private:
|
||||
PyObject* m_module;
|
||||
static PyMethodDef initial_methods[1];
|
||||
};
|
||||
|
||||
class module_builder : public module_builder_base
|
||||
{
|
||||
public:
|
||||
module_builder(const char* name)
|
||||
: module_builder_base(name) {}
|
||||
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_wrapped_function(fn), name);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// inline implementations
|
||||
//
|
||||
inline PyObject* module_builder_base::module() const
|
||||
{
|
||||
return m_module;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif
|
||||
90
include/boost/python/object/class_converters.hpp
Normal file
90
include/boost/python/object/class_converters.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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/object/class_wrapper.hpp>
|
||||
# include <boost/mpl/for_each.hpp>
|
||||
# include <boost/python/handle.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
# include <boost/python/object/find_instance.hpp>
|
||||
# include <boost/python/object/inheritance.hpp>
|
||||
# include <boost/python/detail/force_instantiate.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
|
||||
{
|
||||
// Ignored is needed because mpl::for_each is still actually
|
||||
// accumulate. We're not using any state so it just sits there.
|
||||
template <class Ignored, class Base>
|
||||
struct apply
|
||||
{
|
||||
typedef void type; // 'type' needs to be defined for the same reasons
|
||||
|
||||
// Here's the runtime part:
|
||||
static void execute()
|
||||
{
|
||||
// Register the Base class
|
||||
register_dynamic_id<Base>();
|
||||
// Register the up-cast
|
||||
register_conversion<Derived,Base>(false);
|
||||
|
||||
// Register the down-cast, if appropriate.
|
||||
mpl::select_type<
|
||||
is_polymorphic<Base>::value
|
||||
, 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)
|
||||
{
|
||||
// cause the static registration to be instantiated.
|
||||
python::detail::force_instantiate(instance_finder<Derived>::registration);
|
||||
|
||||
// register all up/downcasts here
|
||||
register_dynamic_id<Derived>();
|
||||
|
||||
// register each base in the sequence
|
||||
mpl::for_each<Bases, void, register_base_of<Derived> >::execute();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // CLASS_CONVERTERS_DWA2002119_HPP
|
||||
40
include/boost/python/object/find_instance.hpp
Normal file
40
include/boost/python/object/find_instance.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 FIND_INSTANCE_DWA2002312_HPP
|
||||
# define FIND_INSTANCE_DWA2002312_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/python/converter/registry.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
// Given a type_id, find the instance data which corresponds to it, or
|
||||
// return 0 in case no such type is held.
|
||||
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, type_info);
|
||||
|
||||
// This produces a function with the right signature for use in from_python conversions
|
||||
template <class T>
|
||||
struct instance_finder
|
||||
{
|
||||
instance_finder()
|
||||
{
|
||||
converter::registry::insert(&execute, python::type_id<T>());
|
||||
}
|
||||
|
||||
static instance_finder const registration;
|
||||
private:
|
||||
static inline void* execute(PyObject* p)
|
||||
{
|
||||
return find_instance_impl(p, python::type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
instance_finder<T> const instance_finder<T>::registration;
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FIND_INSTANCE_DWA2002312_HPP
|
||||
108
include/boost/python/object/forward.hpp
Normal file
108
include/boost/python/object/forward.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright David Abrahams 2001. 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 FORWARD_DWA20011215_HPP
|
||||
# define FORWARD_DWA20011215_HPP
|
||||
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/type_traits/composite_traits.hpp>
|
||||
# include <boost/type_traits/transform_traits.hpp>
|
||||
# include <boost/ref.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class T>
|
||||
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; }
|
||||
private:
|
||||
reference m_value;
|
||||
};
|
||||
|
||||
// A little metaprogram which selects the type to pass through an
|
||||
// intermediate forwarding function when the destination argument type
|
||||
// is T.
|
||||
template <class T>
|
||||
struct forward
|
||||
: mpl::select_type<
|
||||
is_scalar<T>::value
|
||||
, T
|
||||
, reference_to_value<T> >
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class unforward
|
||||
{
|
||||
public:
|
||||
typedef typename unwrap_reference<T>::type& type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unforward<reference_to_value<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
# else // no partial specialization
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_reference_to_value_t)[1];
|
||||
typedef char (&no_reference_to_value_t)[2];
|
||||
|
||||
no_reference_to_value_t is_reference_to_value_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct unforwarder
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename unwrap_reference<T>::type& type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct unforwarder<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::reference type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class 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)));
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class unforward
|
||||
: public detail::unforwarder<
|
||||
detail::is_reference_to_value<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // FORWARD_DWA20011215_HPP
|
||||
167
include/boost/python/object/inheritance.hpp
Normal file
167
include/boost/python/object/inheritance.hpp
Normal file
@@ -0,0 +1,167 @@
|
||||
// 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 INHERITANCE_DWA200216_HPP
|
||||
# define INHERITANCE_DWA200216_HPP
|
||||
|
||||
# include <boost/python/type_id.hpp>
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/mpl/select_type.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
typedef type_info class_id;
|
||||
using python::type_id;
|
||||
|
||||
// Types used to get address and id of most derived type
|
||||
typedef std::pair<void*,class_id> dynamic_id_t;
|
||||
typedef dynamic_id_t (*dynamic_id_function)(void*);
|
||||
|
||||
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);
|
||||
|
||||
// is_polymorphic test from John Maddock
|
||||
template <class T>
|
||||
struct is_polymorphic
|
||||
{
|
||||
struct d1 : public T
|
||||
{
|
||||
d1();
|
||||
char padding[256];
|
||||
};
|
||||
struct d2 : public T
|
||||
{
|
||||
d2();
|
||||
virtual ~d2();
|
||||
virtual void foo();
|
||||
char padding[256];
|
||||
};
|
||||
BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1)));
|
||||
};
|
||||
|
||||
//
|
||||
// a generator with an execute() function which, given a source type
|
||||
// and a pointer to an object of that type, returns its most-derived
|
||||
// /reachable/ type identifier and object pointer.
|
||||
//
|
||||
|
||||
// first, the case where T has virtual functions
|
||||
template <class T>
|
||||
struct polymorphic_id_generator
|
||||
{
|
||||
static dynamic_id_t execute(void* p_)
|
||||
{
|
||||
T* p = static_cast<T*>(p_);
|
||||
return std::make_pair(dynamic_cast<void*>(p), class_id(typeid(*p)));
|
||||
}
|
||||
};
|
||||
|
||||
// now, the non-polymorphic case.
|
||||
template <class T>
|
||||
struct non_polymorphic_id_generator
|
||||
{
|
||||
static dynamic_id_t execute(void* p_)
|
||||
{
|
||||
return std::make_pair(p_, python::type_id<T>());
|
||||
}
|
||||
};
|
||||
|
||||
// Now the generalized selector
|
||||
template <class T>
|
||||
struct dynamic_id_generator
|
||||
{
|
||||
typedef typename mpl::select_type<
|
||||
is_polymorphic<T>::value
|
||||
, polymorphic_id_generator<T>
|
||||
, non_polymorphic_id_generator<T> >::type type;
|
||||
};
|
||||
|
||||
// Register the dynamic id function for T with the type-conversion
|
||||
// system.
|
||||
template <class T>
|
||||
void register_dynamic_id(T* = 0)
|
||||
{
|
||||
typedef typename dynamic_id_generator<T>::type generator;
|
||||
register_dynamic_id_aux(
|
||||
python::type_id<T>(), &generator::execute);
|
||||
}
|
||||
|
||||
//
|
||||
// a generator with an execute() function which, given a void*
|
||||
// pointing to an object of type Source will attempt to convert it to
|
||||
// an object of type Target.
|
||||
//
|
||||
|
||||
template <class Source, class Target>
|
||||
struct dynamic_cast_generator
|
||||
{
|
||||
static void* execute(void* source)
|
||||
{
|
||||
return dynamic_cast<Target*>(
|
||||
static_cast<Source*>(source));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
struct implicit_cast_generator
|
||||
{
|
||||
static void* execute(void* source)
|
||||
{
|
||||
Target* result = static_cast<Source*>(source);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Source, class Target>
|
||||
struct cast_generator
|
||||
{
|
||||
// CWPro7 will return false sometimes, but that's OK since we can
|
||||
// always cast up with dynamic_cast<>
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, is_upcast = (
|
||||
is_base_and_derived<Target,Source>::value
|
||||
));
|
||||
|
||||
typedef typename mpl::select_type<
|
||||
is_upcast
|
||||
# if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
// 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
|
||||
, 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);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
||||
|
||||
#endif // INHERITANCE_DWA200216_HPP
|
||||
67
include/boost/python/object_attributes.hpp
Executable file
67
include/boost/python/object_attributes.hpp
Executable file
@@ -0,0 +1,67 @@
|
||||
// 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 OBJECT_ATTRIBUTES_DWA2002615_HPP
|
||||
# define OBJECT_ATTRIBUTES_DWA2002615_HPP
|
||||
|
||||
# include <boost/python/proxy.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/object_protocol.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
struct const_attribute_policies
|
||||
{
|
||||
typedef char const* key_type;
|
||||
static object get(object const& target, char const* key);
|
||||
};
|
||||
|
||||
struct attribute_policies : const_attribute_policies
|
||||
{
|
||||
static object const& set(object const& target, char const* key, object const& value);
|
||||
static void del(object const&target, char const* key);
|
||||
};
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
template <class U>
|
||||
inline object_attribute object_operators<U>::attr(char const* name)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_attribute(x, name);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline const_object_attribute object_operators<U>::attr(char const* name) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_attribute(x, name);
|
||||
}
|
||||
|
||||
inline object const_attribute_policies::get(object const& target, char const* key)
|
||||
{
|
||||
return python::getattr(target, key);
|
||||
}
|
||||
|
||||
inline object const& attribute_policies::set(
|
||||
object const& target
|
||||
, char const* key
|
||||
, object const& value)
|
||||
{
|
||||
python::setattr(target, key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void attribute_policies::del(
|
||||
object const& target
|
||||
, char const* key)
|
||||
{
|
||||
python::delattr(target, key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::api
|
||||
|
||||
#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP
|
||||
88
include/boost/python/object_items.hpp
Executable file
88
include/boost/python/object_items.hpp
Executable file
@@ -0,0 +1,88 @@
|
||||
// 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 OBJECT_ITEMS_DWA2002615_HPP
|
||||
# define OBJECT_ITEMS_DWA2002615_HPP
|
||||
|
||||
# include <boost/python/proxy.hpp>
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/object_protocol.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
struct const_item_policies
|
||||
{
|
||||
typedef object key_type;
|
||||
static object get(object const& target, object const& key);
|
||||
};
|
||||
|
||||
struct item_policies : const_item_policies
|
||||
{
|
||||
static object const& set(object const& target, object const& key, object const& value);
|
||||
static void del(object const& target, object const& key);
|
||||
};
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
template <class U>
|
||||
inline object_item
|
||||
object_operators<U>::operator[](object_cref key)
|
||||
{
|
||||
object_cref2 x = *static_cast<U*>(this);
|
||||
return object_item(x, key);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline const_object_item
|
||||
object_operators<U>::operator[](object_cref key) const
|
||||
{
|
||||
object_cref2 x = *static_cast<U const*>(this);
|
||||
return const_object_item(x, key);
|
||||
}
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||
template <class U>
|
||||
template <class T>
|
||||
inline const_object_item
|
||||
object_operators<U>::operator[](T const& key) const
|
||||
{
|
||||
return (*this)[object(key)];
|
||||
}
|
||||
|
||||
template <class U>
|
||||
template <class T>
|
||||
inline object_item
|
||||
object_operators<U>::operator[](T const& key)
|
||||
{
|
||||
return (*this)[object(key)];
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
inline object const_item_policies::get(object const& target, object const& key)
|
||||
{
|
||||
return getitem(target, key);
|
||||
}
|
||||
|
||||
inline object const& item_policies::set(
|
||||
object const& target
|
||||
, object const& key
|
||||
, object const& value)
|
||||
{
|
||||
setitem(target, key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void item_policies::del(
|
||||
object const& target
|
||||
, object const& key)
|
||||
{
|
||||
delitem(target, key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::api
|
||||
|
||||
#endif // OBJECT_ITEMS_DWA2002615_HPP
|
||||
555
include/boost/python/operators.hpp
Normal file
555
include/boost/python/operators.hpp
Normal file
@@ -0,0 +1,555 @@
|
||||
// (C) Copyright Ullrich Koethe and David Abrahams 2000-2001. 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.
|
||||
//
|
||||
// The authors gratefully acknowlege the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
//
|
||||
// Revision History:
|
||||
// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams)
|
||||
// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams)
|
||||
#ifndef OPERATORS_UK112000_H_
|
||||
# define OPERATORS_UK112000_H_
|
||||
# ifdef BOOST_PYTHON_V2
|
||||
|
||||
# include <boost/python/operators2.hpp>
|
||||
|
||||
# else
|
||||
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string. This confuses to_python(), so we'll use
|
||||
// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
|
||||
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
|
||||
# define BOOST_PYTHON_USE_SSTREAM
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_PYTHON_USE_SSTREAM)
|
||||
# include <sstream>
|
||||
# else
|
||||
# include <strstream>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r);
|
||||
|
||||
namespace detail {
|
||||
|
||||
// helper class for automatic operand type detection
|
||||
// during operator wrapping.
|
||||
struct auto_operand {};
|
||||
}
|
||||
|
||||
// Define operator ids that can be or'ed together
|
||||
// (boost::python::op_add | boost::python::op_sub | boost::python::op_mul).
|
||||
// This allows to wrap several operators in one line.
|
||||
enum operator_id
|
||||
{
|
||||
op_add = 0x1,
|
||||
op_sub = 0x2,
|
||||
op_mul = 0x4,
|
||||
op_div = 0x8,
|
||||
op_mod = 0x10,
|
||||
op_divmod =0x20,
|
||||
op_pow = 0x40,
|
||||
op_lshift = 0x80,
|
||||
op_rshift = 0x100,
|
||||
op_and = 0x200,
|
||||
op_xor = 0x400,
|
||||
op_or = 0x800,
|
||||
op_neg = 0x1000,
|
||||
op_pos = 0x2000,
|
||||
op_abs = 0x4000,
|
||||
op_invert = 0x8000,
|
||||
op_int = 0x10000,
|
||||
op_long = 0x20000,
|
||||
op_float = 0x40000,
|
||||
op_str = 0x80000,
|
||||
op_cmp = 0x100000,
|
||||
op_gt = 0x200000,
|
||||
op_ge = 0x400000,
|
||||
op_lt = 0x800000,
|
||||
op_le = 0x1000000,
|
||||
op_eq = 0x2000000,
|
||||
op_ne = 0x4000000
|
||||
};
|
||||
|
||||
// Wrap the operators given by "which". Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>());
|
||||
template <long which, class operand = boost::python::detail::auto_operand>
|
||||
struct operators {};
|
||||
|
||||
// Wrap heterogeneous operators with given left operand type. Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::left_operand<int>());
|
||||
template <class T>
|
||||
struct left_operand {};
|
||||
|
||||
// Wrap heterogeneous operators with given right operand type. Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::right_operand<int>());
|
||||
template <class T>
|
||||
struct right_operand {};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Specified>
|
||||
struct operand_select
|
||||
{
|
||||
template <class wrapped_type>
|
||||
struct wrapped
|
||||
{
|
||||
typedef Specified type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct operand_select<auto_operand>
|
||||
{
|
||||
template <class wrapped_type>
|
||||
struct wrapped
|
||||
{
|
||||
typedef const wrapped_type& type;
|
||||
};
|
||||
};
|
||||
|
||||
template <long> struct define_operator;
|
||||
|
||||
// Base class which grants access to extension_class_base::add_method() to its derived classes
|
||||
struct add_operator_base
|
||||
{
|
||||
protected:
|
||||
static inline void add_method(extension_class_base* target, function* method, const char* name)
|
||||
{ target->add_method(method, name); }
|
||||
};
|
||||
|
||||
//
|
||||
// choose_op, choose_unary_op, and choose_rop
|
||||
//
|
||||
// These templates use "poor man's partial specialization" to generate the
|
||||
// appropriate add_method() call (if any) for a given operator and argument set.
|
||||
//
|
||||
// Usage:
|
||||
// choose_op<(which & op_add)>::template args<left_t,right_t>::add(ext_class);
|
||||
//
|
||||
// (see extension_class<>::def_operators() for more examples).
|
||||
//
|
||||
template <long op_selector>
|
||||
struct choose_op
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template operator_function<Left, Right>(),
|
||||
def_op::name());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_op<0>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template <long op_selector>
|
||||
struct choose_unary_op
|
||||
{
|
||||
template <class Operand>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template operator_function<Operand>(),
|
||||
def_op::name());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_unary_op<0>
|
||||
{
|
||||
template <class Operand>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template <long op_selector>
|
||||
struct choose_rop
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template roperator_function<Right, Left>(),
|
||||
def_op::rname());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_rop<0>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Fully specialize define_operator for all operators defined in operator_id above.
|
||||
// Every specialization defines one function object for normal operator calls and one
|
||||
// for operator calls with operands reversed ("__r*__" function variants).
|
||||
// Specializations for most operators follow a standard pattern: execute the expression
|
||||
// that uses the operator in question. This standard pattern is realized by the following
|
||||
// macros so that the actual specialization can be done by just calling a macro.
|
||||
# define PY_DEFINE_BINARY_OPERATORS(id, oper) \
|
||||
template <> \
|
||||
struct define_operator<op_##id> \
|
||||
{ \
|
||||
template <class Left, class Right = Left> \
|
||||
struct operator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__" #id "__"; } \
|
||||
}; \
|
||||
\
|
||||
template <class Right, class Left> \
|
||||
struct roperator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__r" #id "__"; } \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
static const char * name() { return "__" #id "__"; } \
|
||||
static const char * rname() { return "__r" #id "__"; } \
|
||||
}
|
||||
|
||||
# define PY_DEFINE_UNARY_OPERATORS(id, oper) \
|
||||
template <> \
|
||||
struct define_operator<op_##id> \
|
||||
{ \
|
||||
template <class operand> \
|
||||
struct operator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()))); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__" #id "__"; } \
|
||||
}; \
|
||||
\
|
||||
static const char * name() { return "__" #id "__"; } \
|
||||
}
|
||||
|
||||
PY_DEFINE_BINARY_OPERATORS(add, +);
|
||||
PY_DEFINE_BINARY_OPERATORS(sub, -);
|
||||
PY_DEFINE_BINARY_OPERATORS(mul, *);
|
||||
PY_DEFINE_BINARY_OPERATORS(div, /);
|
||||
PY_DEFINE_BINARY_OPERATORS(mod, %);
|
||||
PY_DEFINE_BINARY_OPERATORS(lshift, <<);
|
||||
PY_DEFINE_BINARY_OPERATORS(rshift, >>);
|
||||
PY_DEFINE_BINARY_OPERATORS(and, &);
|
||||
PY_DEFINE_BINARY_OPERATORS(xor, ^);
|
||||
PY_DEFINE_BINARY_OPERATORS(or, |);
|
||||
PY_DEFINE_BINARY_OPERATORS(gt, >);
|
||||
PY_DEFINE_BINARY_OPERATORS(ge, >=);
|
||||
PY_DEFINE_BINARY_OPERATORS(lt, <);
|
||||
PY_DEFINE_BINARY_OPERATORS(le, <=);
|
||||
PY_DEFINE_BINARY_OPERATORS(eq, ==);
|
||||
PY_DEFINE_BINARY_OPERATORS(ne, !=);
|
||||
|
||||
PY_DEFINE_UNARY_OPERATORS(neg, -);
|
||||
PY_DEFINE_UNARY_OPERATORS(pos, +);
|
||||
PY_DEFINE_UNARY_OPERATORS(abs, abs);
|
||||
PY_DEFINE_UNARY_OPERATORS(invert, ~);
|
||||
PY_DEFINE_UNARY_OPERATORS(int, long);
|
||||
PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong);
|
||||
PY_DEFINE_UNARY_OPERATORS(float, double);
|
||||
|
||||
# undef PY_DEFINE_BINARY_OPERATORS
|
||||
# undef PY_DEFINE_UNARY_OPERATORS
|
||||
|
||||
// Some operators need special treatment, e.g. because there is no corresponding
|
||||
// expression in C++. These are specialized manually.
|
||||
|
||||
// pow(): Manual specialization needed because an error message is required if this
|
||||
// function is called with three arguments. The "power modulo" operator is not
|
||||
// supported by define_operator, but can be wrapped manually (see special.html).
|
||||
template <>
|
||||
struct define_operator<op_pow>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
|
||||
throw_argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__pow__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
|
||||
throw_argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rpow__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__pow__"; }
|
||||
static const char * rname() { return "__rpow__"; }
|
||||
};
|
||||
|
||||
// divmod(): Manual specialization needed because we must actually call two operators and
|
||||
// return a tuple containing both results
|
||||
template <>
|
||||
struct define_operator<op_divmod>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__divmod__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rdivmod__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__divmod__"; }
|
||||
static const char * rname() { return "__rdivmod__"; }
|
||||
};
|
||||
|
||||
// cmp(): Manual specialization needed because there is no three-way compare in C++.
|
||||
// It is implemented by two one-way comparisons with operators reversed in the second.
|
||||
template <>
|
||||
struct define_operator<op_cmp>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__cmp__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rcmp__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__cmp__"; }
|
||||
static const char * rname() { return "__rcmp__"; }
|
||||
};
|
||||
|
||||
# ifndef BOOST_PYTHON_USE_SSTREAM
|
||||
class unfreezer {
|
||||
public:
|
||||
unfreezer(std::ostrstream& s) : m_stream(s) {}
|
||||
~unfreezer() { m_stream.freeze(false); }
|
||||
private:
|
||||
std::ostrstream& m_stream;
|
||||
};
|
||||
# endif
|
||||
|
||||
// str(): Manual specialization needed because the string conversion does not follow
|
||||
// the standard pattern relized by the macros.
|
||||
template <>
|
||||
struct define_operator<op_str>
|
||||
{
|
||||
template <class operand>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject*) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string.
|
||||
# ifdef BOOST_PYTHON_USE_SSTREAM
|
||||
std::ostringstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
|
||||
return BOOST_PYTHON_CONVERSION::to_python(s.str());
|
||||
# else
|
||||
std::ostrstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()) << char();
|
||||
auto unfreezer unfreeze(s);
|
||||
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
|
||||
# endif
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__str__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__str__"; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
# undef BOOST_PYTHON_USE_SSTREAM
|
||||
# endif
|
||||
#endif /* OPERATORS_UK112000_H_ */
|
||||
113
include/boost/python/other.hpp
Executable file
113
include/boost/python/other.hpp
Executable file
@@ -0,0 +1,113 @@
|
||||
#ifndef OTHER_DWA20020601_HPP
|
||||
# define OTHER_DWA20020601_HPP
|
||||
// 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.
|
||||
|
||||
# if _MSC_VER+0 >= 1020
|
||||
# pragma once
|
||||
# endif
|
||||
|
||||
# include <boost/config.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template<class T> struct other
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
class is_other
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_other<other<T> >
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_other
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_other<other<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
# else // no partial specialization
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_other_t)[1];
|
||||
typedef char (&no_other_t)[2];
|
||||
|
||||
no_other_t is_other_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_other_t is_other_test(type< other<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct other_unwrapper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct other_unwrapper<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_other
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_other_test(type<T>()))
|
||||
== sizeof(detail::yes_other_t)));
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unwrap_other
|
||||
: public detail::other_unwrapper<
|
||||
is_other<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
}
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // #ifndef OTHER_DWA20020601_HPP
|
||||
39
include/boost/python/pointee.hpp
Normal file
39
include/boost/python/pointee.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 POINTEE_DWA2002323_HPP
|
||||
# define POINTEE_DWA2002323_HPP
|
||||
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <bool is_ptr = true>
|
||||
struct pointee_impl
|
||||
{
|
||||
template <class T> struct apply : remove_pointer<T> {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pointee_impl<false>
|
||||
{
|
||||
template <class T> struct apply
|
||||
{
|
||||
typedef typename T::element_type type;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct pointee
|
||||
: detail::pointee_impl<is_pointer<T>::value>::template apply<T>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::python::detail
|
||||
|
||||
#endif // POINTEE_DWA2002323_HPP
|
||||
101
include/boost/python/proxy.hpp
Executable file
101
include/boost/python/proxy.hpp
Executable file
@@ -0,0 +1,101 @@
|
||||
// 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 PROXY_DWA2002615_HPP
|
||||
# define PROXY_DWA2002615_HPP
|
||||
# include <boost/python/object_core.hpp>
|
||||
# include <boost/python/object_operators.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
template <class Policies>
|
||||
class proxy : public object_operators<proxy<Policies> >
|
||||
{
|
||||
typedef typename Policies::key_type key_type;
|
||||
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200
|
||||
typedef proxy const& assignment_self;
|
||||
# else
|
||||
typedef proxy assignment_self;
|
||||
# endif
|
||||
public:
|
||||
proxy(object const& target, key_type const& key);
|
||||
operator object() const;
|
||||
|
||||
// to support a[b] = c[d]
|
||||
proxy const& operator=(assignment_self) const;
|
||||
|
||||
template <class T>
|
||||
inline proxy const& operator=(T const& rhs) const
|
||||
{
|
||||
Policies::set(m_target, m_key, object(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
public: // implementation detail
|
||||
void del() const;
|
||||
|
||||
private:
|
||||
object m_target;
|
||||
key_type m_key;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
inline void del(proxy<T> const& x)
|
||||
{
|
||||
x.del();
|
||||
}
|
||||
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
|
||||
template <class Policies>
|
||||
inline proxy<Policies>::proxy(object const& target, key_type const& key)
|
||||
: m_target(target), m_key(key)
|
||||
{}
|
||||
|
||||
template <class Policies>
|
||||
inline proxy<Policies>::operator object() const
|
||||
{
|
||||
return Policies::get(m_target, m_key);
|
||||
}
|
||||
|
||||
// to support a[b] = c[d]
|
||||
template <class Policies>
|
||||
inline proxy<Policies> const& proxy<Policies>::operator=(typename proxy::assignment_self rhs) const
|
||||
{
|
||||
return *this = python::object(rhs);
|
||||
}
|
||||
|
||||
# define BOOST_PYTHON_PROXY_INPLACE(op) \
|
||||
template <class Policies, class R> \
|
||||
proxy<Policies> const& operator op(proxy<Policies> const& lhs, R const& rhs) \
|
||||
{ \
|
||||
object old(lhs); \
|
||||
return lhs = (old op rhs); \
|
||||
}
|
||||
BOOST_PYTHON_PROXY_INPLACE(+=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(-=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(*=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(/=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(%=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(<<=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(>>=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(&=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(^=)
|
||||
BOOST_PYTHON_PROXY_INPLACE(|=)
|
||||
# undef BOOST_PYTHON_PROXY_INPLACE
|
||||
|
||||
template <class Policies>
|
||||
inline void proxy<Policies>::del() const
|
||||
{
|
||||
Policies::del(m_target, m_key);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::api
|
||||
|
||||
#endif // PROXY_DWA2002615_HPP
|
||||
127
include/boost/python/ptr.hpp
Normal file
127
include/boost/python/ptr.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef PTR_DWA20020601_HPP
|
||||
# define PTR_DWA20020601_HPP
|
||||
// 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.
|
||||
//
|
||||
// Based on boost/ref.hpp, thus:
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2001 Peter Dimov
|
||||
|
||||
# if _MSC_VER+0 >= 1020
|
||||
# pragma once
|
||||
# endif
|
||||
|
||||
# include <boost/config.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template<class Ptr> class pointer_wrapper
|
||||
{
|
||||
public:
|
||||
typedef Ptr type;
|
||||
|
||||
explicit pointer_wrapper(Ptr x): p_(x) {}
|
||||
operator Ptr() const { return p_; }
|
||||
Ptr get() const { return p_; }
|
||||
private:
|
||||
Ptr p_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline pointer_wrapper<T> ptr(T t)
|
||||
{
|
||||
return pointer_wrapper<T>(t);
|
||||
}
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template<typename T>
|
||||
class is_pointer_wrapper
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_pointer_wrapper<pointer_wrapper<T> >
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_pointer
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_pointer<pointer_wrapper<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
# else // no partial specialization
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef char (&yes_pointer_wrapper_t)[1];
|
||||
typedef char (&no_pointer_wrapper_t)[2];
|
||||
|
||||
no_pointer_wrapper_t is_pointer_wrapper_test(...);
|
||||
|
||||
template<typename T>
|
||||
yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper<T> >);
|
||||
|
||||
template<bool wrapped>
|
||||
struct pointer_unwrapper
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct pointer_unwrapper<true>
|
||||
{
|
||||
template <class T>
|
||||
struct apply
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class is_pointer_wrapper
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(detail::is_pointer_wrapper_test(boost::type<T>()))
|
||||
== sizeof(detail::yes_pointer_wrapper_t)));
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class unwrap_pointer
|
||||
: public detail::pointer_unwrapper<
|
||||
is_pointer_wrapper<T>::value
|
||||
>::template apply<T>
|
||||
{};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // #ifndef PTR_DWA20020601_HPP
|
||||
42
include/boost/python/refcount.hpp
Executable file
42
include/boost/python/refcount.hpp
Executable file
@@ -0,0 +1,42 @@
|
||||
// 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 REFCOUNT_DWA2002615_HPP
|
||||
# define REFCOUNT_DWA2002615_HPP
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/cast.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
inline T* incref(T* p)
|
||||
{
|
||||
Py_INCREF(python::upcast<PyObject>(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* xincref(T* p)
|
||||
{
|
||||
Py_XINCREF(python::upcast<PyObject>(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void decref(T* p)
|
||||
{
|
||||
Py_DECREF(python::upcast<PyObject>(p));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void xdecref(T* p)
|
||||
{
|
||||
Py_XDECREF(python::upcast<PyObject>(p));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // REFCOUNT_DWA2002615_HPP
|
||||
236
include/boost/python/reference.hpp
Normal file
236
include/boost/python/reference.hpp
Normal file
@@ -0,0 +1,236 @@
|
||||
// (C) Copyright David Abrahams 2000. 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.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef PYPTR_DWA050400_H_
|
||||
# define PYPTR_DWA050400_H_
|
||||
|
||||
# ifdef BOOST_PYTHON_V2
|
||||
|
||||
# error obsolete
|
||||
|
||||
# else
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
# include <cassert>
|
||||
# include <cstddef>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
|
||||
# include <boost/python/conversions.hpp>
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
template <class T, class Value, class Base = boost::detail::empty_base>
|
||||
struct py_ptr_conversions : Base
|
||||
{
|
||||
inline friend T from_python(PyObject* x, boost::python::type<const T&>)
|
||||
{ return T(boost::python::downcast<Value>(x).get(), T::increment_count); }
|
||||
|
||||
inline friend T from_python(PyObject* x, boost::python::type<T>)
|
||||
{ return T(boost::python::downcast<Value>(x).get(), T::increment_count); }
|
||||
|
||||
inline friend PyObject* to_python(T x)
|
||||
{ return boost::python::as_object(x.release()); }
|
||||
|
||||
};
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
|
||||
|
||||
template <class T>
|
||||
class reference
|
||||
: public py_ptr_conversions<reference<T>, T>
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
reference(const reference& rhs)
|
||||
: m_p(rhs.m_p)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
|
||||
reference() : m_p(0) {}
|
||||
|
||||
// These are two ways of spelling the same thing, that we need to increment
|
||||
// the reference count on the pointer when we're initialized.
|
||||
enum increment_count_t { increment_count };
|
||||
|
||||
enum allow_null { null_ok };
|
||||
|
||||
template <class T2>
|
||||
explicit reference(T2* x)
|
||||
: m_p(expect_non_null(x))
|
||||
{
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t)
|
||||
: m_p(expect_non_null(x))
|
||||
{
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
Py_INCREF(m_p);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null)
|
||||
: m_p(x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null, increment_count_t)
|
||||
: m_p(x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t, allow_null)
|
||||
: m_p(x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(m_p);
|
||||
}
|
||||
|
||||
reference& operator=(const reference& rhs)
|
||||
{
|
||||
assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = rhs.m_p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~reference()
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
}
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return *m_p;
|
||||
}
|
||||
|
||||
// MSVC doesn't like boost::dereferencable unless T has a default
|
||||
// constructor, so operator-> must be defined by hand :(
|
||||
T* operator->() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return &**this;
|
||||
}
|
||||
|
||||
T* get() const
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
return m_p;
|
||||
}
|
||||
|
||||
T* release()
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
T* p = m_p;
|
||||
m_p = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = 0;
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = expect_non_null(x);
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, increment_count_t)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = expect_non_null(x);
|
||||
assert(m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, allow_null)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, allow_null, increment_count_t)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x, increment_count_t, allow_null)
|
||||
{
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
Py_XINCREF(x);
|
||||
Py_XDECREF(m_p);
|
||||
m_p = x;
|
||||
assert(m_p == 0 || m_p->ob_refcnt > 0);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
private:
|
||||
template<typename Y> friend class shared_ptr;
|
||||
#endif
|
||||
|
||||
inline PyObject* object() const
|
||||
{
|
||||
return as_object(m_p);
|
||||
}
|
||||
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
typedef reference<PyObject> ref;
|
||||
|
||||
template <class T>
|
||||
ref make_ref(const T& x)
|
||||
{
|
||||
return ref(to_python(x));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // BOOST_PYTHON_V2
|
||||
|
||||
#endif // PYPTR_DWA050400_H_
|
||||
30
test/back_reference.py
Normal file
30
test/back_reference.py
Normal file
@@ -0,0 +1,30 @@
|
||||
'''
|
||||
>>> from back_reference_ext import *
|
||||
>>> y = Y(3)
|
||||
>>> z = Z(4)
|
||||
>>> x_instances()
|
||||
2
|
||||
>>> y2 = copy_Y(y)
|
||||
>>> x_instances()
|
||||
3
|
||||
>>> z2 = copy_Z(z)
|
||||
>>> x_instances()
|
||||
4
|
||||
>>> y_identity(y) is y
|
||||
1
|
||||
>>> y_equality(y, y)
|
||||
1
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
34
test/borrowed.cpp
Executable file
34
test/borrowed.cpp
Executable file
@@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
template <class T>
|
||||
void assert_borrowed_ptr(T const& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr<T>::value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void assert_not_borrowed_ptr(T const& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr<T>::value);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
assert_borrowed_ptr(borrowed((PyObject*)0));
|
||||
assert_borrowed_ptr(borrowed((PyTypeObject*)0));
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> const*)0);
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> volatile*)0);
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> const volatile*)0);
|
||||
assert_not_borrowed_ptr((PyObject*)0);
|
||||
assert_not_borrowed_ptr(0);
|
||||
return 0;
|
||||
}
|
||||
133
test/callbacks.py
Normal file
133
test/callbacks.py
Normal file
@@ -0,0 +1,133 @@
|
||||
'''
|
||||
>>> from callbacks_ext import *
|
||||
|
||||
>>> def double(x):
|
||||
... return x + x
|
||||
...
|
||||
>>> apply_int_int(double, 42)
|
||||
84
|
||||
>>> apply_void_int(double, 42)
|
||||
|
||||
>>> def identity(x):
|
||||
... return x
|
||||
|
||||
Once we have array conversion support, this test will fail. Er,
|
||||
succeed<wink>:
|
||||
|
||||
>>> try: apply_to_string_literal(identity)
|
||||
... except: pass # expected
|
||||
... else: print 'expected an exception!'
|
||||
|
||||
>>> x = apply_X_X(identity, X(42))
|
||||
>>> x.value()
|
||||
42
|
||||
>>> x_count()
|
||||
1
|
||||
>>> del x
|
||||
>>> x_count()
|
||||
0
|
||||
|
||||
>>> def increment(x):
|
||||
... x.set(x.value() + 1)
|
||||
...
|
||||
>>> x = X(42)
|
||||
>>> apply_void_X_ref(increment, x)
|
||||
>>> x.value()
|
||||
43
|
||||
|
||||
>>> apply_void_X_cref(increment, x)
|
||||
>>> x.value() # const-ness is not respected, sorry!
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> def decrement(x):
|
||||
... global last_x
|
||||
... last_x = x
|
||||
... if x is not None:
|
||||
... x.set(x.value() - 1)
|
||||
|
||||
>>> apply_void_X_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
43
|
||||
>>> last_x.value()
|
||||
43
|
||||
>>> increment(last_x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> apply_void_X_deep_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_deep_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
43
|
||||
|
||||
>>> y = apply_X_ref_handle(identity, x)
|
||||
>>> assert y.value() == x.value()
|
||||
>>> increment(x)
|
||||
>>> assert y.value() == x.value()
|
||||
|
||||
>>> y = apply_X_ptr_handle_cref(identity, x)
|
||||
>>> assert y.value() == x.value()
|
||||
>>> increment(x)
|
||||
>>> assert y.value() == x.value()
|
||||
|
||||
>>> y = apply_X_ptr_handle_cref(identity, None)
|
||||
>>> y
|
||||
|
||||
>>> def new_x(ignored):
|
||||
... return X(666)
|
||||
...
|
||||
>>> try: apply_X_ref_handle(new_x, 1)
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> try: apply_X_ptr_handle_cref(new_x, 1)
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> try: apply_cstring_cstring(identity, 'hello')
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> apply_char_char(identity, 'x')
|
||||
'x'
|
||||
|
||||
>>> apply_cstring_pyobject(identity, 'hello')
|
||||
'hello'
|
||||
|
||||
>>> apply_cstring_pyobject(identity, None)
|
||||
|
||||
|
||||
>>> apply_char_char(identity, 'x')
|
||||
'x'
|
||||
|
||||
>>> assert apply_to_own_type(identity) is type(identity)
|
||||
|
||||
>>> assert apply_object_object(identity, identity) is identity
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
1281
test/comprehensive.py
Normal file
1281
test/comprehensive.py
Normal file
File diff suppressed because it is too large
Load Diff
1173
test/doctest.py
Normal file
1173
test/doctest.py
Normal file
File diff suppressed because it is too large
Load Diff
45
test/if_else.cpp
Normal file
45
test/if_else.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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.
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/python/detail/if_else.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
typedef char c1;
|
||||
typedef char c2[2];
|
||||
typedef char c3[3];
|
||||
typedef char c4[4];
|
||||
|
||||
template <unsigned size>
|
||||
struct choose
|
||||
{
|
||||
typedef typename boost::python::detail::if_<
|
||||
(sizeof(c1) == size)
|
||||
>::template then<
|
||||
c1
|
||||
>::template elif<
|
||||
(sizeof(c2) == size)
|
||||
>::template then<
|
||||
c2
|
||||
>::template elif<
|
||||
(sizeof(c3) == size)
|
||||
>::template then<
|
||||
c3
|
||||
>::template elif<
|
||||
(sizeof(c4) == size)
|
||||
>::template then<
|
||||
c4
|
||||
>::template else_<void*>::type type;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<1>::type,c1>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<2>::type,c2>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<3>::type,c3>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<4>::type,c4>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<5>::type,void*>::value));
|
||||
return 0;
|
||||
}
|
||||
80
test/indirect_traits_test.cpp
Normal file
80
test/indirect_traits_test.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
//#include <stdio.h>
|
||||
#include <cassert>
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
//#define print(expr) printf("%s ==> %s\n", #expr, expr)
|
||||
|
||||
// not all the compilers can handle an incomplete class type here.
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::detail;
|
||||
|
||||
#if 0 // not yet supported
|
||||
assert(is_reference_to_function<int (&)()>::value);
|
||||
assert(!is_reference_to_function<int (*)()>::value);
|
||||
#endif
|
||||
|
||||
assert(!is_pointer_to_function<int (&)()>::value);
|
||||
assert(is_pointer_to_function<int (*)()>::value);
|
||||
|
||||
assert(is_reference_to_pointer<int*&>::value);
|
||||
assert(is_reference_to_pointer<int* const&>::value);
|
||||
assert(is_reference_to_pointer<int*volatile&>::value);
|
||||
assert(is_reference_to_pointer<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_pointer<int const volatile>::value);
|
||||
assert(!is_reference_to_pointer<int>::value);
|
||||
assert(!is_reference_to_pointer<int*>::value);
|
||||
|
||||
assert(!is_reference_to_const<int*&>::value);
|
||||
assert(is_reference_to_const<int* const&>::value);
|
||||
assert(!is_reference_to_const<int*volatile&>::value);
|
||||
assert(is_reference_to_const<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_const<int const volatile>::value);
|
||||
assert(!is_reference_to_const<int>::value);
|
||||
assert(!is_reference_to_const<int*>::value);
|
||||
|
||||
assert(is_reference_to_non_const<int*&>::value);
|
||||
assert(!is_reference_to_non_const<int* const&>::value);
|
||||
assert(is_reference_to_non_const<int*volatile&>::value);
|
||||
assert(!is_reference_to_non_const<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_non_const<int const volatile>::value);
|
||||
assert(!is_reference_to_non_const<int>::value);
|
||||
assert(!is_reference_to_non_const<int*>::value);
|
||||
|
||||
assert(!is_reference_to_volatile<int*&>::value);
|
||||
assert(!is_reference_to_volatile<int* const&>::value);
|
||||
assert(is_reference_to_volatile<int*volatile&>::value);
|
||||
assert(is_reference_to_volatile<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_volatile<int const volatile>::value);
|
||||
assert(!is_reference_to_volatile<int>::value);
|
||||
assert(!is_reference_to_volatile<int*>::value);
|
||||
|
||||
assert(!is_reference_to_class<int>::value);
|
||||
assert(!is_reference_to_class<int&>::value);
|
||||
assert(!is_reference_to_class<int*>::value);
|
||||
|
||||
assert(!is_reference_to_class<X>::value);
|
||||
assert(is_reference_to_class<X&>::value);
|
||||
assert(is_reference_to_class<X const&>::value);
|
||||
assert(is_reference_to_class<X volatile&>::value);
|
||||
assert(is_reference_to_class<X const volatile&>::value);
|
||||
|
||||
assert(!is_pointer_to_class<int>::value);
|
||||
assert(!is_pointer_to_class<int*>::value);
|
||||
assert(!is_pointer_to_class<int&>::value);
|
||||
|
||||
assert(!is_pointer_to_class<X>::value);
|
||||
assert(!is_pointer_to_class<X&>::value);
|
||||
assert(is_pointer_to_class<X*>::value);
|
||||
assert(is_pointer_to_class<X const*>::value);
|
||||
assert(is_pointer_to_class<X volatile*>::value);
|
||||
assert(is_pointer_to_class<X const volatile*>::value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
test/iterator.py
Normal file
72
test/iterator.py
Normal file
@@ -0,0 +1,72 @@
|
||||
'''
|
||||
>>> from iterator_ext import *
|
||||
>>> from input_iterator import *
|
||||
>>> x = list_int()
|
||||
>>> x.push_back(1)
|
||||
>>> x.back()
|
||||
1
|
||||
>>> x.push_back(3)
|
||||
>>> x.push_back(5)
|
||||
>>> for y in x:
|
||||
... print y
|
||||
1
|
||||
3
|
||||
5
|
||||
>>> z = range(x)
|
||||
>>> for y in z:
|
||||
... print y
|
||||
1
|
||||
3
|
||||
5
|
||||
|
||||
Range2 wraps a transform_iterator which doubles the elements it
|
||||
traverses. This proves we can wrap input iterators
|
||||
|
||||
>>> z2 = range2(x)
|
||||
>>> for y in z2:
|
||||
... print y
|
||||
2
|
||||
6
|
||||
10
|
||||
|
||||
>>> l2 = two_lists()
|
||||
>>> for y in l2.primes:
|
||||
... print y
|
||||
2
|
||||
3
|
||||
5
|
||||
7
|
||||
11
|
||||
13
|
||||
>>> for y in l2.evens:
|
||||
... print y
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
10
|
||||
12
|
||||
>>> ll = list_list()
|
||||
>>> ll.push_back(x)
|
||||
>>> x.push_back(7)
|
||||
>>> ll.push_back(x)
|
||||
>>> for a in ll:
|
||||
... for b in a:
|
||||
... print b,
|
||||
... print
|
||||
...
|
||||
1 3 5
|
||||
1 3 5 7
|
||||
'''
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
2
test/minimal.py
Normal file
2
test/minimal.py
Normal file
@@ -0,0 +1,2 @@
|
||||
import minimal_ext
|
||||
|
||||
16
test/multi_arg_constructor.py
Normal file
16
test/multi_arg_constructor.py
Normal file
@@ -0,0 +1,16 @@
|
||||
'''
|
||||
>>> from multi_arg_constructor_ext import *
|
||||
>>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3)
|
||||
'''
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
126
test/object.py
Normal file
126
test/object.py
Normal file
@@ -0,0 +1,126 @@
|
||||
'''
|
||||
>>> from object_ext import *
|
||||
>>> def print1(x):
|
||||
... print x
|
||||
>>> call_object_3(print1)
|
||||
3
|
||||
>>> message()
|
||||
'hello, world!'
|
||||
>>> number()
|
||||
42
|
||||
|
||||
>>> test('hi')
|
||||
1
|
||||
>>> test(None)
|
||||
0
|
||||
>>> test_not('hi')
|
||||
0
|
||||
>>> test_not(0)
|
||||
1
|
||||
|
||||
Attributes
|
||||
|
||||
>>> class X: pass
|
||||
...
|
||||
>>> x = X()
|
||||
|
||||
>>> try: obj_getattr(x, 'foo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
|
||||
>>> obj_setattr(x, 'foo', 1)
|
||||
>>> x.foo
|
||||
1
|
||||
>>> obj_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_const_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_setattr42(x, 'foo')
|
||||
>>> x.foo
|
||||
42
|
||||
>>> obj_moveattr(x, 'foo', 'bar')
|
||||
>>> x.bar
|
||||
42
|
||||
>>> test_attr(x, 'foo')
|
||||
1
|
||||
>>> test_not_attr(x, 'foo')
|
||||
0
|
||||
>>> x.foo = None
|
||||
>>> test_attr(x, 'foo')
|
||||
0
|
||||
>>> test_not_attr(x, 'foo')
|
||||
1
|
||||
|
||||
Items
|
||||
|
||||
>>> d = {}
|
||||
>>> obj_setitem(d, 'foo', 1)
|
||||
>>> d['foo']
|
||||
1
|
||||
>>> obj_getitem(d, 'foo')
|
||||
1
|
||||
>>> obj_const_getitem(d, 'foo')
|
||||
1
|
||||
>>> obj_setitem42(d, 'foo')
|
||||
>>> obj_getitem(d, 'foo')
|
||||
42
|
||||
>>> d['foo']
|
||||
42
|
||||
>>> obj_moveitem(d, 'foo', 'bar')
|
||||
>>> d['bar']
|
||||
42
|
||||
>>> obj_moveitem2(d, 'bar', d, 'baz')
|
||||
>>> d['baz']
|
||||
42
|
||||
>>> test_item(d, 'foo')
|
||||
1
|
||||
>>> test_not_item(d, 'foo')
|
||||
0
|
||||
>>> d['foo'] = None
|
||||
>>> test_item(d, 'foo')
|
||||
0
|
||||
>>> test_not_item(d, 'foo')
|
||||
1
|
||||
|
||||
Slices
|
||||
|
||||
>>> assert check_string_slice()
|
||||
|
||||
Operators
|
||||
|
||||
|
||||
>>> assert check_binary_operators()
|
||||
|
||||
>>> class X: pass
|
||||
...
|
||||
>>> assert check_inplace(range(3), X())
|
||||
|
||||
|
||||
Now make sure that object is actually managing reference counts
|
||||
|
||||
>>> import weakref
|
||||
>>> class Z: pass
|
||||
...
|
||||
>>> z = Z()
|
||||
>>> def death(r): print 'death'
|
||||
...
|
||||
>>> r = weakref.ref(z, death)
|
||||
>>> z.foo = 1
|
||||
>>> obj_getattr(z, 'foo')
|
||||
1
|
||||
>>> del z
|
||||
death
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
12
test/object_fail1.cpp
Executable file
12
test/object_fail1.cpp
Executable file
@@ -0,0 +1,12 @@
|
||||
// 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.
|
||||
#include <boost/python/object.hpp>
|
||||
|
||||
int f(boost::python::object const& x)
|
||||
{
|
||||
x._("hello") = 1;
|
||||
return 0;
|
||||
}
|
||||
86
test/operators.py
Normal file
86
test/operators.py
Normal file
@@ -0,0 +1,86 @@
|
||||
'''
|
||||
>>> from operators_ext import *
|
||||
>>> x = X(42)
|
||||
>>> x.value()
|
||||
42
|
||||
>>> y = x - X(5)
|
||||
>>> y.value()
|
||||
37
|
||||
>>> y = x - 4
|
||||
>>> y.value()
|
||||
38
|
||||
>>> y = 3 - x
|
||||
>>> y.value()
|
||||
-39
|
||||
>>> (-y).value()
|
||||
39
|
||||
|
||||
>>> abs(y).value()
|
||||
39
|
||||
|
||||
>>> x < 10
|
||||
0
|
||||
>>> x < 43
|
||||
1
|
||||
|
||||
>>> 10 < x
|
||||
1
|
||||
>>> 43 < x
|
||||
0
|
||||
|
||||
>>> x < y
|
||||
0
|
||||
>>> y < x
|
||||
1
|
||||
|
||||
------
|
||||
>>> x > 10
|
||||
1
|
||||
>>> x > 43
|
||||
0
|
||||
|
||||
>>> 10 > x
|
||||
0
|
||||
>>> 43 > x
|
||||
1
|
||||
|
||||
>>> x > y
|
||||
1
|
||||
>>> y > x
|
||||
0
|
||||
|
||||
>>> y = x - 5
|
||||
>>> x -= y
|
||||
>>> x.value()
|
||||
5
|
||||
>>> str(x)
|
||||
'5'
|
||||
|
||||
>>> z = Z(10)
|
||||
>>> int(z)
|
||||
10
|
||||
>>> float(z)
|
||||
10.0
|
||||
>>> complex(z)
|
||||
(10+0j)
|
||||
|
||||
>>> pow(2,x)
|
||||
32
|
||||
>>> pow(x,2).value()
|
||||
25
|
||||
>>> pow(X(2),x).value()
|
||||
32
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
35
test/pointee.cpp
Normal file
35
test/pointee.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
#include <boost/python/pointee.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
struct A;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<std::auto_ptr<char**> >::type
|
||||
, char**
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<boost::shared_ptr<A> >::type
|
||||
, A>::value));
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<char*>::type
|
||||
, char
|
||||
>::value));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
39
test/pointer_type_id_test.cpp
Normal file
39
test/pointer_type_id_test.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <cassert>
|
||||
#include <boost/python/converter/pointer_type_id.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::converter;
|
||||
|
||||
boost::python::type_info x
|
||||
= boost::python::type_id<int>();
|
||||
|
||||
|
||||
assert(pointer_type_id<int*>() == x);
|
||||
assert(pointer_type_id<int const*>() == x);
|
||||
assert(pointer_type_id<int volatile*>() == x);
|
||||
assert(pointer_type_id<int const volatile*>() == x);
|
||||
|
||||
assert(pointer_type_id<int*&>() == x);
|
||||
assert(pointer_type_id<int const*&>() == x);
|
||||
assert(pointer_type_id<int volatile*&>() == x);
|
||||
assert(pointer_type_id<int const volatile*&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*const&>() == x);
|
||||
assert(pointer_type_id<int const*const&>() == x);
|
||||
assert(pointer_type_id<int volatile*const&>() == x);
|
||||
assert(pointer_type_id<int const volatile*const&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*volatile&>() == x);
|
||||
assert(pointer_type_id<int const*volatile&>() == x);
|
||||
assert(pointer_type_id<int volatile*volatile&>() == x);
|
||||
assert(pointer_type_id<int const volatile*volatile&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*const volatile&>() == x);
|
||||
assert(pointer_type_id<int const*const volatile&>() == x);
|
||||
assert(pointer_type_id<int volatile*const volatile&>() == x);
|
||||
assert(pointer_type_id<int const volatile*const volatile&>() == x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
test/raw_pyobject_fail1.cpp
Executable file
12
test/raw_pyobject_fail1.cpp
Executable file
@@ -0,0 +1,12 @@
|
||||
// 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.
|
||||
#include <boost/python/converter/arg_to_python.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::python::converter::arg_to_python<PyTypeObject*> x(0);
|
||||
return 0;
|
||||
}
|
||||
14
test/raw_pyobject_fail2.cpp
Executable file
14
test/raw_pyobject_fail2.cpp
Executable file
@@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
#include <boost/python/converter/arg_to_python.hpp>
|
||||
|
||||
struct X : PyObject {};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::python::converter::arg_to_python<X*> x(0);
|
||||
return 0;
|
||||
}
|
||||
112
test/result.cpp
Executable file
112
test/result.cpp
Executable file
@@ -0,0 +1,112 @@
|
||||
// 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.
|
||||
#include <boost/python/detail/result.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <functional>
|
||||
|
||||
using boost::python::detail::result;
|
||||
using boost::type;
|
||||
|
||||
void expect_int(type<int>*) {}
|
||||
void expect_string(type<char*>*) {}
|
||||
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Test the usage which works for functions, member functions, and data members
|
||||
expect_int(
|
||||
result((int(*)())0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(*)(char))0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)())0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)(char))0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)())0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)(char))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)())0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)(char))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*))0)
|
||||
);
|
||||
|
||||
// Show that we can use the general version that works for
|
||||
// AdaptableFunctions
|
||||
expect_int(
|
||||
result((int(*)())0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)())0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result(std::plus<int>(),0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)())0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)())0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result(std::plus<char*>(),0)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
157
test/select_from_python_test.cpp
Normal file
157
test/select_from_python_test.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include <boost/python/converter/arg_from_python.hpp>
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition
|
||||
#if ((defined(__GNUC__) && __GNUC__ < 3)) \
|
||||
|| (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
|
||||
namespace boost { namespace python {
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}}
|
||||
#endif
|
||||
|
||||
int result;
|
||||
|
||||
#define ASSERT_SAME(T1,T2) \
|
||||
if (!is_same< T1, T2 >::value) { \
|
||||
std::cout << "*********************\n"; \
|
||||
std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \
|
||||
std::cout << "*********************\n"; \
|
||||
result = 1; \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::converter;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int>::type, arg_rvalue_from_python<int>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const>::type, arg_rvalue_from_python<int const>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile>::type, arg_rvalue_from_python<int volatile>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile>::type, arg_rvalue_from_python<int const volatile>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*>::type, pointer_arg_from_python<int*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*>::type, pointer_arg_from_python<int const*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*>::type, pointer_arg_from_python<int volatile*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*>::type, pointer_arg_from_python<int const volatile*>
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int&>::type, reference_arg_from_python<int&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const&>::type, arg_rvalue_from_python<int const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile&>::type, reference_arg_from_python<int volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile&>::type, reference_arg_from_python<int const volatile&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*&>::type, reference_arg_from_python<int*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*&>::type, reference_arg_from_python<int const*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*&>::type, reference_arg_from_python<int volatile*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*&>::type, reference_arg_from_python<int const volatile*&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int* const&>::type, pointer_cref_arg_from_python<int*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const* const&>::type, pointer_cref_arg_from_python<int const*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile* const&>::type, pointer_cref_arg_from_python<int volatile*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile* const&>::type, pointer_cref_arg_from_python<int const volatile*const&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*volatile&>::type, reference_arg_from_python<int*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*volatile&>::type, reference_arg_from_python<int const*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*volatile&>::type, reference_arg_from_python<int volatile*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*volatile&>::type, reference_arg_from_python<int const volatile*volatile&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*const volatile&>::type, reference_arg_from_python<int*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*const volatile&>::type, reference_arg_from_python<int const*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*const volatile&>::type, reference_arg_from_python<int volatile*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*const volatile&>::type, reference_arg_from_python<int const volatile*const volatile&>
|
||||
);
|
||||
return result;
|
||||
}
|
||||
19
test/upcast.cpp
Executable file
19
test/upcast.cpp
Executable file
@@ -0,0 +1,19 @@
|
||||
// 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.
|
||||
#include <boost/python/cast.hpp>
|
||||
|
||||
struct X { long x; };
|
||||
struct Y : X, PyObject {};
|
||||
|
||||
int main()
|
||||
{
|
||||
PyTypeObject o;
|
||||
Y y;
|
||||
assert(&boost::python::upcast<PyObject>(&o)->ob_refcnt == &o.ob_refcnt);
|
||||
assert(&boost::python::upcast<PyObject>(&y)->ob_refcnt == &y.ob_refcnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user