1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright David Abrahams 2002, Joel de Guzman, 2002. 4 // Distributed under the Boost Software License, Version 1.0. (See 5 // accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 /////////////////////////////////////////////////////////////////////////////// 9 #if !defined(BOOST_PP_IS_ITERATING) 10 11 #ifndef DEFAULTS_DEF_JDG20020811_HPP 12 #define DEFAULTS_DEF_JDG20020811_HPP 13 14 #include <boost/python/detail/defaults_gen.hpp> 15 #include <boost/python/detail/type_traits.hpp> 16 #include <boost/mpl/front.hpp> 17 #include <boost/mpl/size.hpp> 18 #include <boost/static_assert.hpp> 19 #include <boost/preprocessor/iterate.hpp> 20 #include <boost/python/class_fwd.hpp> 21 #include <boost/python/scope.hpp> 22 #include <boost/preprocessor/debug/line.hpp> 23 #include <boost/python/detail/scope.hpp> 24 #include <boost/python/detail/make_keyword_range_fn.hpp> 25 #include <boost/python/object/add_to_namespace.hpp> 26 27 /////////////////////////////////////////////////////////////////////////////// 28 namespace boost { namespace python { 29 30 struct module; 31 32 namespace objects 33 { 34 struct class_base; 35 } 36 37 namespace detail 38 { 39 // Called as:: 40 // 41 // name_space_def(ns, "func", func, kw, policies, docstring, &ns) 42 // 43 // Dispatch to properly add f to namespace ns. 44 // 45 // @group define_stub_function helpers { 46 template <class Func, class CallPolicies, class NameSpaceT> name_space_def(NameSpaceT & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,objects::class_base *)47 static void name_space_def( 48 NameSpaceT& name_space 49 , char const* name 50 , Func f 51 , keyword_range const& kw 52 , CallPolicies const& policies 53 , char const* doc 54 , objects::class_base* 55 ) 56 { 57 typedef typename NameSpaceT::wrapped_type wrapped_type; 58 59 objects::add_to_namespace( 60 name_space, name, 61 detail::make_keyword_range_function( 62 f, policies, kw, get_signature(f, (wrapped_type*)0)) 63 , doc 64 ); 65 } 66 67 template <class Func, class CallPolicies> name_space_def(object & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,...)68 static void name_space_def( 69 object& name_space 70 , char const* name 71 , Func f 72 , keyword_range const& kw 73 , CallPolicies const& policies 74 , char const* doc 75 , ... 76 ) 77 { 78 scope within(name_space); 79 80 detail::scope_setattr_doc( 81 name 82 , detail::make_keyword_range_function(f, policies, kw) 83 , doc); 84 } 85 86 // For backward compatibility -- is this obsolete? 87 template <class Func, class CallPolicies, class NameSpaceT> name_space_def(NameSpaceT & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,module *)88 static void name_space_def( 89 NameSpaceT& name_space 90 , char const* name 91 , Func f 92 , keyword_range const& kw // ignored 93 , CallPolicies const& policies 94 , char const* doc 95 , module* 96 ) 97 { 98 name_space.def(name, f, policies, doc); 99 } 100 // } 101 102 103 // Expansions of :: 104 // 105 // template <typename OverloadsT, typename NameSpaceT> 106 // inline void 107 // define_stub_function( 108 // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_<N>) 109 // { 110 // name_space.def(name, &OverloadsT::func_N); 111 // } 112 // 113 // where N runs from 0 to BOOST_PYTHON_MAX_ARITY. 114 // 115 // The set of overloaded functions (define_stub_function) expects: 116 // 117 // 1. char const* name: function name that will be visible to python 118 // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) 119 // 3. NameSpaceT& name_space: a python::class_ or python::module instance 120 // 4. int_t<N>: the Nth overloaded function (OverloadsT::func_N) 121 // (see defaults_gen.hpp) 122 // 5. char const* name: doc string 123 // 124 // @group define_stub_function<N> { 125 template <int N> 126 struct define_stub_function {}; 127 128 #define BOOST_PP_ITERATION_PARAMS_1 \ 129 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>)) 130 131 #include BOOST_PP_ITERATE() 132 133 // } 134 135 // This helper template struct does the actual recursive 136 // definition. There's a generic version 137 // define_with_defaults_helper<N> and a terminal case 138 // define_with_defaults_helper<0>. The struct and its 139 // specialization has a sole static member function def that 140 // expects: 141 // 142 // 1. char const* name: function name that will be 143 // visible to python 144 // 145 // 2. OverloadsT: a function overloads struct 146 // (see defaults_gen.hpp) 147 // 148 // 3. NameSpaceT& name_space: a python::class_ or 149 // python::module instance 150 // 151 // 4. char const* name: doc string 152 // 153 // The def static member function calls a corresponding 154 // define_stub_function<N>. The general case recursively calls 155 // define_with_defaults_helper<N-1>::def until it reaches the 156 // terminal case case define_with_defaults_helper<0>. 157 template <int N> 158 struct define_with_defaults_helper { 159 160 template <class StubsT, class CallPolicies, class NameSpaceT> 161 static void defboost::python::detail::define_with_defaults_helper162 def( 163 char const* name, 164 StubsT stubs, 165 keyword_range kw, 166 CallPolicies const& policies, 167 NameSpaceT& name_space, 168 char const* doc) 169 { 170 // define the NTH stub function of stubs 171 define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc); 172 173 if (kw.second > kw.first) 174 --kw.second; 175 176 // call the next define_with_defaults_helper 177 define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc); 178 } 179 }; 180 181 template <> 182 struct define_with_defaults_helper<0> { 183 184 template <class StubsT, class CallPolicies, class NameSpaceT> 185 static void defboost::python::detail::define_with_defaults_helper186 def( 187 char const* name, 188 StubsT stubs, 189 keyword_range const& kw, 190 CallPolicies const& policies, 191 NameSpaceT& name_space, 192 char const* doc) 193 { 194 // define the Oth stub function of stubs 195 define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc); 196 // return 197 } 198 }; 199 200 // define_with_defaults 201 // 202 // 1. char const* name: function name that will be 203 // visible to python 204 // 205 // 2. OverloadsT: a function overloads struct 206 // (see defaults_gen.hpp) 207 // 208 // 3. CallPolicies& policies: Call policies 209 // 4. NameSpaceT& name_space: a python::class_ or 210 // python::module instance 211 // 212 // 5. SigT sig: Function signature typelist 213 // (see defaults_gen.hpp) 214 // 215 // 6. char const* name: doc string 216 // 217 // This is the main entry point. This function recursively 218 // defines all stub functions of StubT (see defaults_gen.hpp) in 219 // NameSpaceT name_space which can be either a python::class_ or 220 // a python::module. The sig argument is a typelist that 221 // specifies the return type, the class (for member functions, 222 // and the arguments. Here are some SigT examples: 223 // 224 // int foo(int) mpl::vector<int, int> 225 // void bar(int, int) mpl::vector<void, int, int> 226 // void C::foo(int) mpl::vector<void, C, int> 227 // 228 template <class OverloadsT, class NameSpaceT, class SigT> 229 inline void define_with_defaults(char const * name,OverloadsT const & overloads,NameSpaceT & name_space,SigT const &)230 define_with_defaults( 231 char const* name, 232 OverloadsT const& overloads, 233 NameSpaceT& name_space, 234 SigT const&) 235 { 236 typedef typename mpl::front<SigT>::type return_type; 237 typedef typename OverloadsT::void_return_type void_return_type; 238 typedef typename OverloadsT::non_void_return_type non_void_return_type; 239 240 typedef typename mpl::if_c< 241 is_same<void, return_type>::value 242 , void_return_type 243 , non_void_return_type 244 >::type stubs_type; 245 246 BOOST_STATIC_ASSERT( 247 (stubs_type::max_args) <= mpl::size<SigT>::value); 248 249 typedef typename stubs_type::template gen<SigT> gen_type; 250 define_with_defaults_helper<stubs_type::n_funcs-1>::def( 251 name 252 , gen_type() 253 , overloads.keywords() 254 , overloads.call_policies() 255 , name_space 256 , overloads.doc_string()); 257 } 258 259 } // namespace detail 260 261 }} // namespace boost::python 262 263 #endif // DEFAULTS_DEF_JDG20020811_HPP 264 265 #else // defined(BOOST_PP_IS_ITERATING) 266 // PP vertical iteration code 267 268 269 template <> 270 struct define_stub_function<BOOST_PP_ITERATION()> { 271 template <class StubsT, class CallPolicies, class NameSpaceT> definedefine_stub_function272 static void define( 273 char const* name 274 , StubsT const& 275 , keyword_range const& kw 276 , CallPolicies const& policies 277 , NameSpaceT& name_space 278 , char const* doc) 279 { 280 detail::name_space_def( 281 name_space 282 , name 283 , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()) 284 , kw 285 , policies 286 , doc 287 , &name_space); 288 } 289 }; 290 291 #endif // !defined(BOOST_PP_IS_ITERATING) 292