python.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. // Copyright Daniel Wallin 2006. Use, modification and distribution is
  2. // subject to the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_PARAMETER_PYTHON_060209_HPP
  5. # define BOOST_PARAMETER_PYTHON_060209_HPP
  6. # include <boost/mpl/vector.hpp>
  7. # include <boost/mpl/fold.hpp>
  8. # include <boost/mpl/prior.hpp>
  9. # include <boost/mpl/shift_right.hpp>
  10. # include <boost/mpl/shift_left.hpp>
  11. # include <boost/mpl/bitand.hpp>
  12. # include <boost/mpl/pair.hpp>
  13. # include <boost/mpl/size.hpp>
  14. # include <boost/mpl/push_back.hpp>
  15. # include <boost/mpl/or.hpp>
  16. # include <boost/mpl/count_if.hpp>
  17. # include <boost/mpl/transform.hpp>
  18. # include <boost/mpl/front.hpp>
  19. # include <boost/mpl/iterator_range.hpp>
  20. # include <boost/mpl/next.hpp>
  21. # include <boost/mpl/begin_end.hpp>
  22. # include <boost/mpl/not.hpp>
  23. # include <boost/mpl/empty.hpp>
  24. # include <boost/python/def.hpp>
  25. # include <boost/python/make_constructor.hpp>
  26. # include <boost/python/init.hpp>
  27. # include <boost/python/to_python_converter.hpp>
  28. # include <boost/parameter/aux_/maybe.hpp>
  29. # include <boost/parameter/aux_/python/invoker.hpp>
  30. namespace boost { namespace parameter { namespace python
  31. {
  32. namespace python_ = boost::python;
  33. }}}
  34. namespace boost { namespace parameter { namespace python { namespace aux
  35. {
  36. inline PyObject* unspecified_type()
  37. {
  38. static PyTypeObject unspecified = {
  39. PyObject_HEAD_INIT(NULL)
  40. 0, /* ob_size */
  41. "Boost.Parameter.Unspecified", /* tp_name */
  42. PyType_Type.tp_basicsize, /* tp_basicsize */
  43. 0, /* tp_itemsize */
  44. 0, /* tp_dealloc */
  45. 0, /* tp_print */
  46. 0, /* tp_getattr */
  47. 0, /* tp_setattr */
  48. 0, /* tp_compare */
  49. 0, /* tp_repr */
  50. 0, /* tp_as_number */
  51. 0, /* tp_as_sequence */
  52. 0, /* tp_as_mapping */
  53. 0, /* tp_hash */
  54. 0, /* tp_call */
  55. 0, /* tp_str */
  56. 0, /* tp_getattro */
  57. 0, /* tp_setattro */
  58. 0, /* tp_as_buffer */
  59. Py_TPFLAGS_DEFAULT, /* tp_flags */
  60. 0, /* tp_doc */
  61. };
  62. if (unspecified.ob_type == 0)
  63. {
  64. unspecified.ob_type = &PyType_Type;
  65. PyType_Ready(&unspecified);
  66. }
  67. return (PyObject*)&unspecified;
  68. }
  69. struct empty_tag {};
  70. struct empty_tag_to_python
  71. {
  72. static PyObject* convert(empty_tag)
  73. {
  74. return python_::xincref(unspecified_type());
  75. }
  76. };
  77. }}}} // namespace boost::parameter::python::aux
  78. namespace boost { namespace python
  79. {
  80. // Converts a Python value to a maybe<T>
  81. template <class T>
  82. struct arg_from_python<parameter::aux::maybe<T> >
  83. : arg_from_python<T>
  84. {
  85. arg_from_python(PyObject* p)
  86. : arg_from_python<T>(p)
  87. , empty(parameter::python::aux::unspecified_type() == p)
  88. {}
  89. bool convertible() const
  90. {
  91. return empty || arg_from_python<T>::convertible();
  92. }
  93. parameter::aux::maybe<T> operator()()
  94. {
  95. if (empty)
  96. {
  97. return parameter::aux::maybe<T>();
  98. }
  99. else
  100. {
  101. return parameter::aux::maybe<T>(
  102. arg_from_python<T>::operator()()
  103. );
  104. }
  105. }
  106. bool empty;
  107. };
  108. }} // namespace boost::python
  109. namespace boost { namespace parameter { namespace python {
  110. namespace aux
  111. {
  112. template <class K>
  113. struct is_optional
  114. : mpl::not_<
  115. mpl::or_<typename K::required, typename K::optimized_default>
  116. >
  117. {};
  118. template <class K, class Required, class Optimized, class T>
  119. struct arg_spec
  120. {
  121. typedef K keyword;
  122. typedef Required required;
  123. typedef T type;
  124. typedef Optimized optimized_default;
  125. };
  126. template <class K, class T, class Optimized = mpl::false_>
  127. struct make_arg_spec_impl
  128. {
  129. typedef arg_spec<
  130. typename K::first, typename K::second, Optimized, T
  131. > type;
  132. };
  133. template <class K, class T>
  134. struct make_arg_spec_impl<K, T, typename K::third>
  135. {
  136. typedef arg_spec<
  137. typename K::first, typename K::second, typename K::third, T
  138. > type;
  139. };
  140. template <class K, class T>
  141. struct make_arg_spec
  142. : make_arg_spec_impl<K, T>
  143. {
  144. };
  145. template <class Spec, class State>
  146. struct combinations_op
  147. {
  148. typedef typename State::second bits;
  149. typedef typename State::first result0;
  150. typedef typename mpl::if_<
  151. mpl::or_<
  152. typename Spec::required
  153. , typename Spec::optimized_default
  154. , mpl::bitand_<bits, mpl::long_<1> >
  155. >
  156. , typename mpl::push_back<result0, Spec>::type
  157. , result0
  158. >::type result;
  159. typedef typename mpl::if_<
  160. mpl::or_<
  161. typename Spec::required
  162. , typename Spec::optimized_default
  163. >
  164. , bits
  165. , typename mpl::shift_right<bits, mpl::long_<1> >::type
  166. >::type next_bits;
  167. typedef mpl::pair<
  168. result
  169. , next_bits
  170. > type;
  171. };
  172. // Used as start value in the recursive arg() composition below.
  173. struct no_keywords
  174. {
  175. template <class T>
  176. T const& operator,(T const& x) const
  177. {
  178. return x;
  179. }
  180. };
  181. template <class Def, class F, class Iter, class End, class Keywords>
  182. void def_combination_aux0(
  183. Def def, F f, Iter, End, Keywords const& keywords, mpl::false_)
  184. {
  185. typedef typename mpl::deref<Iter>::type spec;
  186. typedef typename spec::keyword kw;
  187. def_combination_aux(
  188. def, f, typename mpl::next<Iter>::type(), End()
  189. , (
  190. keywords, boost::python::arg(kw::keyword_name())
  191. )
  192. );
  193. }
  194. template <class Def, class F, class Iter, class End, class Keywords>
  195. void def_combination_aux0(
  196. Def def, F f, Iter, End, Keywords const& keywords, mpl::true_)
  197. {
  198. typedef typename mpl::deref<Iter>::type spec;
  199. typedef typename spec::keyword kw;
  200. def_combination_aux(
  201. def, f, typename mpl::next<Iter>::type(), End()
  202. , (
  203. keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
  204. )
  205. );
  206. }
  207. inline void initialize_converter()
  208. {
  209. static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
  210. }
  211. template <class Def, class F, class Iter, class End, class Keywords>
  212. void def_combination_aux(
  213. Def def, F f, Iter, End, Keywords const& keywords)
  214. {
  215. typedef typename mpl::deref<Iter>::type spec;
  216. typedef typename mpl::and_<
  217. typename spec::optimized_default
  218. , mpl::not_<typename spec::required>
  219. >::type optimized_default;
  220. def_combination_aux0(
  221. def, f, Iter(), End(), keywords, optimized_default()
  222. );
  223. }
  224. template <class Def, class F, class End, class Keywords>
  225. void def_combination_aux(
  226. Def def, F f, End, End, Keywords const& keywords)
  227. {
  228. def(f, keywords);
  229. }
  230. template <class Def, class F, class End>
  231. void def_combination_aux(
  232. Def def, F f, End, End, no_keywords const&)
  233. {
  234. def(f);
  235. }
  236. template <
  237. class Def, class Specs, class Bits, class Invoker
  238. >
  239. void def_combination(
  240. Def def, Specs*, Bits, Invoker*)
  241. {
  242. typedef typename mpl::fold<
  243. Specs
  244. , mpl::pair<mpl::vector0<>, Bits>
  245. , combinations_op<mpl::_2, mpl::_1>
  246. >::type combination0;
  247. typedef typename combination0::first combination;
  248. typedef typename mpl::apply_wrap1<
  249. Invoker, combination
  250. >::type invoker;
  251. def_combination_aux(
  252. def
  253. , &invoker::execute
  254. , typename mpl::begin<combination>::type()
  255. , typename mpl::end<combination>::type()
  256. , no_keywords()
  257. );
  258. }
  259. template <
  260. class Def, class Specs, class Bits, class End, class Invoker
  261. >
  262. void def_combinations(
  263. Def def, Specs*, Bits, End, Invoker*)
  264. {
  265. initialize_converter();
  266. def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
  267. def_combinations(
  268. def
  269. , (Specs*)0
  270. , mpl::long_<Bits::value + 1>()
  271. , End()
  272. , (Invoker*)0
  273. );
  274. }
  275. template <
  276. class Def, class Specs, class End, class Invoker
  277. >
  278. void def_combinations(
  279. Def, Specs*, End, End, Invoker*)
  280. {}
  281. struct not_specified {};
  282. template <class CallPolicies>
  283. struct call_policies_as_options
  284. {
  285. call_policies_as_options(CallPolicies const& call_policies)
  286. : call_policies(call_policies)
  287. {}
  288. CallPolicies const& policies() const
  289. {
  290. return call_policies;
  291. }
  292. char const* doc() const
  293. {
  294. return 0;
  295. }
  296. CallPolicies call_policies;
  297. };
  298. template <class Class, class Options = not_specified>
  299. struct def_class
  300. {
  301. def_class(Class& cl, char const* name, Options options = Options())
  302. : cl(cl)
  303. , name(name)
  304. , options(options)
  305. {}
  306. template <class F>
  307. void def(F f, not_specified const*) const
  308. {
  309. cl.def(name, f);
  310. }
  311. template <class F>
  312. void def(F f, void const*) const
  313. {
  314. cl.def(name, f, options.doc(), options.policies());
  315. }
  316. template <class F>
  317. void operator()(F f) const
  318. {
  319. this->def(f, &options);
  320. }
  321. template <class F, class Keywords>
  322. void def(F f, Keywords const& keywords, not_specified const*) const
  323. {
  324. cl.def(name, f, keywords);
  325. }
  326. template <class F, class Keywords>
  327. void def(F f, Keywords const& keywords, void const*) const
  328. {
  329. cl.def(name, f, keywords, options.doc(), options.policies());
  330. }
  331. template <class F, class Keywords>
  332. void operator()(F f, Keywords const& keywords) const
  333. {
  334. this->def(f, keywords, &options);
  335. }
  336. Class& cl;
  337. char const* name;
  338. Options options;
  339. };
  340. template <class Class, class CallPolicies = boost::python::default_call_policies>
  341. struct def_init
  342. {
  343. def_init(Class& cl, CallPolicies call_policies = CallPolicies())
  344. : cl(cl)
  345. , call_policies(call_policies)
  346. {}
  347. template <class F>
  348. void operator()(F f) const
  349. {
  350. cl.def(
  351. "__init__"
  352. , boost::python::make_constructor(f, call_policies)
  353. );
  354. }
  355. template <class F, class Keywords>
  356. void operator()(F f, Keywords const& keywords) const
  357. {
  358. cl.def(
  359. "__init__"
  360. , boost::python::make_constructor(f, call_policies, keywords)
  361. );
  362. }
  363. Class& cl;
  364. CallPolicies call_policies;
  365. };
  366. struct def_function
  367. {
  368. def_function(char const* name)
  369. : name(name)
  370. {}
  371. template <class F>
  372. void operator()(F f) const
  373. {
  374. boost::python::def(name, f);
  375. }
  376. template <class F, class Keywords>
  377. void operator()(F f, Keywords const& keywords) const
  378. {
  379. boost::python::def(name, f, keywords);
  380. }
  381. char const* name;
  382. };
  383. } // namespace aux
  384. template <class M, class Signature>
  385. void def(char const* name, Signature)
  386. {
  387. typedef mpl::iterator_range<
  388. typename mpl::next<
  389. typename mpl::begin<Signature>::type
  390. >::type
  391. , typename mpl::end<Signature>::type
  392. > arg_types;
  393. typedef typename mpl::transform<
  394. typename M::keywords
  395. , arg_types
  396. , aux::make_arg_spec<mpl::_1, mpl::_2>
  397. , mpl::back_inserter<mpl::vector0<> >
  398. >::type arg_specs;
  399. typedef typename mpl::count_if<
  400. arg_specs
  401. , aux::is_optional<mpl::_1>
  402. >::type optional_arity;
  403. typedef typename mpl::front<Signature>::type result_type;
  404. typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
  405. aux::def_combinations(
  406. aux::def_function(name)
  407. , (arg_specs*)0
  408. , mpl::long_<0>()
  409. , mpl::long_<upper::value>()
  410. , (aux::make_invoker<M, result_type>*)0
  411. );
  412. }
  413. template <class M, class Class, class Signature>
  414. void def(Class& cl, char const* name, Signature)
  415. {
  416. typedef mpl::iterator_range<
  417. typename mpl::next<
  418. typename mpl::begin<Signature>::type
  419. >::type
  420. , typename mpl::end<Signature>::type
  421. > arg_types;
  422. typedef typename mpl::transform<
  423. typename M::keywords
  424. , arg_types
  425. , aux::make_arg_spec<mpl::_1, mpl::_2>
  426. , mpl::back_inserter<mpl::vector0<> >
  427. >::type arg_specs;
  428. typedef typename mpl::count_if<
  429. arg_specs
  430. , aux::is_optional<mpl::_1>
  431. >::type optional_arity;
  432. typedef typename mpl::front<Signature>::type result_type;
  433. typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
  434. aux::def_combinations(
  435. aux::def_class<Class>(cl, name)
  436. , (arg_specs*)0
  437. , mpl::long_<0>()
  438. , mpl::long_<upper::value>()
  439. , (aux::make_invoker<M, result_type>*)0
  440. );
  441. }
  442. namespace aux
  443. {
  444. template <class K>
  445. struct keyword
  446. {
  447. typedef K type;
  448. };
  449. template <class K>
  450. struct keyword<K*>
  451. {
  452. typedef K type;
  453. };
  454. template <class K>
  455. struct keyword<K**>
  456. {
  457. typedef K type;
  458. };
  459. template <class K>
  460. struct required
  461. {
  462. typedef mpl::true_ type;
  463. };
  464. template <class K>
  465. struct required<K*>
  466. {
  467. typedef mpl::false_ type;
  468. };
  469. template <class K>
  470. struct optimized
  471. {
  472. typedef mpl::true_ type;
  473. };
  474. template <class K>
  475. struct optimized<K**>
  476. {
  477. typedef mpl::false_ type;
  478. };
  479. template <class T>
  480. struct make_kw_spec;
  481. template <class K, class T>
  482. struct make_kw_spec<K(T)>
  483. {
  484. typedef arg_spec<
  485. typename keyword<K>::type
  486. , typename required<K>::type
  487. , typename optimized<K>::type
  488. , T
  489. > type;
  490. };
  491. } // namespace aux
  492. template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
  493. struct init
  494. : boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
  495. {
  496. init(CallPolicies call_policies = CallPolicies())
  497. : call_policies(call_policies)
  498. {}
  499. template <class CallPolicies1>
  500. init<ParameterSpecs, CallPolicies1>
  501. operator[](CallPolicies1 const& call_policies) const
  502. {
  503. return init<ParameterSpecs, CallPolicies1>(call_policies);
  504. }
  505. template <class Class>
  506. void visit_aux(Class& cl, mpl::true_) const
  507. {
  508. cl.def(boost::python::init<>()[call_policies]);
  509. }
  510. template <class Class>
  511. void visit_aux(Class& cl, mpl::false_) const
  512. {
  513. typedef typename mpl::transform<
  514. ParameterSpecs
  515. , aux::make_kw_spec<mpl::_>
  516. , mpl::back_inserter<mpl::vector0<> >
  517. >::type arg_specs;
  518. typedef typename mpl::count_if<
  519. arg_specs
  520. , aux::is_optional<mpl::_>
  521. >::type optional_arity;
  522. typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
  523. aux::def_combinations(
  524. aux::def_init<Class, CallPolicies>(cl, call_policies)
  525. , (arg_specs*)0
  526. , mpl::long_<0>()
  527. , mpl::long_<upper::value>()
  528. , (aux::make_init_invoker<typename Class::wrapped_type>*)0
  529. );
  530. }
  531. template <class Class>
  532. void visit(Class& cl) const
  533. {
  534. visit_aux(cl, mpl::empty<ParameterSpecs>());
  535. }
  536. CallPolicies call_policies;
  537. };
  538. template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
  539. struct call
  540. : boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
  541. {
  542. call(CallPolicies const& call_policies = CallPolicies())
  543. : call_policies(call_policies)
  544. {}
  545. template <class CallPolicies1>
  546. call<ParameterSpecs, CallPolicies1>
  547. operator[](CallPolicies1 const& call_policies) const
  548. {
  549. return call<ParameterSpecs, CallPolicies1>(call_policies);
  550. }
  551. template <class Class>
  552. void visit(Class& cl) const
  553. {
  554. typedef mpl::iterator_range<
  555. typename mpl::next<
  556. typename mpl::begin<ParameterSpecs>::type
  557. >::type
  558. , typename mpl::end<ParameterSpecs>::type
  559. > arg_types;
  560. typedef typename mpl::front<ParameterSpecs>::type result_type;
  561. typedef typename mpl::transform<
  562. arg_types
  563. , aux::make_kw_spec<mpl::_>
  564. , mpl::back_inserter<mpl::vector0<> >
  565. >::type arg_specs;
  566. typedef typename mpl::count_if<
  567. arg_specs
  568. , aux::is_optional<mpl::_>
  569. >::type optional_arity;
  570. typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
  571. typedef aux::call_policies_as_options<CallPolicies> options;
  572. aux::def_combinations(
  573. aux::def_class<Class, options>(cl, "__call__", options(call_policies))
  574. , (arg_specs*)0
  575. , mpl::long_<0>()
  576. , mpl::long_<upper::value>()
  577. , (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
  578. );
  579. }
  580. CallPolicies call_policies;
  581. };
  582. template <class Fwd, class ParameterSpecs>
  583. struct function
  584. : boost::python::def_visitor<function<Fwd, ParameterSpecs> >
  585. {
  586. template <class Class, class Options>
  587. void visit(Class& cl, char const* name, Options const& options) const
  588. {
  589. typedef mpl::iterator_range<
  590. typename mpl::next<
  591. typename mpl::begin<ParameterSpecs>::type
  592. >::type
  593. , typename mpl::end<ParameterSpecs>::type
  594. > arg_types;
  595. typedef typename mpl::front<ParameterSpecs>::type result_type;
  596. typedef typename mpl::transform<
  597. arg_types
  598. , aux::make_kw_spec<mpl::_>
  599. , mpl::back_inserter<mpl::vector0<> >
  600. >::type arg_specs;
  601. typedef typename mpl::count_if<
  602. arg_specs
  603. , aux::is_optional<mpl::_>
  604. >::type optional_arity;
  605. typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
  606. aux::def_combinations(
  607. aux::def_class<Class, Options>(cl, name, options)
  608. , (arg_specs*)0
  609. , mpl::long_<0>()
  610. , mpl::long_<upper::value>()
  611. , (aux::make_member_invoker<
  612. Fwd, result_type, typename Class::wrapped_type
  613. >*)0
  614. );
  615. }
  616. };
  617. }}} // namespace boost::parameter::python
  618. #endif // BOOST_PARAMETER_PYTHON_060209_HPP