File indexing completed on 2025-01-19 09:46:11
0001
0002
0003
0004
0005 #ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
0006 # define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
0007
0008 # include <boost/python/detail/prefix.hpp>
0009
0010 # include <boost/python/default_call_policies.hpp>
0011 # include <boost/python/object/life_support.hpp>
0012 # include <algorithm>
0013
0014 namespace boost { namespace python {
0015
0016 namespace detail
0017 {
0018 template <std::size_t N>
0019 struct get_prev
0020 {
0021 template <class ArgumentPackage>
0022 static PyObject* execute(ArgumentPackage const& args, PyObject* = 0)
0023 {
0024 int const pre_n = static_cast<int>(N) - 1;
0025 return detail::get(mpl::int_<pre_n>(), args);
0026 }
0027 };
0028 template <>
0029 struct get_prev<0>
0030 {
0031 template <class ArgumentPackage>
0032 static PyObject* execute(ArgumentPackage const&, PyObject* zeroth)
0033 {
0034 return zeroth;
0035 }
0036 };
0037 }
0038 template <
0039 std::size_t custodian
0040 , std::size_t ward
0041 , class BasePolicy_ = default_call_policies
0042 >
0043 struct with_custodian_and_ward : BasePolicy_
0044 {
0045 BOOST_STATIC_ASSERT(custodian != ward);
0046 BOOST_STATIC_ASSERT(custodian > 0);
0047 BOOST_STATIC_ASSERT(ward > 0);
0048
0049 template <class ArgumentPackage>
0050 static bool precall(ArgumentPackage const& args_)
0051 {
0052 unsigned arity_ = detail::arity(args_);
0053 if (custodian > arity_ || ward > arity_)
0054 {
0055 PyErr_SetString(
0056 PyExc_IndexError
0057 , "boost::python::with_custodian_and_ward: argument index out of range"
0058 );
0059 return false;
0060 }
0061
0062 PyObject* patient = detail::get_prev<ward>::execute(args_);
0063 PyObject* nurse = detail::get_prev<custodian>::execute(args_);
0064
0065 PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient);
0066 if (life_support == 0)
0067 return false;
0068
0069 bool result = BasePolicy_::precall(args_);
0070
0071 if (!result) {
0072 Py_DECREF(life_support);
0073 }
0074
0075 return result;
0076 }
0077 };
0078
0079 template <std::size_t custodian, std::size_t ward, class BasePolicy_ = default_call_policies>
0080 struct with_custodian_and_ward_postcall : BasePolicy_
0081 {
0082 BOOST_STATIC_ASSERT(custodian != ward);
0083
0084 template <class ArgumentPackage>
0085 static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
0086 {
0087 std::size_t arity_ = detail::arity(args_);
0088
0089
0090
0091 if ( (std::max)(custodian, ward) > arity_ )
0092 {
0093 PyErr_SetString(
0094 PyExc_IndexError
0095 , "boost::python::with_custodian_and_ward_postcall: argument index out of range"
0096 );
0097 return 0;
0098 }
0099
0100 PyObject* patient = detail::get_prev<ward>::execute(args_, result);
0101 PyObject* nurse = detail::get_prev<custodian>::execute(args_, result);
0102
0103 if (nurse == 0) return 0;
0104
0105 result = BasePolicy_::postcall(args_, result);
0106 if (result == 0)
0107 return 0;
0108
0109 if (python::objects::make_nurse_and_patient(nurse, patient) == 0)
0110 {
0111 Py_XDECREF(result);
0112 return 0;
0113 }
0114 return result;
0115 }
0116 };
0117
0118
0119 }}
0120
0121 #endif