make_arg_list.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. // Copyright David Abrahams, Daniel Wallin 2003.
  2. // Copyright Cromwell D. Enage 2018.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_PARAMETER_AUX_PACK_MAKE_ARG_LIST_HPP
  7. #define BOOST_PARAMETER_AUX_PACK_MAKE_ARG_LIST_HPP
  8. namespace boost { namespace parameter { namespace aux {
  9. template <
  10. typename List
  11. , typename DeducedArgs
  12. , typename TagFn
  13. , typename IsPositional
  14. , typename UsedArgs
  15. , typename ArgumentPack
  16. , typename Error
  17. , typename EmitsErrors
  18. >
  19. struct make_arg_list_aux;
  20. }}} // namespace boost::parameter::aux
  21. #include <boost/parameter/aux_/arg_list.hpp>
  22. #include <boost/parameter/aux_/void.hpp>
  23. #include <boost/parameter/aux_/pack/unmatched_argument.hpp>
  24. #include <boost/parameter/aux_/pack/tag_type.hpp>
  25. #include <boost/parameter/aux_/pack/is_named_argument.hpp>
  26. #include <boost/parameter/aux_/pack/insert_tagged.hpp>
  27. #include <boost/parameter/aux_/pack/deduce_tag.hpp>
  28. #include <boost/parameter/deduced.hpp>
  29. #include <boost/parameter/config.hpp>
  30. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  31. #include <boost/mp11/integral.hpp>
  32. #include <boost/mp11/list.hpp>
  33. #include <boost/mp11/utility.hpp>
  34. #include <type_traits>
  35. #else
  36. #include <boost/mpl/bool.hpp>
  37. #include <boost/mpl/pair.hpp>
  38. #include <boost/mpl/if.hpp>
  39. #include <boost/mpl/eval_if.hpp>
  40. #include <boost/mpl/apply_wrap.hpp>
  41. #include <boost/mpl/identity.hpp>
  42. #include <boost/type_traits/is_same.hpp>
  43. #include <boost/type_traits/remove_const.hpp>
  44. #include <boost/type_traits/remove_reference.hpp>
  45. #endif
  46. namespace boost { namespace parameter { namespace aux {
  47. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  48. template <typename ArgumentPack, typename TaggedArg, typename EmitsErrors>
  49. struct append_to_make_arg_list
  50. {
  51. using type = ::boost::mp11::mp_push_front<
  52. ArgumentPack
  53. , ::boost::parameter::aux::flat_like_arg_tuple<
  54. typename TaggedArg::key_type
  55. , TaggedArg
  56. , EmitsErrors
  57. >
  58. >;
  59. };
  60. #endif
  61. // Borland needs the insane extra-indirection workaround below so that
  62. // it doesn't magically drop the const qualifier from the argument type.
  63. template <
  64. typename List
  65. , typename DeducedArgs
  66. , typename TagFn
  67. , typename IsPositional
  68. , typename UsedArgs
  69. , typename ArgumentPack
  70. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  71. , typename _argument
  72. #endif
  73. , typename Error
  74. , typename EmitsErrors
  75. >
  76. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  77. class make_arg_list00
  78. #else
  79. class make_arg_list0
  80. #endif
  81. {
  82. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  83. typedef typename List::arg _argument;
  84. #endif
  85. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  86. using _arg_type = typename ::std::remove_const<
  87. typename ::std::remove_reference<_argument>::type
  88. >::type;
  89. using _is_tagged = ::boost::parameter::aux
  90. ::is_named_argument<_argument>;
  91. #else
  92. typedef typename ::boost::remove_const<
  93. typename ::boost::remove_reference<_argument>::type
  94. >::type _arg_type;
  95. typedef ::boost::parameter::aux
  96. ::is_named_argument<_argument> _is_tagged;
  97. #endif
  98. typedef typename List::spec _parameter_spec;
  99. typedef typename ::boost::parameter::aux
  100. ::tag_type<_parameter_spec>::type _tag;
  101. // If this argument is either explicitly tagged or a deduced
  102. // parameter, then turn off positional matching.
  103. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  104. using _is_positional = ::boost::mp11::mp_if<
  105. IsPositional
  106. , ::boost::mp11::mp_if<
  107. ::boost::parameter::aux::is_deduced<_parameter_spec>
  108. , ::boost::mp11::mp_false
  109. , ::boost::mp11::mp_if<
  110. _is_tagged
  111. , ::boost::mp11::mp_false
  112. , ::boost::mp11::mp_true
  113. >
  114. >
  115. , ::boost::mp11::mp_false
  116. >;
  117. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  118. typedef typename ::boost::mpl::eval_if<
  119. IsPositional
  120. , ::boost::mpl::eval_if<
  121. ::boost::parameter::aux::is_deduced<_parameter_spec>
  122. , ::boost::mpl::false_
  123. , ::boost::mpl::if_<
  124. _is_tagged
  125. , ::boost::mpl::false_
  126. , ::boost::mpl::true_
  127. >
  128. >
  129. , ::boost::mpl::false_
  130. >::type _is_positional;
  131. #endif // BOOST_PARAMETER_CAN_USE_MP11
  132. // If this parameter is explicitly tagged, then add it to the
  133. // used-parmeters set. We only really need to add parameters
  134. // that are deduced, but we would need a way to check if
  135. // a given tag corresponds to a deduced parameter spec.
  136. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  137. using _used_args = typename ::boost::mp11::mp_if<
  138. _is_tagged
  139. , ::boost::parameter::aux::insert_tagged<UsedArgs,_arg_type>
  140. , ::boost::mp11::mp_identity<UsedArgs>
  141. >::type;
  142. #else
  143. typedef typename ::boost::mpl::eval_if<
  144. _is_tagged
  145. , ::boost::parameter::aux::insert_tagged<UsedArgs,_arg_type>
  146. , ::boost::mpl::identity<UsedArgs>
  147. >::type _used_args;
  148. #endif
  149. // If this parameter is neither explicitly tagged nor positionally
  150. // matched, then deduce the tag from the deduced parameter specs.
  151. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  152. using _deduced_data = typename ::boost::mp11::mp_if<
  153. ::boost::mp11::mp_if<
  154. _is_tagged
  155. , ::boost::mp11::mp_true
  156. , _is_positional
  157. >
  158. , ::boost::mp11::mp_identity<
  159. ::boost::mp11::mp_list< ::boost::parameter::void_,_used_args>
  160. >
  161. #else
  162. typedef typename ::boost::mpl::eval_if<
  163. typename ::boost::mpl::if_<
  164. _is_tagged
  165. , ::boost::mpl::true_
  166. , _is_positional
  167. >::type
  168. , ::boost::mpl::pair< ::boost::parameter::void_,_used_args>
  169. #endif
  170. , ::boost::parameter::aux::deduce_tag<
  171. _argument
  172. , ArgumentPack
  173. , DeducedArgs
  174. , _used_args
  175. , TagFn
  176. , EmitsErrors
  177. >
  178. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  179. >::type;
  180. #else
  181. >::type _deduced_data;
  182. #endif
  183. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  184. // If this parameter is explicitly tagged ...
  185. using _tagged = ::boost::mp11::mp_if<
  186. _is_tagged
  187. // ... just use it
  188. , _arg_type
  189. // ... else ...
  190. , ::boost::mp11::mp_if<
  191. // if positional matching is turned on ...
  192. _is_positional
  193. // ... tag it positionally
  194. , ::boost::mp11::mp_apply_q<
  195. TagFn
  196. , ::boost::mp11::mp_list<_tag,_argument>
  197. >
  198. // ... else, use the deduced tag
  199. , ::boost::mp11::mp_at_c<_deduced_data,0>
  200. >
  201. >;
  202. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  203. // If this parameter is explicitly tagged ...
  204. typedef typename ::boost::mpl::eval_if<
  205. _is_tagged
  206. // ... just use it
  207. , ::boost::mpl::identity<_arg_type>
  208. // ... else ...
  209. , ::boost::mpl::eval_if<
  210. // if positional matching is turned on ...
  211. _is_positional
  212. // ... tag it positionally
  213. , ::boost::mpl::apply_wrap2<TagFn,_tag,_argument>
  214. // ... else, use the deduced tag
  215. , ::boost::mpl::first<_deduced_data>
  216. >
  217. >::type _tagged;
  218. #endif // BOOST_PARAMETER_CAN_USE_MP11
  219. // Build the arg_list incrementally, prepending new nodes.
  220. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  221. using _error = ::boost::mp11::mp_if<
  222. ::boost::mp11::mp_if<
  223. ::std::is_same<Error,::boost::parameter::void_>
  224. , ::std::is_same<_tagged,::boost::parameter::void_>
  225. , ::boost::mp11::mp_false
  226. >
  227. #else
  228. typedef typename ::boost::mpl::if_<
  229. typename ::boost::mpl::if_<
  230. ::boost::is_same<Error,::boost::parameter::void_>
  231. , ::boost::is_same<_tagged,::boost::parameter::void_>
  232. , ::boost::mpl::false_
  233. >::type
  234. #endif
  235. , ::boost::parameter::aux::unmatched_argument<_argument>
  236. , ::boost::parameter::void_
  237. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  238. >;
  239. #else
  240. >::type _error;
  241. #endif
  242. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  243. using _argument_pack = typename ::boost::mp11::mp_if<
  244. ::std::is_same<_tagged,::boost::parameter::void_>
  245. , ::boost::mp11::mp_identity<ArgumentPack>
  246. , ::boost::parameter::aux
  247. ::append_to_make_arg_list<ArgumentPack,_tagged,EmitsErrors>
  248. >::type;
  249. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  250. typedef typename ::boost::mpl::if_<
  251. ::boost::is_same<_tagged,::boost::parameter::void_>
  252. , ArgumentPack
  253. #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  254. , ::boost::parameter::aux::arg_list<_tagged,ArgumentPack>
  255. #else
  256. , ::boost::parameter::aux
  257. ::arg_list<_tagged,ArgumentPack,EmitsErrors>
  258. #endif
  259. >::type _argument_pack;
  260. #endif // BOOST_PARAMETER_CAN_USE_MP11
  261. public:
  262. typedef typename ::boost::parameter::aux::make_arg_list_aux<
  263. typename List::tail
  264. , DeducedArgs
  265. , TagFn
  266. , _is_positional
  267. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  268. , ::boost::mp11::mp_at_c<_deduced_data,1>
  269. #else
  270. , typename _deduced_data::second
  271. #endif
  272. , _argument_pack
  273. , _error
  274. , EmitsErrors
  275. >::type type;
  276. };
  277. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  278. template <
  279. typename List
  280. , typename DeducedArgs
  281. , typename TagFn
  282. , typename IsPositional
  283. , typename UsedArgs
  284. , typename ArgumentPack
  285. , typename Error
  286. , typename EmitsErrors
  287. >
  288. struct make_arg_list0
  289. {
  290. typedef typename ::boost::mpl::eval_if<
  291. typename List::is_arg_const
  292. , ::boost::parameter::aux::make_arg_list00<
  293. List
  294. , DeducedArgs
  295. , TagFn
  296. , IsPositional
  297. , UsedArgs
  298. , ArgumentPack
  299. , typename List::arg const
  300. , Error
  301. , EmitsErrors
  302. >
  303. , ::boost::parameter::aux::make_arg_list00<
  304. List
  305. , DeducedArgs
  306. , TagFn
  307. , IsPositional
  308. , UsedArgs
  309. , ArgumentPack
  310. , typename List::arg
  311. , Error
  312. , EmitsErrors
  313. >
  314. >::type type;
  315. };
  316. #endif // Borland workarounds needed.
  317. // Returns an ArgumentPack where the list of arguments has been tagged
  318. // with keyword tags.
  319. //
  320. // List: A specialization of item<> (see below). Contains both
  321. // the ordered ParameterSpecs, and the given arguments.
  322. //
  323. // DeducedArgs: A specialization of deduced_item<> (see below).
  324. // A list containing only the deduced ParameterSpecs.
  325. //
  326. // TagFn: A metafunction class used to tag positional or deduced
  327. // arguments with a keyword tag.
  328. //
  329. // IsPositional: An mpl::bool_<> specialization indicating if positional
  330. // matching is to be performed.
  331. //
  332. // DeducedSet: An mpl::set<> containing the keyword tags used so far.
  333. //
  334. // ArgumentPack: The ArgumentPack built so far. This is initially an
  335. // empty_arg_list and is built incrementally.
  336. template <
  337. typename List
  338. , typename DeducedArgs
  339. , typename TagFn
  340. , typename IsPositional
  341. , typename DeducedSet
  342. , typename ArgumentPack
  343. , typename Error
  344. , typename EmitsErrors
  345. >
  346. struct make_arg_list_aux
  347. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  348. : ::boost::mp11::mp_if<
  349. ::std::is_same<List,::boost::parameter::void_>
  350. , ::boost::mp11::mp_identity<
  351. ::boost::mp11::mp_list<ArgumentPack,Error>
  352. >
  353. #else
  354. : ::boost::mpl::eval_if<
  355. ::boost::is_same<List,::boost::parameter::void_>
  356. , ::boost::mpl::identity< ::boost::mpl::pair<ArgumentPack,Error> >
  357. #endif
  358. , ::boost::parameter::aux::make_arg_list0<
  359. List
  360. , DeducedArgs
  361. , TagFn
  362. , IsPositional
  363. , DeducedSet
  364. , ArgumentPack
  365. , Error
  366. , EmitsErrors
  367. >
  368. >
  369. {
  370. };
  371. }}} // namespace boost::parameter::aux
  372. #include <boost/parameter/aux_/set.hpp>
  373. namespace boost { namespace parameter { namespace aux {
  374. // VC6.5 was choking on the default parameters for make_arg_list_aux,
  375. // so this just forwards to that adding in the defaults.
  376. template <
  377. typename List
  378. , typename DeducedArgs
  379. , typename TagFn
  380. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  381. , typename EmitsErrors = ::boost::mp11::mp_true
  382. #else
  383. , typename EmitsErrors = ::boost::mpl::true_
  384. #endif
  385. >
  386. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  387. using make_arg_list = ::boost::parameter::aux::make_arg_list_aux<
  388. #else
  389. struct make_arg_list
  390. : ::boost::parameter::aux::make_arg_list_aux<
  391. #endif
  392. List
  393. , DeducedArgs
  394. , TagFn
  395. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  396. , ::boost::mp11::mp_true
  397. #else
  398. , ::boost::mpl::true_
  399. #endif
  400. , ::boost::parameter::aux::set0
  401. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  402. , ::boost::parameter::aux::flat_like_arg_list<>
  403. #else
  404. , ::boost::parameter::aux::empty_arg_list
  405. #endif
  406. , ::boost::parameter::void_
  407. , EmitsErrors
  408. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  409. >;
  410. #else
  411. >
  412. {
  413. };
  414. #endif
  415. }}} // namespace boost::parameter::aux
  416. #endif // include guard