Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:46:11

0001 // Copyright David Abrahams 2002.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
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; // separate line is gcc-2.96 workaround
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         // check if either custodian or ward exceeds the arity
0089         // (this weird formulation avoids "always false" warnings
0090         // for arity_ = 0)
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 }} // namespace boost::python
0120 
0121 #endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP