212 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| // 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 DEF_HELPER_DWA200287_HPP
 | |
| # define DEF_HELPER_DWA200287_HPP
 | |
| 
 | |
| # include <boost/python/args.hpp>
 | |
| # include <boost/type_traits/same_traits.hpp>
 | |
| # include <boost/python/detail/indirect_traits.hpp>
 | |
| # include <boost/mpl/not.hpp>
 | |
| # include <boost/mpl/and.hpp>
 | |
| # include <boost/mpl/or.hpp>
 | |
| # include <boost/type_traits/add_reference.hpp>
 | |
| # include <boost/mpl/lambda.hpp>
 | |
| # include <boost/mpl/apply.hpp>
 | |
| # include <boost/tuple/tuple.hpp>
 | |
| # include <boost/python/detail/not_specified.hpp>
 | |
| # include <boost/python/detail/def_helper_fwd.hpp>
 | |
| 
 | |
| namespace boost { namespace python {
 | |
| 
 | |
| struct default_call_policies;
 | |
| 
 | |
| namespace detail
 | |
| {
 | |
|   // tuple_extract<Tuple,Predicate>::extract(t) returns the first
 | |
|   // element of a Tuple whose type E satisfies the given Predicate
 | |
|   // applied to add_reference<E>. The Predicate must be an MPL
 | |
|   // metafunction class.
 | |
|   template <class Tuple, class Predicate>
 | |
|   struct tuple_extract;
 | |
| 
 | |
|   // Implementation class for when the tuple's head type does not
 | |
|   // satisfy the Predicate
 | |
|   template <bool matched>
 | |
|   struct tuple_extract_impl
 | |
|   {
 | |
|       template <class Tuple, class Predicate>
 | |
|       struct apply
 | |
|       {
 | |
|           typedef typename Tuple::head_type result_type;
 | |
|           
 | |
|           static typename Tuple::head_type extract(Tuple const& x)
 | |
|           {
 | |
|               return x.get_head();
 | |
|           }
 | |
|       };
 | |
|   };
 | |
| 
 | |
|   // Implementation specialization for when the tuple's head type
 | |
|   // satisfies the predicate
 | |
|   template <>
 | |
|   struct tuple_extract_impl<false>
 | |
|   {
 | |
|       template <class Tuple, class Predicate>
 | |
|       struct apply
 | |
|       {
 | |
|           // recursive application of tuple_extract on the tail of the tuple
 | |
|           typedef tuple_extract<typename Tuple::tail_type, Predicate> next;
 | |
|           typedef typename next::result_type result_type;
 | |
|           
 | |
|           static result_type extract(Tuple const& x)
 | |
|           {
 | |
|               return next::extract(x.get_tail());
 | |
|           }
 | |
|       };
 | |
|   };
 | |
| 
 | |
|   // A metafunction which selects a version of tuple_extract_impl to
 | |
|   // use for the implementation of tuple_extract
 | |
|   template <class Tuple, class Predicate>
 | |
|   struct tuple_extract_base_select
 | |
|   {
 | |
|       typedef typename Tuple::head_type head_type;
 | |
|       typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t;
 | |
|       BOOST_STATIC_CONSTANT(bool, match = match_t::value);
 | |
|       typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type;
 | |
|   };
 | |
|   
 | |
|   template <class Tuple, class Predicate>
 | |
|   struct tuple_extract
 | |
|       : tuple_extract_base_select<
 | |
|          Tuple
 | |
|          , typename mpl::lambda<Predicate>::type
 | |
|       >::type
 | |
|   {
 | |
|   };
 | |
| 
 | |
| 
 | |
|   //
 | |
|   // Specialized extractors for the docstring, keywords, CallPolicies,
 | |
|   // and default implementation of virtual functions
 | |
|   //
 | |
| 
 | |
|   template <class Tuple>
 | |
|   struct doc_extract
 | |
|       : tuple_extract<
 | |
|         Tuple
 | |
|         , mpl::not_<
 | |
|            mpl::or_<
 | |
|                indirect_traits::is_reference_to_class<mpl::_1>
 | |
|              , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 >
 | |
|            >
 | |
|         >
 | |
|      >
 | |
|   {
 | |
|   };
 | |
|   
 | |
|   template <class Tuple>
 | |
|   struct keyword_extract
 | |
|       : tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > >
 | |
|   {
 | |
|   };
 | |
| 
 | |
|   template <class Tuple>
 | |
|   struct policy_extract
 | |
|       : tuple_extract<
 | |
|           Tuple
 | |
|           , mpl::and_<
 | |
|              mpl::not_<is_same<not_specified const&,mpl::_1> >
 | |
|               , indirect_traits::is_reference_to_class<mpl::_1 >
 | |
|               , mpl::not_<is_reference_to_keywords<mpl::_1 > >
 | |
|           >
 | |
|         >
 | |
|   {
 | |
|   };
 | |
| 
 | |
|   template <class Tuple>
 | |
|   struct default_implementation_extract
 | |
|       : tuple_extract<
 | |
|           Tuple
 | |
|           , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 >
 | |
|           >
 | |
|   {
 | |
|   };
 | |
| 
 | |
|   //
 | |
|   // A helper class for decoding the optional arguments to def()
 | |
|   // invocations, which can be supplied in any order and are
 | |
|   // discriminated by their type properties. The template parameters
 | |
|   // are expected to be the types of the actual (optional) arguments
 | |
|   // passed to def().
 | |
|   //
 | |
|   template <class T1, class T2, class T3, class T4>
 | |
|   struct def_helper
 | |
|   {
 | |
|       // A tuple type which begins with references to the supplied
 | |
|       // arguments and ends with actual representatives of the default
 | |
|       // types.
 | |
|       typedef boost::tuples::tuple<
 | |
|           T1 const&
 | |
|           , T2 const&
 | |
|           , T3 const&
 | |
|           , T4 const&
 | |
|           , default_call_policies
 | |
|           , detail::keywords<0>
 | |
|           , char const*
 | |
|           , void(not_specified::*)()   // A function pointer type which is never an
 | |
|                                        // appropriate default implementation
 | |
|           > all_t;
 | |
| 
 | |
|       // Constructors; these initialize an member of the tuple type
 | |
|       // shown above.
 | |
|       def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {}
 | |
|       def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {}
 | |
|       def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {}
 | |
|       def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {}
 | |
| 
 | |
|    private: // types
 | |
|       typedef typename default_implementation_extract<all_t>::result_type default_implementation_t;
 | |
|       
 | |
|    public: // Constants which can be used for static assertions.
 | |
| 
 | |
|       // Users must not supply a default implementation for non-class
 | |
|       // methods.
 | |
|       BOOST_STATIC_CONSTANT(
 | |
|           bool, has_default_implementation = (
 | |
|               !is_same<default_implementation_t, void(not_specified::*)()>::value));
 | |
|       
 | |
|    public: // Extractor functions which pull the appropriate value out
 | |
|            // of the tuple
 | |
|       char const* doc() const
 | |
|       {
 | |
|           return doc_extract<all_t>::extract(m_all);
 | |
|       }
 | |
|       
 | |
|       typename keyword_extract<all_t>::result_type keywords() const
 | |
|       {
 | |
|           return keyword_extract<all_t>::extract(m_all);
 | |
|       }
 | |
|       
 | |
|       typename policy_extract<all_t>::result_type policies() const
 | |
|       {
 | |
|           return policy_extract<all_t>::extract(m_all);
 | |
|       }
 | |
| 
 | |
|       default_implementation_t default_implementation() const
 | |
|       {
 | |
|           return default_implementation_extract<all_t>::extract(m_all);
 | |
|       }
 | |
|       
 | |
|    private: // data members
 | |
|       all_t m_all; 
 | |
|       not_specified m_nil; // for filling in not_specified slots
 | |
|   };
 | |
| }
 | |
| 
 | |
| }} // namespace boost::python::detail
 | |
| 
 | |
| #endif // DEF_HELPER_DWA200287_HPP
 | 
