2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 06:02:14 +00:00

better auto_ptr support

[SVN r17592]
This commit is contained in:
Dave Abrahams
2003-02-22 18:11:08 +00:00
parent b42b243287
commit acdad5caf3
5 changed files with 108 additions and 11 deletions

View File

@@ -0,0 +1,64 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/mpl/bool_c.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory>
#endif
#ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
namespace boost { namespace python { namespace detail {
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_AUTO_PTR)
template <class T>
struct is_auto_ptr
{
typedef char yes;
typedef char (&no)[2];
static
T& f();
template <class U>
static yes test(std::auto_ptr<U>&, int);
template <class U>
static no test(U&, ...);
BOOST_STATIC_CONSTANT(
bool, value = sizeof(test(f(), 0)) == sizeof(yes));
typedef mpl::bool_c<value> type;
};
# else
template <class T>
struct is_auto_ptr : mpl::false_c
{
};
# if !defined(BOOST_NO_AUTO_PTR)
template <class T>
struct is_auto_ptr<std::auto_ptr<T> > : mpl::true_c
{
};
# endif
# endif
template <class T>
struct copy_ctor_mutates_rhs
: is_auto_ptr<T>
{
};
}}} // namespace boost::python::detail
#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP

View File

@@ -11,12 +11,13 @@
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/call_traits.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/python/object_core.hpp>
# include <boost/python/refcount.hpp>
# include <boost/utility.hpp>
# include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/detail/void_return.hpp>
namespace boost { namespace python {
@@ -53,7 +54,12 @@ namespace converter
template <class T>
struct extract_rvalue : private noncopyable
{
typedef typename call_traits<T>::param_type result_type;
typedef typename mpl::if_<
python::detail::copy_ctor_mutates_rhs<T>
, T&
, typename call_traits<T>::param_type
>::type result_type;
extract_rvalue(PyObject*);
bool check() const;

View File

@@ -66,10 +66,17 @@ BOOST_PYTHON_MODULE(auto_ptr_ext)
.def("value", &X::value)
;
class_<Y, std::auto_ptr<Y>, bases<X>, boost::noncopyable>("X", init<int>())
class_<Y, std::auto_ptr<Y>, bases<X>, boost::noncopyable>("Y", init<int>())
;
// VC6 auto_ptrs do not have converting constructors
#if defined(BOOST_MSVC_STD_ITERATOR)
scope().attr("broken_auto_ptr") = 1;
#else
scope().attr("broken_auto_ptr") = 0;
implicitly_convertible<std::auto_ptr<Y>, std::auto_ptr<X> >();
#endif
def("look", look);
def("steal", steal);
def("maybe_steal", maybe_steal);

View File

@@ -13,13 +13,13 @@
>>> maybe_steal(x, 1)
42
>>> (not '--broken-auto-ptr' in sys.argv) and look(x) or -1
>>> broken_auto_ptr and -1 or look(x)
-1
>>> x = X(69)
>>> steal(x)
69
>>> (not '--broken-auto-ptr' in sys.argv) and look(x) or -1
>>> broken_auto_ptr and -1 or look(x)
-1
>>> if not '--broken-auto-ptr' in sys.argv:
@@ -46,9 +46,6 @@
>>> y.value()
42
>>> maybe_steal(y, 0)
42
>>> try: maybe_steal(y, 0)
... except TypeError: pass
... else: print 'expected a TypeError exception'
@@ -56,10 +53,10 @@
>>> y.value()
42
>>> steal(y)
>>> broken_auto_ptr and 42 or steal(y)
42
>>> if not '--broken-auto-ptr' in sys.argv:
>>> if not broken_auto_ptr:
... try: y.value()
... except TypeError: pass
... else: print 'expected a TypeError exception'

23
test/copy_ctor_mutates_rhs.cpp Executable file
View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
#include <boost/static_assert.hpp>
#include <memory>
#include <string>
struct foo
{
operator std::auto_ptr<int>&() const;
};
int main()
{
using namespace boost::python::detail;
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<int>::value);
BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs<std::auto_ptr<int> >::value);
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<std::string>::value);
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<foo>::value);
}