named_function_params.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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. static param_not_found g_param_not_found;
  207. template <typename Tag, typename Args>
  208. struct get_param_type:
  209. lookup_named_param_def<Tag, Args, param_not_found> {};
  210. template <class Tag, typename Args>
  211. inline
  212. const typename lookup_named_param_def<Tag, Args, param_not_found>::type&
  213. get_param(const Args& p, Tag) {
  214. return lookup_named_param_def<Tag, Args, param_not_found>::get(p, g_param_not_found);
  215. }
  216. template <class P, class Default>
  217. const P& choose_param(const P& param, const Default&) {
  218. return param;
  219. }
  220. template <class Default>
  221. Default choose_param(const param_not_found&, const Default& d) {
  222. return d;
  223. }
  224. template <typename T>
  225. inline bool is_default_param(const T&) { return false; }
  226. inline bool is_default_param(const param_not_found&)
  227. { return true; }
  228. namespace detail {
  229. template <typename T>
  230. struct const_type_as_type {typedef typename T::const_type type;};
  231. } // namespace detail
  232. // Use this function instead of choose_param() when you want
  233. // to avoid requiring get(tag, g) when it is not used.
  234. namespace detail {
  235. template <typename GraphIsConst, typename Graph, typename Param, typename Tag>
  236. struct choose_impl_result:
  237. boost::mpl::eval_if<
  238. boost::is_same<Param, param_not_found>,
  239. boost::mpl::eval_if<
  240. GraphIsConst,
  241. detail::const_type_as_type<property_map<Graph, Tag> >,
  242. property_map<Graph, Tag> >,
  243. boost::mpl::identity<Param> > {};
  244. // Parameters of f are (GraphIsConst, Graph, Param, Tag)
  245. template <bool Found> struct choose_impl_helper;
  246. template <> struct choose_impl_helper<false> {
  247. template <typename Param, typename Graph, typename PropertyTag>
  248. static typename property_map<typename boost::remove_const<Graph>::type, PropertyTag>::const_type
  249. f(boost::mpl::true_, const Graph& g, const Param&, PropertyTag tag) {
  250. return get(tag, g);
  251. }
  252. template <typename Param, typename Graph, typename PropertyTag>
  253. static typename property_map<typename boost::remove_const<Graph>::type, PropertyTag>::type
  254. f(boost::mpl::false_, Graph& g, const Param&, PropertyTag tag) {
  255. return get(tag, g);
  256. }
  257. };
  258. template <> struct choose_impl_helper<true> {
  259. template <typename GraphIsConst, typename Param, typename Graph, typename PropertyTag>
  260. static Param f(GraphIsConst, const Graph&, const Param& p, PropertyTag) {
  261. return p;
  262. }
  263. };
  264. }
  265. template <typename Param, typename Graph, typename PropertyTag>
  266. typename detail::choose_impl_result<boost::mpl::true_, Graph, Param, PropertyTag>::type
  267. choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
  268. {
  269. return detail::choose_impl_helper<!boost::is_same<Param, param_not_found>::value>
  270. ::f(boost::mpl::true_(), g, p, tag);
  271. }
  272. template <typename Param, typename Graph, typename PropertyTag>
  273. typename detail::choose_impl_result<boost::mpl::false_, Graph, Param, PropertyTag>::type
  274. choose_pmap(const Param& p, Graph& g, PropertyTag tag)
  275. {
  276. return detail::choose_impl_helper<!boost::is_same<Param, param_not_found>::value>
  277. ::f(boost::mpl::false_(), g, p, tag);
  278. }
  279. namespace detail {
  280. // used in the max-flow algorithms
  281. template <class Graph, class P, class T, class R>
  282. struct edge_capacity_value
  283. {
  284. typedef bgl_named_params<P, T, R> Params;
  285. typedef typename detail::choose_impl_result<boost::mpl::true_, Graph, typename get_param_type<edge_capacity_t, Params>::type, edge_capacity_t>::type CapacityEdgeMap;
  286. typedef typename property_traits<CapacityEdgeMap>::value_type type;
  287. };
  288. // used in the max-flow algorithms
  289. template <class Graph, class P, class T, class R>
  290. struct edge_weight_value
  291. {
  292. typedef bgl_named_params<P, T, R> Params;
  293. typedef typename detail::choose_impl_result<boost::mpl::true_, Graph, typename get_param_type<edge_weight_t, Params>::type, edge_weight_t>::type WeightMap;
  294. typedef typename property_traits<WeightMap>::value_type type;
  295. };
  296. }
  297. // Declare all new tags
  298. namespace graph {
  299. namespace keywords {
  300. #define BOOST_BGL_ONE_PARAM_REF(name, key) BOOST_PARAMETER_NAME(name)
  301. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_PARAMETER_NAME(name)
  302. BOOST_BGL_DECLARE_NAMED_PARAMS
  303. #undef BOOST_BGL_ONE_PARAM_REF
  304. #undef BOOST_BGL_ONE_PARAM_CREF
  305. }
  306. }
  307. namespace detail {
  308. template <typename Tag> struct convert_one_keyword {};
  309. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  310. template <> \
  311. struct convert_one_keyword<BOOST_PP_CAT(key, _t)> { \
  312. typedef boost::graph::keywords::tag::name type; \
  313. };
  314. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_BGL_ONE_PARAM_REF(name, key)
  315. BOOST_BGL_DECLARE_NAMED_PARAMS
  316. #undef BOOST_BGL_ONE_PARAM_REF
  317. #undef BOOST_BGL_ONE_PARAM_CREF
  318. template <typename T>
  319. struct convert_bgl_params_to_boost_parameter {
  320. typedef typename convert_one_keyword<typename T::tag_type>::type new_kw;
  321. typedef boost::parameter::aux::tagged_argument<new_kw, const typename T::value_type> tagged_arg_type;
  322. typedef convert_bgl_params_to_boost_parameter<typename T::next_type> rest_conv;
  323. typedef boost::parameter::aux::arg_list<tagged_arg_type, typename rest_conv::type> type;
  324. static type conv(const T& x) {
  325. return type(tagged_arg_type(x.m_value), rest_conv::conv(x.m_base));
  326. }
  327. };
  328. template <typename P, typename R>
  329. struct convert_bgl_params_to_boost_parameter<bgl_named_params<P, int, R> > {
  330. typedef convert_bgl_params_to_boost_parameter<R> rest_conv;
  331. typedef typename rest_conv::type type;
  332. static type conv(const bgl_named_params<P, int, R>& x) {
  333. return rest_conv::conv(x.m_base);
  334. }
  335. };
  336. template <>
  337. struct convert_bgl_params_to_boost_parameter<boost::no_property> {
  338. typedef boost::parameter::aux::empty_arg_list type;
  339. static type conv(const boost::no_property&) {return type();}
  340. };
  341. template <>
  342. struct convert_bgl_params_to_boost_parameter<boost::no_named_parameters> {
  343. typedef boost::parameter::aux::empty_arg_list type;
  344. static type conv(const boost::no_named_parameters&) {return type();}
  345. };
  346. struct bgl_parameter_not_found_type {};
  347. template <typename ArgPack, typename KeywordType>
  348. 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> > {};
  349. }
  350. #define BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(old_type, old_var) \
  351. typedef typename boost::detail::convert_bgl_params_to_boost_parameter<old_type>::type arg_pack_type; \
  352. arg_pack_type arg_pack = boost::detail::convert_bgl_params_to_boost_parameter<old_type>::conv(old_var);
  353. namespace detail {
  354. template <typename ArgType, typename Prop, typename Graph, bool Exists>
  355. struct override_const_property_t {
  356. typedef typename boost::remove_const<ArgType>::type result_type;
  357. result_type operator()(const Graph&, const ArgType& a) const {return a;}
  358. };
  359. template <typename ArgType, typename Prop, typename Graph>
  360. struct override_const_property_t<ArgType, Prop, Graph, false> {
  361. typedef typename boost::property_map<Graph, Prop>::const_type result_type;
  362. result_type operator()(const Graph& g, const ArgType&) const {return get(Prop(), g);}
  363. };
  364. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  365. struct override_const_property_result {
  366. typedef
  367. typename override_const_property_t<
  368. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  369. Prop,
  370. Graph,
  371. boost::detail::parameter_exists<ArgPack, Tag>::value
  372. >::result_type
  373. type;
  374. };
  375. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  376. typename override_const_property_result<ArgPack, Tag, Prop, Graph>::type
  377. override_const_property(const ArgPack& ap, const boost::parameter::keyword<Tag>& t, const Graph& g, Prop) {
  378. return override_const_property_t<
  379. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  380. Prop,
  381. Graph,
  382. boost::detail::parameter_exists<ArgPack, Tag>::value
  383. >()(g, ap[t | 0]);
  384. }
  385. template <typename ArgType, typename Prop, typename Graph, bool Exists>
  386. struct override_property_t {
  387. typedef ArgType result_type;
  388. result_type operator()(const Graph&, const typename boost::add_reference<ArgType>::type a) const {return a;}
  389. };
  390. template <typename ArgType, typename Prop, typename Graph>
  391. struct override_property_t<ArgType, Prop, Graph, false> {
  392. typedef typename boost::property_map<Graph, Prop>::type result_type;
  393. result_type operator()(const Graph& g, const ArgType&) const {return get(Prop(), g);}
  394. };
  395. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  396. struct override_property_result {
  397. typedef
  398. typename override_property_t<
  399. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  400. Prop,
  401. Graph,
  402. boost::detail::parameter_exists<ArgPack, Tag>::value
  403. >::result_type
  404. type;
  405. };
  406. template <typename ArgPack, typename Tag, typename Prop, typename Graph>
  407. typename override_property_result<ArgPack, Tag, Prop, Graph>::type
  408. override_property(const ArgPack& ap, const boost::parameter::keyword<Tag>& t, const Graph& g, Prop) {
  409. return override_property_t<
  410. typename boost::parameter::value_type<ArgPack, Tag, int>::type,
  411. Prop,
  412. Graph,
  413. boost::detail::parameter_exists<ArgPack, Tag>::value
  414. >()(g, ap[t | 0]);
  415. }
  416. template <typename F> struct make_arg_pack_type;
  417. template <> struct make_arg_pack_type<void()> {typedef boost::parameter::aux::empty_arg_list type;};
  418. template <typename K, typename A>
  419. struct make_arg_pack_type<void(K, A)> {
  420. typedef boost::parameter::aux::tagged_argument<K, A> type;
  421. };
  422. #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))>,
  423. #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)
  424. #define BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION(z, i, _) \
  425. template <BOOST_PP_ENUM_PARAMS(i, typename Keyword), BOOST_PP_ENUM_PARAMS(i, typename Arg)> \
  426. struct make_arg_pack_type<void(BOOST_PP_ENUM_PARAMS(i, Keyword), BOOST_PP_ENUM_PARAMS(i, Arg))> { \
  427. typedef \
  428. 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), ~) \
  429. type; \
  430. };
  431. BOOST_PP_REPEAT_FROM_TO(2, 11, BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION, ~)
  432. #undef BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION
  433. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(name, nfixed, nnamed_max) \
  434. /* Entry point for conversion from BGL-style named parameters */ \
  435. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_COMMA_IF(nfixed) typename ArgPack> \
  436. typename boost::result_of< \
  437. 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&) \
  438. >::type \
  439. 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) { \
  440. 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); \
  441. } \
  442. /* Individual functions taking Boost.Parameter-style keyword arguments */ \
  443. BOOST_PP_REPEAT(BOOST_PP_INC(nnamed_max), BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE, (name)(nfixed))
  444. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE(z, nnamed, seq) \
  445. BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX(z, nnamed, BOOST_PP_SEQ_ELEM(0, seq), BOOST_PP_SEQ_ELEM(1, seq))
  446. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX(z, nnamed, name, nfixed) \
  447. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, typename Keyword) BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, typename Arg)> \
  448. typename boost::result_of< \
  449. detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)> \
  450. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) \
  451. 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&) \
  452. >::type \
  453. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param) \
  454. BOOST_PP_ENUM_TRAILING(nnamed, BOOST_GRAPH_MAKE_PAIR_PARAM, ~)) { \
  455. return detail::BOOST_PP_CAT(name, _impl)<BOOST_PP_ENUM_PARAMS(nfixed, Param)>() \
  456. (BOOST_PP_ENUM_PARAMS(nfixed, param), \
  457. (boost::parameter::aux::empty_arg_list() BOOST_PP_ENUM_TRAILING_PARAMS(nnamed, kw))); \
  458. }
  459. #define BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(name, nfixed) \
  460. template <BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_COMMA_IF(nfixed) class P, class T, class R> \
  461. typename boost::result_of< \
  462. ::boost::graph::detail::BOOST_PP_CAT(name, _impl) BOOST_PP_EXPR_IF(nfixed, <) BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_EXPR_IF(nfixed, >) \
  463. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) \
  464. const typename boost::detail::convert_bgl_params_to_boost_parameter<boost::bgl_named_params<P, T, R> >::type &) \
  465. >::type \
  466. 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) { \
  467. typedef boost::bgl_named_params<P, T, R> old_style_params_type; \
  468. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(old_style_params_type, old_style_params) \
  469. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)(BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) arg_pack); \
  470. } \
  471. \
  472. BOOST_PP_EXPR_IF(nfixed, template <) BOOST_PP_ENUM_PARAMS(nfixed, typename Param) BOOST_PP_EXPR_IF(nfixed, >) \
  473. BOOST_PP_EXPR_IF(nfixed, typename) boost::result_of< \
  474. ::boost::graph::detail::BOOST_PP_CAT(name, _impl) BOOST_PP_EXPR_IF(nfixed, <) BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_EXPR_IF(nfixed, >) \
  475. (BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) const boost::parameter::aux::empty_arg_list &) \
  476. >::type \
  477. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, & param)) { \
  478. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(boost::no_named_parameters, boost::no_named_parameters()) \
  479. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)(BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) arg_pack); \
  480. }
  481. }
  482. namespace detail {
  483. template <bool Exists, typename Graph, typename ArgPack, typename Value, typename PM>
  484. struct map_maker_helper {
  485. typedef PM map_type;
  486. static PM make_map(const Graph&, Value, const PM& pm, const ArgPack&) {
  487. return pm;
  488. }
  489. };
  490. template <typename Graph, typename ArgPack, typename Value, typename PM>
  491. struct map_maker_helper<false, Graph, ArgPack, Value, PM> {
  492. typedef typename boost::remove_const<
  493. typename override_const_property_t<
  494. typename boost::parameter::value_type<
  495. ArgPack, boost::graph::keywords::tag::vertex_index_map, int>::type,
  496. boost::vertex_index_t,
  497. Graph,
  498. boost::detail::parameter_exists<
  499. ArgPack, boost::graph::keywords::tag::vertex_index_map>::value
  500. >::result_type>::type vi_map_type;
  501. typedef
  502. boost::shared_array_property_map<Value, vi_map_type>
  503. map_type;
  504. static map_type make_map(const Graph& g,
  505. Value v,
  506. const PM&,
  507. const ArgPack& ap) {
  508. return make_shared_array_property_map(
  509. num_vertices(g),
  510. v,
  511. override_const_property(
  512. ap,
  513. boost::graph::keywords::_vertex_index_map,
  514. g, vertex_index));
  515. }
  516. };
  517. template <typename Graph, typename ArgPack, typename MapTag, typename ValueType>
  518. struct map_maker {
  519. BOOST_STATIC_CONSTANT(
  520. bool,
  521. has_map =
  522. (parameter_exists<ArgPack, MapTag>
  523. ::value));
  524. typedef map_maker_helper<has_map, Graph, ArgPack, ValueType,
  525. typename boost::remove_const<
  526. typename boost::parameter::value_type<
  527. ArgPack,
  528. MapTag,
  529. int
  530. >::type
  531. >::type> helper;
  532. typedef typename helper::map_type map_type;
  533. static map_type make_map(const Graph& g, const ArgPack& ap, ValueType default_value) {
  534. return helper::make_map(g, default_value, ap[::boost::parameter::keyword<MapTag>::instance | 0], ap);
  535. }
  536. };
  537. template <typename MapTag, typename ValueType = void>
  538. class make_property_map_from_arg_pack_gen {
  539. ValueType default_value;
  540. public:
  541. make_property_map_from_arg_pack_gen(ValueType default_value)
  542. : default_value(default_value) {}
  543. template <typename Graph, typename ArgPack>
  544. typename map_maker<Graph, ArgPack, MapTag, ValueType>::map_type
  545. operator()(const Graph& g, const ArgPack& ap) const {
  546. return map_maker<Graph, ArgPack, MapTag, ValueType>::make_map(g, ap, default_value);
  547. }
  548. };
  549. template <typename MapTag>
  550. class make_property_map_from_arg_pack_gen<MapTag, void> {
  551. public:
  552. template <typename ValueType, typename Graph, typename ArgPack>
  553. typename map_maker<Graph, ArgPack, MapTag, ValueType>::map_type
  554. operator()(const Graph& g, const ArgPack& ap, ValueType default_value) const {
  555. return map_maker<Graph, ArgPack, MapTag, ValueType>::make_map(g, ap, default_value);
  556. }
  557. };
  558. static const
  559. make_property_map_from_arg_pack_gen<
  560. boost::graph::keywords::tag::color_map,
  561. default_color_type>
  562. make_color_map_from_arg_pack(white_color);
  563. template <bool Exists, class Graph, class ArgPack, class KeyT, class ValueT, class KeyMapTag, class IndexInHeapMapTag, class Compare, class Q>
  564. struct priority_queue_maker_helper {
  565. typedef Q priority_queue_type;
  566. static priority_queue_type
  567. make_queue(const Graph&, const ArgPack&, KeyT, const Q& q) {
  568. return q;
  569. }
  570. };
  571. template <class Graph, class ArgPack, class KeyT, class ValueT, class KeyMapTag, class IndexInHeapMapTag, class Compare, class Q>
  572. struct priority_queue_maker_helper<false, Graph, ArgPack, KeyT, ValueT, KeyMapTag, IndexInHeapMapTag, Compare, Q> {
  573. typedef typename std::vector<ValueT>::size_type default_index_in_heap_type;
  574. typedef typename map_maker<Graph, ArgPack, IndexInHeapMapTag, default_index_in_heap_type>::helper::map_type index_in_heap_map;
  575. 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;
  576. static priority_queue_type
  577. make_queue(const Graph& g, const ArgPack& ap, KeyT defaultKey, const Q&) {
  578. return priority_queue_type(
  579. map_maker<Graph, ArgPack, KeyMapTag, KeyT>::make_map(g, ap, defaultKey),
  580. 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))
  581. );
  582. }
  583. };
  584. template <class Graph, class ArgPack, class KeyT, class ValueT, class PriorityQueueTag, class KeyMapTag, class IndexInHeapMapTag, class Compare>
  585. struct priority_queue_maker {
  586. BOOST_STATIC_CONSTANT(
  587. bool,
  588. g_hasQ =
  589. (parameter_exists<ArgPack, PriorityQueueTag>
  590. ::value));
  591. typedef boost::reference_wrapper<int> int_refw;
  592. typedef typename boost::parameter::value_type<
  593. ArgPack,
  594. PriorityQueueTag,
  595. int_refw
  596. >::type
  597. param_value_type_wrapper;
  598. typedef typename param_value_type_wrapper::type
  599. param_value_type;
  600. typedef typename boost::remove_const<param_value_type>::type param_value_type_no_const;
  601. typedef priority_queue_maker_helper<g_hasQ, Graph, ArgPack, KeyT, ValueT, KeyMapTag, IndexInHeapMapTag, Compare,
  602. param_value_type_no_const> helper;
  603. typedef typename helper::priority_queue_type priority_queue_type;
  604. static priority_queue_type make_queue(const Graph& g, const ArgPack& ap, KeyT defaultKey) {
  605. return helper::make_queue(g, ap, defaultKey, ap[::boost::parameter::keyword<PriorityQueueTag>::instance | 0]);
  606. }
  607. };
  608. 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>
  609. struct make_priority_queue_from_arg_pack_gen {
  610. KeyT defaultKey;
  611. make_priority_queue_from_arg_pack_gen(KeyT defaultKey_) : defaultKey(defaultKey_) { }
  612. template <class F>
  613. struct result {
  614. typedef typename remove_const<typename remove_reference<typename function_traits<F>::arg1_type>::type>::type graph_type;
  615. typedef typename remove_const<typename remove_reference<typename function_traits<F>::arg2_type>::type>::type arg_pack_type;
  616. typedef typename priority_queue_maker<graph_type, arg_pack_type, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::priority_queue_type type;
  617. };
  618. template <class Graph, class ArgPack>
  619. typename priority_queue_maker<Graph, ArgPack, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::priority_queue_type
  620. operator()(const Graph& g, const ArgPack& ap) const {
  621. return priority_queue_maker<Graph, ArgPack, KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag, Compare>::make_queue(g, ap, defaultKey);
  622. }
  623. };
  624. template <typename G>
  625. typename boost::graph_traits<G>::vertex_descriptor
  626. get_null_vertex(const G&) {return boost::graph_traits<G>::null_vertex();}
  627. template <typename G>
  628. typename boost::graph_traits<G>::vertex_descriptor
  629. get_default_starting_vertex(const G& g) {
  630. std::pair<typename boost::graph_traits<G>::vertex_iterator, typename boost::graph_traits<G>::vertex_iterator> iters = vertices(g);
  631. return (iters.first == iters.second) ? boost::graph_traits<G>::null_vertex() : *iters.first;
  632. }
  633. template <typename G>
  634. struct get_default_starting_vertex_t {
  635. typedef typename boost::graph_traits<G>::vertex_descriptor result_type;
  636. const G& g;
  637. get_default_starting_vertex_t(const G& g): g(g) {}
  638. result_type operator()() const {return get_default_starting_vertex(g);}
  639. };
  640. // Wrapper to avoid instantiating numeric_limits when users provide distance_inf value manually
  641. template <typename T>
  642. struct get_max {
  643. T operator()() const {
  644. return (std::numeric_limits<T>::max)();
  645. }
  646. typedef T result_type;
  647. };
  648. } // namespace detail
  649. } // namespace boost
  650. #undef BOOST_BGL_DECLARE_NAMED_PARAMS
  651. #endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP