mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 12:30:23 -04:00 
			
		
		
		
	git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7593 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
		
			
				
	
	
		
			122 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright David Abrahams 2002.
 | |
| // Distributed under the Boost Software License, Version 1.0. (See
 | |
| // accompanying file LICENSE_1_0.txt or copy at
 | |
| // http://www.boost.org/LICENSE_1_0.txt)
 | |
| #ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
 | |
| # define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
 | |
| 
 | |
| # include <boost/python/detail/prefix.hpp>
 | |
| 
 | |
| # include <boost/python/default_call_policies.hpp>
 | |
| # include <boost/python/object/life_support.hpp>
 | |
| # include <algorithm>
 | |
| 
 | |
| namespace boost { namespace python { 
 | |
| 
 | |
| namespace detail
 | |
| {
 | |
|   template <std::size_t N>
 | |
|   struct get_prev
 | |
|   {
 | |
|       template <class ArgumentPackage>
 | |
|       static PyObject* execute(ArgumentPackage const& args, PyObject* = 0)
 | |
|       {
 | |
|           int const pre_n = static_cast<int>(N) - 1; // separate line is gcc-2.96 workaround
 | |
|           return detail::get(mpl::int_<pre_n>(), args);
 | |
|       }
 | |
|   };
 | |
|   template <>
 | |
|   struct get_prev<0>
 | |
|   {
 | |
|       template <class ArgumentPackage>
 | |
|       static PyObject* execute(ArgumentPackage const&, PyObject* zeroth)
 | |
|       {
 | |
|           return zeroth;
 | |
|       }
 | |
|   };
 | |
| }
 | |
| template <
 | |
|     std::size_t custodian
 | |
|   , std::size_t ward
 | |
|   , class BasePolicy_ = default_call_policies
 | |
| >
 | |
| struct with_custodian_and_ward : BasePolicy_
 | |
| {
 | |
|     BOOST_STATIC_ASSERT(custodian != ward);
 | |
|     BOOST_STATIC_ASSERT(custodian > 0);
 | |
|     BOOST_STATIC_ASSERT(ward > 0);
 | |
| 
 | |
|     template <class ArgumentPackage>
 | |
|     static bool precall(ArgumentPackage const& args_)
 | |
|     {
 | |
|         unsigned arity_ = detail::arity(args_);
 | |
|         if (custodian > arity_ || ward > arity_)
 | |
|         {
 | |
|             PyErr_SetString(
 | |
|                 PyExc_IndexError
 | |
|               , "boost::python::with_custodian_and_ward: argument index out of range"
 | |
|             );
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         PyObject* patient = detail::get_prev<ward>::execute(args_);
 | |
|         PyObject* nurse = detail::get_prev<custodian>::execute(args_);
 | |
| 
 | |
|         PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient);
 | |
|         if (life_support == 0)
 | |
|             return false;
 | |
|     
 | |
|         bool result = BasePolicy_::precall(args_);
 | |
| 
 | |
|         if (!result) {
 | |
|             Py_DECREF(life_support);
 | |
|         }
 | |
|     
 | |
|         return result;
 | |
|     }
 | |
| };
 | |
| 
 | |
| template <std::size_t custodian, std::size_t ward, class BasePolicy_ = default_call_policies>
 | |
| struct with_custodian_and_ward_postcall : BasePolicy_
 | |
| {
 | |
|     BOOST_STATIC_ASSERT(custodian != ward);
 | |
|     
 | |
|     template <class ArgumentPackage>
 | |
|     static PyObject* postcall(ArgumentPackage const& args_, PyObject* result)
 | |
|     {
 | |
|         std::size_t arity_ = detail::arity(args_);
 | |
|         // check if either custodian or ward exceeds the arity
 | |
|         // (this weird formulation avoids "always false" warnings
 | |
|         // for arity_ = 0)
 | |
|         if ( (std::max)(custodian, ward) > arity_ )
 | |
|         {
 | |
|             PyErr_SetString(
 | |
|                 PyExc_IndexError
 | |
|               , "boost::python::with_custodian_and_ward_postcall: argument index out of range"
 | |
|             );
 | |
|             return 0;
 | |
|         }
 | |
|         
 | |
|         PyObject* patient = detail::get_prev<ward>::execute(args_, result);
 | |
|         PyObject* nurse = detail::get_prev<custodian>::execute(args_, result);
 | |
| 
 | |
|         if (nurse == 0) return 0;
 | |
|     
 | |
|         result = BasePolicy_::postcall(args_, result);
 | |
|         if (result == 0)
 | |
|             return 0;
 | |
|             
 | |
|         if (python::objects::make_nurse_and_patient(nurse, patient) == 0)
 | |
|         {
 | |
|             Py_XDECREF(result);
 | |
|             return 0;
 | |
|         }
 | |
|         return result;
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| }} // namespace boost::python
 | |
| 
 | |
| #endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP
 |