| // 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/ice.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 |