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