1 // Copyright David Abrahams 2002. 2 // Distributed under the Boost Software License, Version 1.0. (See 3 // accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 #ifndef DEF_HELPER_DWA200287_HPP 6 # define DEF_HELPER_DWA200287_HPP 7 8 # include <boost/python/args.hpp> 9 # include <boost/python/detail/indirect_traits.hpp> 10 # include <boost/python/detail/type_traits.hpp> 11 # include <boost/mpl/not.hpp> 12 # include <boost/mpl/and.hpp> 13 # include <boost/mpl/or.hpp> 14 # include <boost/mpl/lambda.hpp> 15 # include <boost/mpl/apply.hpp> 16 # include <boost/tuple/tuple.hpp> 17 # include <boost/python/detail/not_specified.hpp> 18 # include <boost/python/detail/def_helper_fwd.hpp> 19 20 namespace boost { namespace python { 21 22 struct default_call_policies; 23 24 namespace detail 25 { 26 // tuple_extract<Tuple,Predicate>::extract(t) returns the first 27 // element of a Tuple whose type E satisfies the given Predicate 28 // applied to add_reference<E>. The Predicate must be an MPL 29 // metafunction class. 30 template <class Tuple, class Predicate> 31 struct tuple_extract; 32 33 // Implementation class for when the tuple's head type does not 34 // satisfy the Predicate 35 template <bool matched> 36 struct tuple_extract_impl 37 { 38 template <class Tuple, class Predicate> 39 struct apply 40 { 41 typedef typename Tuple::head_type result_type; 42 extractboost::python::detail::tuple_extract_impl::apply43 static typename Tuple::head_type extract(Tuple const& x) 44 { 45 return x.get_head(); 46 } 47 }; 48 }; 49 50 // Implementation specialization for when the tuple's head type 51 // satisfies the predicate 52 template <> 53 struct tuple_extract_impl<false> 54 { 55 template <class Tuple, class Predicate> 56 struct apply 57 { 58 // recursive application of tuple_extract on the tail of the tuple 59 typedef tuple_extract<typename Tuple::tail_type, Predicate> next; 60 typedef typename next::result_type result_type; 61 extractboost::python::detail::tuple_extract_impl::apply62 static result_type extract(Tuple const& x) 63 { 64 return next::extract(x.get_tail()); 65 } 66 }; 67 }; 68 69 // A metafunction which selects a version of tuple_extract_impl to 70 // use for the implementation of tuple_extract 71 template <class Tuple, class Predicate> 72 struct tuple_extract_base_select 73 { 74 typedef typename Tuple::head_type head_type; 75 typedef typename mpl::apply1<Predicate, 76 typename add_lvalue_reference<head_type>::type>::type match_t; 77 BOOST_STATIC_CONSTANT(bool, match = match_t::value); 78 typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type; 79 }; 80 81 template <class Tuple, class Predicate> 82 struct tuple_extract 83 : tuple_extract_base_select< 84 Tuple 85 , typename mpl::lambda<Predicate>::type 86 >::type 87 { 88 }; 89 90 91 // 92 // Specialized extractors for the docstring, keywords, CallPolicies, 93 // and default implementation of virtual functions 94 // 95 96 template <class Tuple> 97 struct doc_extract 98 : tuple_extract< 99 Tuple 100 , mpl::not_< 101 mpl::or_< 102 indirect_traits::is_reference_to_class<mpl::_1> 103 , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > 104 > 105 > 106 > 107 { 108 }; 109 110 template <class Tuple> 111 struct keyword_extract 112 : tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > > 113 { 114 }; 115 116 template <class Tuple> 117 struct policy_extract 118 : tuple_extract< 119 Tuple 120 , mpl::and_< 121 mpl::not_<is_same<not_specified const&,mpl::_1> > 122 , indirect_traits::is_reference_to_class<mpl::_1 > 123 , mpl::not_<is_reference_to_keywords<mpl::_1 > > 124 > 125 > 126 { 127 }; 128 129 template <class Tuple> 130 struct default_implementation_extract 131 : tuple_extract< 132 Tuple 133 , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > 134 > 135 { 136 }; 137 138 // 139 // A helper class for decoding the optional arguments to def() 140 // invocations, which can be supplied in any order and are 141 // discriminated by their type properties. The template parameters 142 // are expected to be the types of the actual (optional) arguments 143 // passed to def(). 144 // 145 template <class T1, class T2, class T3, class T4> 146 struct def_helper 147 { 148 // A tuple type which begins with references to the supplied 149 // arguments and ends with actual representatives of the default 150 // types. 151 typedef boost::tuples::tuple< 152 T1 const& 153 , T2 const& 154 , T3 const& 155 , T4 const& 156 , default_call_policies 157 , detail::keywords<0> 158 , char const* 159 , void(not_specified::*)() // A function pointer type which is never an 160 // appropriate default implementation 161 > all_t; 162 163 // Constructors; these initialize an member of the tuple type 164 // shown above. def_helperboost::python::detail::def_helper165 def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} def_helperboost::python::detail::def_helper166 def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} def_helperboost::python::detail::def_helper167 def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} def_helperboost::python::detail::def_helper168 def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} 169 170 private: // types 171 typedef typename default_implementation_extract<all_t>::result_type default_implementation_t; 172 173 public: // Constants which can be used for static assertions. 174 175 // Users must not supply a default implementation for non-class 176 // methods. 177 BOOST_STATIC_CONSTANT( 178 bool, has_default_implementation = ( 179 !is_same<default_implementation_t, void(not_specified::*)()>::value)); 180 181 public: // Extractor functions which pull the appropriate value out 182 // of the tuple docboost::python::detail::def_helper183 char const* doc() const 184 { 185 return doc_extract<all_t>::extract(m_all); 186 } 187 keywordsboost::python::detail::def_helper188 typename keyword_extract<all_t>::result_type keywords() const 189 { 190 return keyword_extract<all_t>::extract(m_all); 191 } 192 policiesboost::python::detail::def_helper193 typename policy_extract<all_t>::result_type policies() const 194 { 195 return policy_extract<all_t>::extract(m_all); 196 } 197 default_implementationboost::python::detail::def_helper198 default_implementation_t default_implementation() const 199 { 200 return default_implementation_extract<all_t>::extract(m_all); 201 } 202 203 private: // data members 204 all_t m_all; 205 not_specified m_nil; // for filling in not_specified slots 206 }; 207 } 208 209 }} // namespace boost::python::detail 210 211 #endif // DEF_HELPER_DWA200287_HPP 212