named_function_params.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
  10. #define BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
  11. #include <functional>
  12. #include <vector>
  13. #include <boost/limits.hpp>
  14. #include <boost/ref.hpp>
  15. #include <boost/utility/result_of.hpp>
  16. #include <boost/preprocessor.hpp>
  17. #include <boost/parameter/name.hpp>
  18. #include <boost/parameter/binding.hpp>
  19. #include <boost/type_traits.hpp>
  20. #include <boost/mpl/not.hpp>
  21. #include <boost/graph/properties.hpp>
  22. #include <boost/graph/detail/d_ary_heap.hpp>
  23. #include <boost/property_map/property_map.hpp>
  24. #include <boost/property_map/shared_array_property_map.hpp>
  25. namespace boost {
  26. struct parity_map_t { };
  27. struct vertex_assignment_map_t { };
  28. struct distance_compare_t { };
  29. struct distance_combine_t { };
  30. struct distance_inf_t { };
  31. struct distance_zero_t { };
  32. struct buffer_param_t { };
  33. struct edge_copy_t { };
  34. struct vertex_copy_t { };
  35. struct vertex_isomorphism_t { };
  36. struct vertex_invariant_t { };
  37. struct vertex_invariant1_t { };
  38. struct vertex_invariant2_t { };
  39. struct edge_compare_t { };
  40. struct vertex_max_invariant_t { };
  41. struct orig_to_copy_t { };
  42. struct root_vertex_t { };
  43. struct polling_t { };
  44. struct lookahead_t { };
  45. struct in_parallel_t { };
  46. struct attractive_force_t { };
  47. struct repulsive_force_t { };
  48. struct force_pairs_t { };
  49. struct cooling_t { };
  50. struct vertex_displacement_t { };
  51. struct iterations_t { };
  52. struct diameter_range_t { };
  53. struct learning_constant_range_t { };
  54. struct vertices_equivalent_t { };
  55. struct edges_equivalent_t { };
  56. struct index_in_heap_map_t { };
  57. struct max_priority_queue_t { };
  58. #define BOOST_BGL_DECLARE_NAMED_PARAMS \
  59. BOOST_BGL_ONE_PARAM_CREF(weight_map, edge_weight) \
  60. BOOST_BGL_ONE_PARAM_CREF(weight_map2, edge_weight2) \
  61. BOOST_BGL_ONE_PARAM_CREF(distance_map, vertex_distance) \
  62. BOOST_BGL_ONE_PARAM_CREF(distance_map2, vertex_distance2) \
  63. BOOST_BGL_ONE_PARAM_CREF(predecessor_map, vertex_predecessor) \
  64. BOOST_BGL_ONE_PARAM_CREF(rank_map, vertex_rank) \
  65. BOOST_BGL_ONE_PARAM_CREF(root_map, vertex_root) \
  66. BOOST_BGL_ONE_PARAM_CREF(root_vertex, root_vertex) \
  67. BOOST_BGL_ONE_PARAM_CREF(edge_centrality_map, edge_centrality) \
  68. BOOST_BGL_ONE_PARAM_CREF(centrality_map, vertex_centrality) \
  69. BOOST_BGL_ONE_PARAM_CREF(parity_map, parity_map) \
  70. BOOST_BGL_ONE_PARAM_CREF(color_map, vertex_color) \
  71. BOOST_BGL_ONE_PARAM_CREF(edge_color_map, edge_color) \
  72. BOOST_BGL_ONE_PARAM_CREF(capacity_map, edge_capacity) \
  73. BOOST_BGL_ONE_PARAM_CREF(residual_capacity_map, edge_residual_capacity) \
  74. BOOST_BGL_ONE_PARAM_CREF(reverse_edge_map, edge_reverse) \
  75. BOOST_BGL_ONE_PARAM_CREF(discover_time_map, vertex_discover_time) \
  76. BOOST_BGL_ONE_PARAM_CREF(lowpoint_map, vertex_lowpoint) \
  77. BOOST_BGL_ONE_PARAM_CREF(vertex_index_map, vertex_index) \
  78. BOOST_BGL_ONE_PARAM_CREF(vertex_index1_map, vertex_index1) \
  79. BOOST_BGL_ONE_PARAM_CREF(vertex_index2_map, vertex_index2) \
  80. BOOST_BGL_ONE_PARAM_CREF(vertex_assignment_map, vertex_assignment_map) \
  81. BOOST_BGL_ONE_PARAM_CREF(visitor, graph_visitor) \
  82. BOOST_BGL_ONE_PARAM_CREF(distance_compare, distance_compare) \
  83. BOOST_BGL_ONE_PARAM_CREF(distance_combine, distance_combine) \
  84. BOOST_BGL_ONE_PARAM_CREF(distance_inf, distance_inf) \
  85. BOOST_BGL_ONE_PARAM_CREF(distance_zero, distance_zero) \
  86. BOOST_BGL_ONE_PARAM_CREF(edge_copy, edge_copy) \
  87. BOOST_BGL_ONE_PARAM_CREF(vertex_copy, vertex_copy) \
  88. BOOST_BGL_ONE_PARAM_REF(buffer, buffer_param) \
  89. BOOST_BGL_ONE_PARAM_CREF(orig_to_copy, orig_to_copy) \
  90. BOOST_BGL_ONE_PARAM_CREF(isomorphism_map, vertex_isomorphism) \
  91. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant, vertex_invariant) \
  92. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant1, vertex_invariant1) \
  93. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant2, vertex_invariant2) \
  94. BOOST_BGL_ONE_PARAM_CREF(vertex_max_invariant, vertex_max_invariant) \
  95. BOOST_BGL_ONE_PARAM_CREF(polling, polling) \
  96. BOOST_BGL_ONE_PARAM_CREF(lookahead, lookahead) \
  97. BOOST_BGL_ONE_PARAM_CREF(in_parallel, in_parallel) \
  98. BOOST_BGL_ONE_PARAM_CREF(displacement_map, vertex_displacement) \
  99. BOOST_BGL_ONE_PARAM_CREF(attractive_force, attractive_force) \
  100. BOOST_BGL_ONE_PARAM_CREF(repulsive_force, repulsive_force) \
  101. BOOST_BGL_ONE_PARAM_CREF(force_pairs, force_pairs) \
  102. BOOST_BGL_ONE_PARAM_CREF(cooling, cooling) \
  103. BOOST_BGL_ONE_PARAM_CREF(iterations, iterations) \
  104. BOOST_BGL_ONE_PARAM_CREF(diameter_range, diameter_range) \
  105. BOOST_BGL_ONE_PARAM_CREF(learning_constant_range, learning_constant_range) \
  106. BOOST_BGL_ONE_PARAM_CREF(vertices_equivalent, vertices_equivalent) \
  107. BOOST_BGL_ONE_PARAM_CREF(edges_equivalent, edges_equivalent) \
  108. BOOST_BGL_ONE_PARAM_CREF(index_in_heap_map, index_in_heap_map) \
  109. BOOST_BGL_ONE_PARAM_REF(max_priority_queue, max_priority_queue)
  110. template <typename T, typename Tag, typename Base = no_property>
  111. struct bgl_named_params
  112. {
  113. typedef bgl_named_params self;
  114. typedef Base next_type;
  115. typedef Tag tag_type;
  116. typedef T value_type;
  117. bgl_named_params(T v = T()) : m_value(v) { }
  118. bgl_named_params(T v, const Base& b) : m_value(v), m_base(b) { }
  119. T m_value;
  120. Base m_base;
  121. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  122. template <typename PType> \
  123. bgl_named_params<boost::reference_wrapper<PType>, BOOST_PP_CAT(key, _t), self> \
  124. name(PType& p) const { \
  125. typedef bgl_named_params<boost::reference_wrapper<PType>, BOOST_PP_CAT(key, _t), self> Params; \
  126. return Params(boost::ref(p), *this); \
  127. } \
  128. #define BOOST_BGL_ONE_PARAM_CREF(name, key) \
  129. template <typename PType> \
  130. bgl_named_params<PType, BOOST_PP_CAT(key, _t), self> \
  131. name(const PType& p) const { \
  132. typedef bgl_named_params<PType, BOOST_PP_CAT(key, _t), self> Params; \
  133. return Params(p, *this); \
  134. } \
  135. BOOST_BGL_DECLARE_NAMED_PARAMS
  136. #undef BOOST_BGL_ONE_PARAM_REF
  137. #undef BOOST_BGL_ONE_PARAM_CREF
  138. // Duplicate
  139. template <typename PType>
  140. bgl_named_params<PType, vertex_color_t, self>
  141. vertex_color_map(const PType& p) const {return this->color_map(p);}
  142. };
  143. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  144. template <typename PType> \
  145. bgl_named_params<boost::reference_wrapper<PType>, BOOST_PP_CAT(key, _t)> \
  146. name(PType& p) { \
  147. typedef bgl_named_params<boost::reference_wrapper<PType>, BOOST_PP_CAT(key, _t)> Params; \
  148. return Params(boost::ref(p)); \
  149. } \
  150. #define BOOST_BGL_ONE_PARAM_CREF(name, key) \
  151. template <typename PType> \
  152. bgl_named_params<PType, BOOST_PP_CAT(key, _t)> \
  153. name(const PType& p) { \
  154. typedef bgl_named_params<PType, BOOST_PP_CAT(key, _t)> Params; \
  155. return Params(p); \
  156. } \
  157. BOOST_BGL_DECLARE_NAMED_PARAMS
  158. #undef BOOST_BGL_ONE_PARAM_REF
  159. #undef BOOST_BGL_ONE_PARAM_CREF
  160. // Duplicate
  161. template <typename PType>
  162. bgl_named_params<PType, vertex_color_t>
  163. vertex_color_map(const PType& p) {return color_map(p);}
  164. namespace detail {
  165. struct unused_tag_type {};
  166. }
  167. typedef bgl_named_params<char, detail::unused_tag_type> no_named_parameters;
  168. //===========================================================================
  169. // Functions for extracting parameters from bgl_named_params
  170. template <typename Tag, typename Args>
  171. struct lookup_named_param {};
  172. template <typename T, typename Tag, typename Base>
  173. struct lookup_named_param<Tag, bgl_named_params<T, Tag, Base> > {
  174. typedef T type;
  175. static const T& get(const bgl_named_params<T, Tag, Base>& p) {
  176. return p.m_value;
  177. }
  178. };
  179. template <typename Tag1, typename T, typename Tag, typename Base>
  180. struct lookup_named_param<Tag1, bgl_named_params<T, Tag, Base> > {
  181. typedef typename lookup_named_param<Tag1, Base>::type type;
  182. static const type& get(const bgl_named_params<T, Tag, Base>& p) {
  183. return lookup_named_param<Tag1, Base>::get(p.m_base);
  184. }
  185. };
  186. template <typename Tag, typename Args, typename Def>
  187. struct lookup_named_param_def {
  188. typedef Def type;
  189. static const Def& get(const Args&, const Def& def) {return def;}
  190. };
  191. template <typename T, typename Tag, typename Base, typename Def>
  192. struct lookup_named_param_def<Tag, bgl_named_params<T, Tag, Base>, Def> {
  193. typedef T type;
  194. static const type& get(const bgl_named_params<T, Tag, Base>& p, const Def&) {
  195. return p.m_value;
  196. }
  197. };
  198. template <typename Tag1, typename T, typename Tag, typename Base, typename Def>
  199. struct lookup_named_param_def<Tag1, bgl_named_params<T, Tag, Base>, Def> {
  200. typedef typename lookup_named_param_def<Tag1, Base, Def>::type type;
  201. static const type& get(const bgl_named_params<T, Tag, Base>& p, const Def& def) {
  202. return lookup_named_param_def<Tag1, Base, Def>::get(p.m_base, def);
  203. }
  204. };
  205. struct param_not_found {};
  206. template <typename Tag, typename Args>
  207. struct get_param_type:
  208. lookup_named_param_def<Tag, Args, param_not_found> {};
  209. template <class Tag, typename Args>
  210. inline
  211. const typename lookup_named_param_def<Tag, Args, param_not_found>::type&
  212. get_param(const Args& p, Tag) {
  213. return lookup_named_param_def<Tag, Args, param_not_found>::get(p, param_not_found());
  214. }
  215. template <class P, class Default>
  216. const P& choose_param(const P& param, const Default&) {
  217. return param;
  218. }
  219. template <class Default>
  220. Default choose_param(const param_not_found&, const Default& d) {
  221. return d;
  222. }
  223. template <typename T>
  224. inline bool is_default_param(const T&) { return false; }
  225. inline bool is_default_param(const param_not_found&)
  226. { return true; }
  227. namespace detail {
  228. template <typename T>
  229. struct const_type_as_type {typedef typename T::const_type type;};
  230. } // namespace detail
  231. // Use this function instead of choose_param() when you want
  232. // to avoid requiring get(tag, g) when it is not used.
  233. namespace detail {
  234. template <typename GraphIsConst, typename Graph, typename Param, typename Tag>
  235. struct choose_impl_result:
  236. boost::mpl::eval_if<
  237. boost::is_same<Param, param_not_found>,
  238. boost::mpl::eval_if<
  239. GraphIsConst,
  240. detail::const_type_as_type<property_map<Graph, Tag> >,
  241. property_map<Graph, Tag> >,
  242. boost::mpl::identity<Param> > {};
  243. // Parameters of f are (GraphIsConst, Graph, Param, Tag)
  244. template <bool Found> struct choose_impl_helper;
  245. template <> struct choose_impl_helper<false> {
  246. template <typename Param, typename Graph, typename PropertyTag>
  247. static typename property_map<typename boost::remove_const<Graph>::type, PropertyTag>::const_type
  248. f(boost::mpl::true_, const Graph& g, const Param&, PropertyTag tag) {
  249. return get(tag, g);
  250. }
  251. template <typename Param, typename Graph, typename PropertyTag>
  252. static typename property_map<typename boost::remove_const<Graph>::type, PropertyTag>::type
  253. f(boost::mpl::false_, Graph& g, const Param&, PropertyTag tag) {
  254. return get(tag, g);
  255. }
  256. };
  257. template <> struct choose_impl_helper<true> {
  258. template <typename GraphIsConst, typename Param, typename Graph, typename PropertyTag>
  259. static Param f(GraphIsConst, const Graph&, const Param& p, PropertyTag) {
  260. return p;
  261. }
  262. };
  263. }
  264. template <typename Param, typename Graph, typename PropertyTag>
  265. typename detail::choose_impl_result<boost::mpl::true_, Graph, Param, PropertyTag>::type
  266. choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
  267. {
  268. return detail::choose_impl_helper<!boost::is_same<Param, param_not_found>::value>
  269. ::f(boost::mpl::true_(), g, p, tag);
  270. }
  271. template <typename Param, typename Graph, typename PropertyTag>
  272. typename detail::choose_impl_result<boost::mpl::false_, Graph, Param, PropertyTag>::type
  273. choose_pmap(const Param& p, Graph& g, PropertyTag tag)
  274. {
  275. return detail::choose_impl_helper<!boost::is_same<Param, param_not_found>::value>
  276. ::f(boost::mpl::false_(), g, p, tag);
  277. }
  278. namespace detail {
  279. // used in the max-flow algorithms
  280. template <class Graph, class P, class T, class R>
  281. struct edge_capacity_value
  282. {
  283. typedef bgl_named_params<P, T, R> Params;
  284. typedef typename detail::choose_impl_result<boost::mpl::true_, Graph, typename get_param_type<Params, edge_capacity_t>::type, edge_capacity_t>::type CapacityEdgeMap;
  285. typedef typename property_traits<CapacityEdgeMap>::value_type type;
  286. };
  287. }
  288. // Declare all new tags
  289. namespace graph {
  290. namespace keywords {
  291. #define BOOST_BGL_ONE_PARAM_REF(name, key) BOOST_PARAMETER_NAME(name)
  292. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_PARAMETER_NAME(name)
  293. BOOST_BGL_DECLARE_NAMED_PARAMS
  294. #undef BOOST_BGL_ONE_PARAM_REF
  295. #undef BOOST_BGL_ONE_PARAM_CREF
  296. }
  297. }
  298. namespace detail {
  299. template <typename Tag> struct convert_one_keyword {};
  300. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  301. template <> \
  302. struct convert_one_keyword<BOOST_PP_CAT(key, _t)> { \
  303. typedef boost::graph::keywords::tag::name type; \
  304. };
  305. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_BGL_ONE_PARAM_REF(name, key)
  306. BOOST_BGL_DECLARE_NAMED_PARAMS
  307. #undef BOOST_BGL_ONE_PARAM_REF
  308. #undef BOOST_BGL_ONE_PARAM_CREF
  309. template <typename T>
  310. struct convert_bgl_params_to_boost_parameter {
  311. typedef typename convert_one_keyword<typename T::tag_type>::type new_kw;
  312. typedef boost::parameter::aux::tagged_argument<new_kw, const typename T::value_type> tagged_arg_type;
  313. typedef convert_bgl_params_to_boost_parameter<typename T::next_type> rest_conv;
  314. typedef boost::parameter::aux::arg_list<tagged_arg_type, typename rest_conv::type> type;
  315. static type conv(const T& x) {
  316. return type(tagged_arg_type(x.m_value), rest_conv::conv(x.m_base));
  317. }
  318. };
  319. template <typename P, typename R>
  320. struct convert_bgl_params_to_boost_parameter<bgl_named_params<P, int, R> > {
  321. typedef convert_bgl_params_to_boost_parameter<R> rest_conv;
  322. typedef typename rest_conv::type type;
  323. static type conv(const bgl_named_params<P, int, R>& x) {
  324. return rest_conv::conv(x.m_base);
  325. }
  326. };
  327. template <>
  328. struct convert_bgl_params_to_boost_parameter<boost::no_property> {
  329. typedef boost::parameter::aux::empty_arg_list type;
  330. static type conv(const boost::no_property&) {return type();}
  331. };
  332. template <>
  333. struct convert_bgl_params_to_boost_parameter<boost::no_named_parameters> {
  334. typedef boost::parameter::aux::empty_arg_list type;
  335. static type conv(const boost::no_named_parameters&) {return type();}
  336. };
  337. struct bgl_parameter_not_found_type {};
  338. template <typename ArgPack, typename KeywordType>
  339. struct parameter_exists : boost::mpl::not_<boost::is_same<typename boost::parameter::binding<ArgPack, KeywordType, bgl_parameter_not_found_type>::type, bgl_parameter_not_found_type> > {};
  340. }
  341. #define BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(old_type, old_var) \
  342. typedef typename boost::detail::convert_bgl_params_to_boost_parameter<old_type>::type arg_pack_type; \
  343. arg_pack_type arg_pack = boost::detail::convert_bgl_params_to_boost_parameter<old_type>::conv(old_var);
  344. namespace detail {
  345. template <typename ArgType, typename Prop, typename Graph, bool Exists>
  346. struct override_const_property_t {
  347. typedef typename boost::remove_const<ArgType>::type result_type;
  348. result_type operator()(const Graph&, const ArgType& a) const {return a;}
  349. };
  350. template <typename ArgType, typename Prop, typename Graph>
  351. struct override_const_property_t<ArgType, Prop, Graph, false> {
  352. typedef typename boost::property_map<Graph, Prop>::const_type result_type;
  353. result_type operator()(const Graph& g, const ArgType&) const {return get(Prop(), g);}
  354. };
  355. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  356. struct override_const_property_result {
  357. typedef
  358. typename override_const_property_t<
  359. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  360. Prop,
  361. Graph,
  362. boost::detail::parameter_exists<ArgPack, Tag>::value
  363. >::result_type
  364. type;
  365. };
  366. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  367. typename override_const_property_result<ArgPack, Tag, Prop, Graph>::type
  368. override_const_property(const ArgPack& ap, const boost::parameter::keyword<Tag>& t, const Graph& g, Prop) {
  369. return override_const_property_t<
  370. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  371. Prop,
  372. Graph,
  373. boost::detail::parameter_exists<ArgPack, Tag>::value
  374. >()(g, ap[t | 0]);
  375. }
  376. template <typename ArgType, typename Prop, typename Graph, bool Exists>
  377. struct override_property_t {
  378. typedef ArgType result_type;
  379. result_type operator()(const Graph&, const typename boost::add_reference<ArgType>::type a) const {return a;}
  380. };
  381. template <typename ArgType, typename Prop, typename Graph>
  382. struct override_property_t<ArgType, Prop, Graph, false> {
  383. typedef typename boost::property_map<Graph, Prop>::type result_type;
  384. result_type operator()(const Graph& g, const ArgType&) const {return get(Prop(), g);}
  385. };
  386. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  387. struct override_property_result {
  388. typedef
  389. typename override_property_t<
  390. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  391. Prop,
  392. Graph,
  393. boost::detail::parameter_exists<ArgPack, Tag>::value
  394. >::result_type
  395. type;
  396. };
  397. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  398. typename override_property_result<ArgPack, Tag, Prop, Graph>::type
  399. override_property(const ArgPack& ap, const boost::parameter::keyword<Tag>& t, const Graph& g, Prop) {
  400. return override_property_t<
  401. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  402. Prop,
  403. Graph,
  404. boost::detail::parameter_exists<ArgPack, Tag>::value
  405. >()(g, ap[t | 0]);
  406. }
  407. template <typename F> struct make_arg_pack_type;
  408. template <> struct make_arg_pack_type<void()> {typedef boost::parameter::aux::empty_arg_list type;};
  409. template <typename K, typename A>
  410. struct make_arg_pack_type<void(K, A)> {
  411. typedef boost::parameter::aux::tagged_argument<K, A> type;
  412. };
  413. #define BOOST_GRAPH_OPENING_PART_OF_PAIR(z, i, n) boost::parameter::aux::arg_list<boost::parameter::aux::tagged_argument<BOOST_PP_CAT(Keyword, BOOST_PP_SUB(n, i)), BOOST_PP_CAT(Arg, BOOST_PP_SUB(n, i))>,
  414. #define BOOST_GRAPH_MAKE_PAIR_PARAM(z, i, _) const boost::parameter::aux::tagged_argument<BOOST_PP_CAT(Keyword, i), BOOST_PP_CAT(Arg, i)>& BOOST_PP_CAT(kw, i)
  415. #define BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION(z, i, _) \
  416. template <BOOST_PP_ENUM_PARAMS(i, typename Keyword), BOOST_PP_ENUM_PARAMS(i, typename Arg)> \
  417. struct make_arg_pack_type<void(BOOST_PP_ENUM_PARAMS(i, Keyword), BOOST_PP_ENUM_PARAMS(i, Arg))> { \
  418. typedef \
  419. BOOST_PP_REPEAT(i, BOOST_GRAPH_OPENING_PART_OF_PAIR, BOOST_PP_DEC(i)) boost::parameter::aux::empty_arg_list BOOST_PP_REPEAT(i, > BOOST_PP_TUPLE_EAT(3), ~) \
  420. type; \
  421. };
  422. BOOST_PP_REPEAT_FROM_TO(2, 11, BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION, ~)
  423. #undef BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION
  424. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(name, nfixed, nnamed_max) \
  425. /* Entry point for conversion from BGL-style named parameters */ \
  426. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_COMMA_IF(nfixed) typename ArgPack> \
  427. typename boost::result_of< \
  428. detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)>(BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) const ArgPack&) \
  429. >::type \
  430. BOOST_PP_CAT(name, _with_named_params)(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param) BOOST_PP_COMMA_IF(nfixed) const ArgPack& arg_pack) { \
  431. return detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)>()(BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) arg_pack); \
  432. } \
  433. /* Individual functions taking Boost.Parameter-style keyword arguments */ \
  434. BOOST_PP_REPEAT(BOOST_PP_INC(nnamed_max), BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE, (name)(nfixed))
  435. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE(z, nnamed, seq) \
  436. BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX(z, nnamed, BOOST_PP_SEQ_ELEM(0, seq), BOOST_PP_SEQ_ELEM(1, seq))
  437. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX(z, nnamed, name, nfixed) \
  438. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, typename Keyword) BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, typename Arg)> \
  439. typename boost::result_of< \
  440. detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)> \
  441. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) \
  442. const typename boost::detail::make_arg_pack_type<void(BOOST_PP_ENUM_PARAMS(nnamed, Keyword) BOOST_PP_COMMA_IF(nnamed) BOOST_PP_ENUM_PARAMS(nnamed, Arg))>::type&) \
  443. >::type \
  444. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param) \
  445. BOOST_PP_ENUM_TRAILING(nnamed, BOOST_GRAPH_MAKE_PAIR_PARAM, ~)) { \
  446. return detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)>() \
  447. (BOOST_PP_ENUM_PARAMS(nfixed, param), \
  448. (boost::parameter::aux::empty_arg_list() BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, kw))); \
  449. }
  450. #define BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(name, nfixed) \
  451. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_COMMA_IF(nfixed) class P, class T, class R> \
  452. typename boost::result_of< \
  453. ::boost::graph::detail::BOOST_PP_CAT(name, _impl) BOOST_PP_EXPR_IF(nfixed, <) BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_EXPR_IF(nfixed, >) \
  454. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) \
  455. const typename boost::detail::convert_bgl_params_to_boost_parameter<boost::bgl_named_params<P, T, R> >::type &) \
  456. >::type \
  457. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param) BOOST_PP_COMMA_IF(nfixed) const boost::bgl_named_params<P, T, R>& old_style_params) { \
  458. typedef boost::bgl_named_params<P, T, R> old_style_params_type; \
  459. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(old_style_params_type, old_style_params) \
  460. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)(BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) arg_pack); \
  461. } \
  462. \
  463. BOOST_PP_EXPR_IF(nfixed, template <) BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_EXPR_IF(nfixed, >) \
  464. BOOST_PP_EXPR_IF(nfixed, typename) boost::result_of< \
  465. ::boost::graph::detail::BOOST_PP_CAT(name, _impl) BOOST_PP_EXPR_IF(nfixed, <) BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_EXPR_IF(nfixed, >) \
  466. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) const boost::parameter::aux::empty_arg_list &) \
  467. >::type \
  468. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param)) { \
  469. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(boost::no_named_parameters, boost::no_named_parameters()) \
  470. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)(BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) arg_pack); \
  471. }
  472. }
  473. namespace detail {
  474. template <bool Exists, typename Graph, typename ArgPack, typename Value, typename PM>
  475. struct map_maker_helper {
  476. typedef PM map_type;
  477. static PM make_map(const Graph&, Value, const PM& pm, const ArgPack&) {
  478. return pm;
  479. }
  480. };
  481. template <typename Graph, typename ArgPack, typename Value, typename PM>
  482. struct map_maker_helper<false, Graph, ArgPack, Value, PM> {
  483. typedef typename boost::remove_const<
  484. typename override_const_property_t<
  485. typename boost::parameter::value_type<
  486. ArgPack, boost::graph::keywords::tag::vertex_index_map, int>::type,
  487. boost::vertex_index_t,
  488. Graph,
  489. boost::detail::parameter_exists<
  490. ArgPack, boost::graph::keywords::tag::vertex_index_map>::value
  491. >::result_type>::type vi_map_type;
  492. typedef
  493. boost::shared_array_property_map<Value, vi_map_type>
  494. map_type;
  495. static map_type make_map(const Graph& g,
  496. Value v,
  497. const PM&,
  498. const ArgPack& ap) {
  499. return make_shared_array_property_map(
  500. num_vertices(g),
  501. v,
  502. override_const_property(
  503. ap,
  504. boost::graph::keywords::_vertex_index_map,
  505. g, vertex_index));
  506. }
  507. };
  508. template <typename Graph, typename ArgPack, typename MapTag, typename ValueType>
  509. struct map_maker {
  510. BOOST_STATIC_CONSTANT(
  511. bool,
  512. has_map =
  513. (parameter_exists<ArgPack, MapTag>
  514. ::value));
  515. typedef map_maker_helper<has_map, Graph, ArgPack, ValueType,
  516. typename boost::remove_const<
  517. typename boost::parameter::value_type<
  518. ArgPack,
  519. MapTag,
  520. int
  521. >::type
  522. >::type> helper;
  523. typedef typename helper::map_type map_type;
  524. static map_type make_map(const Graph& g, const ArgPack& ap, ValueType default_value) {
  525. return helper::make_map(g, default_value, ap[::boost::parameter::keyword<MapTag>::instance | 0], ap);
  526. }
  527. };
  528. template <typename MapTag, typename ValueType = void>
  529. class make_property_map_from_arg_pack_gen {
  530. ValueType default_value;
  531. public:
  532. make_property_map_from_arg_pack_gen(ValueType default_value)
  533. : default_value(default_value) {}
  534. template <typename Graph, typename ArgPack>
  535. typename map_maker<Graph, ArgPack, MapTag, ValueType>::map_type
  536. operator()(const Graph& g, const ArgPack& ap) const {
  537. return map_maker<Graph, ArgPack, MapTag, ValueType>::make_map(g, ap, default_value);
  538. }
  539. };
  540. template <typename MapTag>
  541. class make_property_map_from_arg_pack_gen<MapTag, void> {
  542. public:
  543. template <typename ValueType, typename Graph, typename ArgPack>
  544. typename map_maker<Graph, ArgPack, MapTag, ValueType>::map_type
  545. operator()(const Graph& g, const ArgPack& ap, ValueType default_value) const {
  546. return map_maker<Graph, ArgPack, MapTag, ValueType>::make_map(g, ap, default_value);
  547. }
  548. };
  549. static const
  550. make_property_map_from_arg_pack_gen<
  551. boost::graph::keywords::tag::color_map,
  552. default_color_type>
  553. make_color_map_from_arg_pack(white_color);
  554. template <bool Exists, class Graph, class ArgPack, class KeyT, class ValueT, class KeyMapTag, class IndexInHeapMapTag, class Compare, class Q>
  555. struct priority_queue_maker_helper {
  556. typedef Q priority_queue_type;
  557. static priority_queue_type
  558. make_queue(const Graph&, const ArgPack&, KeyT, const Q& q) {
  559. return q;
  560. }
  561. };
  562. template <class Graph, class ArgPack, class KeyT, class ValueT, class KeyMapTag, class IndexInHeapMapTag, class Compare, class Q>
  563. struct priority_queue_maker_helper<false, Graph, ArgPack, KeyT, ValueT, KeyMapTag, IndexInHeapMapTag, Compare, Q> {
  564. typedef typename std::vector<ValueT>::size_type default_index_in_heap_type;
  565. typedef typename map_maker<Graph, ArgPack, IndexInHeapMapTag, default_index_in_heap_type>::helper::map_type index_in_heap_map;
  566. typedef boost::d_ary_heap_indirect<ValueT, 4, index_in_heap_map, typename map_maker<Graph, ArgPack, KeyMapTag, KeyT>::helper::map_type, Compare> priority_queue_type;
  567. static priority_queue_type
  568. make_queue(const Graph& g, const ArgPack& ap, KeyT defaultKey, const Q&) {
  569. return priority_queue_type(
  570. map_maker<Graph, ArgPack, KeyMapTag, KeyT>::make_map(g, ap, defaultKey),
  571. map_maker<Graph, ArgPack, IndexInHeapMapTag, default_index_in_heap_type>::make_map(g, ap, typename boost::property_traits<index_in_heap_map>::value_type(-1))
  572. );
  573. }
  574. };
  575. template <class Graph, class ArgPack, class KeyT, class ValueT, class PriorityQueueTag, class KeyMapTag, class IndexInHeapMapTag, class Compare>
  576. struct priority_queue_maker {
  577. BOOST_STATIC_CONSTANT(
  578. bool,
  579. g_hasQ =
  580. (parameter_exists<ArgPack, PriorityQueueTag>
  581. ::value));
  582. typedef boost::reference_wrapper<int> int_refw;
  583. typedef typename boost::parameter::value_type<
  584. ArgPack,
  585. PriorityQueueTag,
  586. int_refw
  587. >::type
  588. param_value_type_wrapper;
  589. typedef typename param_value_type_wrapper::type
  590. param_value_type;
  591. typedef typename boost::remove_const<param_value_type>::type param_value_type_no_const;
  592. typedef priority_queue_maker_helper<g_hasQ, Graph, ArgPack, KeyT, ValueT, KeyMapTag, IndexInHeapMapTag, Compare,
  593. param_value_type_no_const> helper;
  594. typedef typename helper::priority_queue_type priority_queue_type;
  595. static priority_queue_type make_queue(const Graph& g, const ArgPack& ap, KeyT defaultKey) {
  596. return helper::make_queue(g, ap, defaultKey, ap[::boost::parameter::keyword<PriorityQueueTag>::instance | 0]);
  597. }
  598. };
  599. template <class PriorityQueueTag, class KeyT, class ValueT, class Compare = std::less<KeyT>, class KeyMapTag = boost::graph::keywords::tag::distance_map, class IndexInHeapMapTag = boost::graph::keywords::tag::index_in_heap_map>
  600. struct make_priority_queue_from_arg_pack_gen {
  601. KeyT defaultKey;
  602. make_priority_queue_from_arg_pack_gen(KeyT defaultKey_) : defaultKey(defaultKey_) { }
  603. template <class F>
  604. struct result {
  605. typedef typename remove_const<typename remove_reference<typename function_traits<F>::arg1_type>::type>::type graph_type;
  606. typedef typename remove_const<typename remove_reference<typename function_traits<F>::arg2_type>::type>::type arg_pack_type;
  607. typedef typename priority_queue_maker<graph_type, arg_pack_type, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::priority_queue_type type;
  608. };
  609. template <class Graph, class ArgPack>
  610. typename priority_queue_maker<Graph, ArgPack, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::priority_queue_type
  611. operator()(const Graph& g, const ArgPack& ap) const {
  612. return priority_queue_maker<Graph, ArgPack, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::make_queue(g, ap, defaultKey);
  613. }
  614. };
  615. template <typename G>
  616. typename boost::graph_traits<G>::vertex_descriptor
  617. get_null_vertex(const G&) {return boost::graph_traits<G>::null_vertex();}
  618. template <typename G>
  619. typename boost::graph_traits<G>::vertex_descriptor
  620. get_default_starting_vertex(const G& g) {
  621. std::pair<typename boost::graph_traits<G>::vertex_iterator, typename boost::graph_traits<G>::vertex_iterator> iters = vertices(g);
  622. return (iters.first == iters.second) ? boost::graph_traits<G>::null_vertex() : *iters.first;
  623. }
  624. template <typename G>
  625. struct get_default_starting_vertex_t {
  626. typedef typename boost::graph_traits<G>::vertex_descriptor result_type;
  627. const G& g;
  628. get_default_starting_vertex_t(const G& g): g(g) {}
  629. result_type operator()() const {return get_default_starting_vertex(g);}
  630. };
  631. // Wrapper to avoid instantiating numeric_limits when users provide distance_inf value manually
  632. template <typename T>
  633. struct get_max {
  634. T operator()() const {
  635. return (std::numeric_limits<T>::max)();
  636. }
  637. typedef T result_type;
  638. };
  639. } // namespace detail
  640. } // namespace boost
  641. #undef BOOST_BGL_DECLARE_NAMED_PARAMS
  642. #endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP