named_function_params.hpp 33 KB

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