named_function_params.hpp 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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. {
  30. struct parity_map_t
  31. {
  32. };
  33. struct vertex_assignment_map_t
  34. {
  35. };
  36. struct distance_compare_t
  37. {
  38. };
  39. struct distance_combine_t
  40. {
  41. };
  42. struct distance_inf_t
  43. {
  44. };
  45. struct distance_zero_t
  46. {
  47. };
  48. struct buffer_param_t
  49. {
  50. };
  51. struct edge_copy_t
  52. {
  53. };
  54. struct vertex_copy_t
  55. {
  56. };
  57. struct vertex_isomorphism_t
  58. {
  59. };
  60. struct vertex_invariant_t
  61. {
  62. };
  63. struct vertex_invariant1_t
  64. {
  65. };
  66. struct vertex_invariant2_t
  67. {
  68. };
  69. struct edge_compare_t
  70. {
  71. };
  72. struct vertex_max_invariant_t
  73. {
  74. };
  75. struct orig_to_copy_t
  76. {
  77. };
  78. struct root_vertex_t
  79. {
  80. };
  81. struct polling_t
  82. {
  83. };
  84. struct lookahead_t
  85. {
  86. };
  87. struct in_parallel_t
  88. {
  89. };
  90. struct attractive_force_t
  91. {
  92. };
  93. struct repulsive_force_t
  94. {
  95. };
  96. struct force_pairs_t
  97. {
  98. };
  99. struct cooling_t
  100. {
  101. };
  102. struct vertex_displacement_t
  103. {
  104. };
  105. struct iterations_t
  106. {
  107. };
  108. struct diameter_range_t
  109. {
  110. };
  111. struct learning_constant_range_t
  112. {
  113. };
  114. struct vertices_equivalent_t
  115. {
  116. };
  117. struct edges_equivalent_t
  118. {
  119. };
  120. struct index_in_heap_map_t
  121. {
  122. };
  123. struct max_priority_queue_t
  124. {
  125. };
  126. #define BOOST_BGL_DECLARE_NAMED_PARAMS \
  127. BOOST_BGL_ONE_PARAM_CREF(weight_map, edge_weight) \
  128. BOOST_BGL_ONE_PARAM_CREF(weight_map2, edge_weight2) \
  129. BOOST_BGL_ONE_PARAM_CREF(distance_map, vertex_distance) \
  130. BOOST_BGL_ONE_PARAM_CREF(distance_map2, vertex_distance2) \
  131. BOOST_BGL_ONE_PARAM_CREF(predecessor_map, vertex_predecessor) \
  132. BOOST_BGL_ONE_PARAM_CREF(rank_map, vertex_rank) \
  133. BOOST_BGL_ONE_PARAM_CREF(root_map, vertex_root) \
  134. BOOST_BGL_ONE_PARAM_CREF(root_vertex, root_vertex) \
  135. BOOST_BGL_ONE_PARAM_CREF(edge_centrality_map, edge_centrality) \
  136. BOOST_BGL_ONE_PARAM_CREF(centrality_map, vertex_centrality) \
  137. BOOST_BGL_ONE_PARAM_CREF(parity_map, parity_map) \
  138. BOOST_BGL_ONE_PARAM_CREF(color_map, vertex_color) \
  139. BOOST_BGL_ONE_PARAM_CREF(edge_color_map, edge_color) \
  140. BOOST_BGL_ONE_PARAM_CREF(capacity_map, edge_capacity) \
  141. BOOST_BGL_ONE_PARAM_CREF(residual_capacity_map, edge_residual_capacity) \
  142. BOOST_BGL_ONE_PARAM_CREF(reverse_edge_map, edge_reverse) \
  143. BOOST_BGL_ONE_PARAM_CREF(discover_time_map, vertex_discover_time) \
  144. BOOST_BGL_ONE_PARAM_CREF(lowpoint_map, vertex_lowpoint) \
  145. BOOST_BGL_ONE_PARAM_CREF(vertex_index_map, vertex_index) \
  146. BOOST_BGL_ONE_PARAM_CREF(vertex_index1_map, vertex_index1) \
  147. BOOST_BGL_ONE_PARAM_CREF(vertex_index2_map, vertex_index2) \
  148. BOOST_BGL_ONE_PARAM_CREF(vertex_assignment_map, vertex_assignment_map) \
  149. BOOST_BGL_ONE_PARAM_CREF(visitor, graph_visitor) \
  150. BOOST_BGL_ONE_PARAM_CREF(distance_compare, distance_compare) \
  151. BOOST_BGL_ONE_PARAM_CREF(distance_combine, distance_combine) \
  152. BOOST_BGL_ONE_PARAM_CREF(distance_inf, distance_inf) \
  153. BOOST_BGL_ONE_PARAM_CREF(distance_zero, distance_zero) \
  154. BOOST_BGL_ONE_PARAM_CREF(edge_copy, edge_copy) \
  155. BOOST_BGL_ONE_PARAM_CREF(vertex_copy, vertex_copy) \
  156. BOOST_BGL_ONE_PARAM_REF(buffer, buffer_param) \
  157. BOOST_BGL_ONE_PARAM_CREF(orig_to_copy, orig_to_copy) \
  158. BOOST_BGL_ONE_PARAM_CREF(isomorphism_map, vertex_isomorphism) \
  159. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant, vertex_invariant) \
  160. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant1, vertex_invariant1) \
  161. BOOST_BGL_ONE_PARAM_CREF(vertex_invariant2, vertex_invariant2) \
  162. BOOST_BGL_ONE_PARAM_CREF(vertex_max_invariant, vertex_max_invariant) \
  163. BOOST_BGL_ONE_PARAM_CREF(polling, polling) \
  164. BOOST_BGL_ONE_PARAM_CREF(lookahead, lookahead) \
  165. BOOST_BGL_ONE_PARAM_CREF(in_parallel, in_parallel) \
  166. BOOST_BGL_ONE_PARAM_CREF(displacement_map, vertex_displacement) \
  167. BOOST_BGL_ONE_PARAM_CREF(attractive_force, attractive_force) \
  168. BOOST_BGL_ONE_PARAM_CREF(repulsive_force, repulsive_force) \
  169. BOOST_BGL_ONE_PARAM_CREF(force_pairs, force_pairs) \
  170. BOOST_BGL_ONE_PARAM_CREF(cooling, cooling) \
  171. BOOST_BGL_ONE_PARAM_CREF(iterations, iterations) \
  172. BOOST_BGL_ONE_PARAM_CREF(diameter_range, diameter_range) \
  173. BOOST_BGL_ONE_PARAM_CREF(learning_constant_range, learning_constant_range) \
  174. BOOST_BGL_ONE_PARAM_CREF(vertices_equivalent, vertices_equivalent) \
  175. BOOST_BGL_ONE_PARAM_CREF(edges_equivalent, edges_equivalent) \
  176. BOOST_BGL_ONE_PARAM_CREF(index_in_heap_map, index_in_heap_map) \
  177. BOOST_BGL_ONE_PARAM_REF(max_priority_queue, max_priority_queue)
  178. template < typename T, typename Tag, typename Base = no_property >
  179. struct bgl_named_params
  180. {
  181. typedef bgl_named_params self;
  182. typedef Base next_type;
  183. typedef Tag tag_type;
  184. typedef T value_type;
  185. bgl_named_params(T v = T()) : m_value(v) {}
  186. bgl_named_params(T v, const Base& b) : m_value(v), m_base(b) {}
  187. T m_value;
  188. Base m_base;
  189. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  190. template < typename PType > \
  191. bgl_named_params< boost::reference_wrapper< PType >, \
  192. BOOST_PP_CAT(key, _t), self > \
  193. name(PType& p) const \
  194. { \
  195. typedef bgl_named_params< boost::reference_wrapper< PType >, \
  196. BOOST_PP_CAT(key, _t), self > \
  197. Params; \
  198. return Params(boost::ref(p), *this); \
  199. }
  200. #define BOOST_BGL_ONE_PARAM_CREF(name, key) \
  201. template < typename PType > \
  202. bgl_named_params< PType, BOOST_PP_CAT(key, _t), self > name( \
  203. const PType& p) const \
  204. { \
  205. typedef bgl_named_params< PType, BOOST_PP_CAT(key, _t), self > Params; \
  206. return Params(p, *this); \
  207. }
  208. BOOST_BGL_DECLARE_NAMED_PARAMS
  209. #undef BOOST_BGL_ONE_PARAM_REF
  210. #undef BOOST_BGL_ONE_PARAM_CREF
  211. // Duplicate
  212. template < typename PType >
  213. bgl_named_params< PType, vertex_color_t, self > vertex_color_map(
  214. const PType& p) const
  215. {
  216. return this->color_map(p);
  217. }
  218. };
  219. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  220. template < typename PType > \
  221. bgl_named_params< boost::reference_wrapper< PType >, \
  222. BOOST_PP_CAT(key, _t) > \
  223. name(PType& p) \
  224. { \
  225. typedef bgl_named_params< boost::reference_wrapper< PType >, \
  226. BOOST_PP_CAT(key, _t) > \
  227. Params; \
  228. return Params(boost::ref(p)); \
  229. }
  230. #define BOOST_BGL_ONE_PARAM_CREF(name, key) \
  231. template < typename PType > \
  232. bgl_named_params< PType, BOOST_PP_CAT(key, _t) > name(const PType& p) \
  233. { \
  234. typedef bgl_named_params< PType, BOOST_PP_CAT(key, _t) > Params; \
  235. return Params(p); \
  236. }
  237. BOOST_BGL_DECLARE_NAMED_PARAMS
  238. #undef BOOST_BGL_ONE_PARAM_REF
  239. #undef BOOST_BGL_ONE_PARAM_CREF
  240. // Duplicate
  241. template < typename PType >
  242. bgl_named_params< PType, vertex_color_t > vertex_color_map(const PType& p)
  243. {
  244. return color_map(p);
  245. }
  246. namespace detail
  247. {
  248. struct unused_tag_type
  249. {
  250. };
  251. }
  252. typedef bgl_named_params< char, detail::unused_tag_type > no_named_parameters;
  253. //===========================================================================
  254. // Functions for extracting parameters from bgl_named_params
  255. template < typename Tag, typename Args > struct lookup_named_param
  256. {
  257. };
  258. template < typename T, typename Tag, typename Base >
  259. struct lookup_named_param< Tag, bgl_named_params< T, Tag, Base > >
  260. {
  261. typedef T type;
  262. static const T& get(const bgl_named_params< T, Tag, Base >& p)
  263. {
  264. return p.m_value;
  265. }
  266. };
  267. template < typename Tag1, typename T, typename Tag, typename Base >
  268. struct lookup_named_param< Tag1, bgl_named_params< T, Tag, Base > >
  269. {
  270. typedef typename lookup_named_param< Tag1, Base >::type type;
  271. static const type& get(const bgl_named_params< T, Tag, Base >& p)
  272. {
  273. return lookup_named_param< Tag1, Base >::get(p.m_base);
  274. }
  275. };
  276. template < typename Tag, typename Args, typename Def >
  277. struct lookup_named_param_def
  278. {
  279. typedef Def type;
  280. static const Def& get(const Args&, const Def& def) { return def; }
  281. };
  282. template < typename T, typename Tag, typename Base, typename Def >
  283. struct lookup_named_param_def< Tag, bgl_named_params< T, Tag, Base >, Def >
  284. {
  285. typedef T type;
  286. static const type& get(
  287. const bgl_named_params< T, Tag, Base >& p, const Def&)
  288. {
  289. return p.m_value;
  290. }
  291. };
  292. template < typename Tag1, typename T, typename Tag, typename Base,
  293. typename Def >
  294. struct lookup_named_param_def< Tag1, bgl_named_params< T, Tag, Base >, Def >
  295. {
  296. typedef typename lookup_named_param_def< Tag1, Base, Def >::type type;
  297. static const type& get(
  298. const bgl_named_params< T, Tag, Base >& p, const Def& def)
  299. {
  300. return lookup_named_param_def< Tag1, Base, Def >::get(p.m_base, def);
  301. }
  302. };
  303. struct param_not_found
  304. {
  305. };
  306. static param_not_found g_param_not_found;
  307. template < typename Tag, typename Args >
  308. struct get_param_type : lookup_named_param_def< Tag, Args, param_not_found >
  309. {
  310. };
  311. template < class Tag, typename Args >
  312. inline const typename lookup_named_param_def< Tag, Args,
  313. param_not_found >::type&
  314. get_param(const Args& p, Tag)
  315. {
  316. return lookup_named_param_def< Tag, Args, param_not_found >::get(
  317. p, g_param_not_found);
  318. }
  319. template < class P, class Default >
  320. const P& choose_param(const P& param, const Default&)
  321. {
  322. return param;
  323. }
  324. template < class Default >
  325. Default choose_param(const param_not_found&, const Default& d)
  326. {
  327. return d;
  328. }
  329. template < typename T > inline bool is_default_param(const T&) { return false; }
  330. inline bool is_default_param(const param_not_found&) { return true; }
  331. namespace detail
  332. {
  333. template < typename T > struct const_type_as_type
  334. {
  335. typedef typename T::const_type type;
  336. };
  337. } // namespace detail
  338. // Use this function instead of choose_param() when you want
  339. // to avoid requiring get(tag, g) when it is not used.
  340. namespace detail
  341. {
  342. template < typename GraphIsConst, typename Graph, typename Param,
  343. typename Tag >
  344. struct choose_impl_result
  345. : boost::mpl::eval_if< boost::is_same< Param, param_not_found >,
  346. boost::mpl::eval_if< GraphIsConst,
  347. detail::const_type_as_type< property_map< Graph, Tag > >,
  348. property_map< Graph, Tag > >,
  349. boost::mpl::identity< Param > >
  350. {
  351. };
  352. // Parameters of f are (GraphIsConst, Graph, Param, Tag)
  353. template < bool Found > struct choose_impl_helper;
  354. template <> struct choose_impl_helper< false >
  355. {
  356. template < typename Param, typename Graph, typename PropertyTag >
  357. static
  358. typename property_map< typename boost::remove_const< Graph >::type,
  359. PropertyTag >::const_type
  360. f(boost::mpl::true_, const Graph& g, const Param&, PropertyTag tag)
  361. {
  362. return get(tag, g);
  363. }
  364. template < typename Param, typename Graph, typename PropertyTag >
  365. static
  366. typename property_map< typename boost::remove_const< Graph >::type,
  367. PropertyTag >::type
  368. f(boost::mpl::false_, Graph& g, const Param&, PropertyTag tag)
  369. {
  370. return get(tag, g);
  371. }
  372. };
  373. template <> struct choose_impl_helper< true >
  374. {
  375. template < typename GraphIsConst, typename Param, typename Graph,
  376. typename PropertyTag >
  377. static Param f(GraphIsConst, const Graph&, const Param& p, PropertyTag)
  378. {
  379. return p;
  380. }
  381. };
  382. }
  383. template < typename Param, typename Graph, typename PropertyTag >
  384. typename detail::choose_impl_result< boost::mpl::true_, Graph, Param,
  385. PropertyTag >::type
  386. choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
  387. {
  388. return detail::choose_impl_helper< !boost::is_same< Param,
  389. param_not_found >::value >::f(boost::mpl::true_(), g, p, tag);
  390. }
  391. template < typename Param, typename Graph, typename PropertyTag >
  392. typename detail::choose_impl_result< boost::mpl::false_, Graph, Param,
  393. PropertyTag >::type
  394. choose_pmap(const Param& p, Graph& g, PropertyTag tag)
  395. {
  396. return detail::choose_impl_helper< !boost::is_same< Param,
  397. param_not_found >::value >::f(boost::mpl::false_(), g, p, tag);
  398. }
  399. namespace detail
  400. {
  401. // used in the max-flow algorithms
  402. template < class Graph, class P, class T, class R >
  403. struct edge_capacity_value
  404. {
  405. typedef bgl_named_params< P, T, R > Params;
  406. typedef typename detail::choose_impl_result< boost::mpl::true_, Graph,
  407. typename get_param_type< edge_capacity_t, Params >::type,
  408. edge_capacity_t >::type CapacityEdgeMap;
  409. typedef typename property_traits< CapacityEdgeMap >::value_type type;
  410. };
  411. // used in the max-flow algorithms
  412. template < class Graph, class P, class T, class R > struct edge_weight_value
  413. {
  414. typedef bgl_named_params< P, T, R > Params;
  415. typedef typename detail::choose_impl_result< boost::mpl::true_, Graph,
  416. typename get_param_type< edge_weight_t, Params >::type,
  417. edge_weight_t >::type WeightMap;
  418. typedef typename property_traits< WeightMap >::value_type type;
  419. };
  420. }
  421. // Declare all new tags
  422. namespace graph
  423. {
  424. namespace keywords
  425. {
  426. #define BOOST_BGL_ONE_PARAM_REF(name, key) BOOST_PARAMETER_NAME(name)
  427. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_PARAMETER_NAME(name)
  428. BOOST_BGL_DECLARE_NAMED_PARAMS
  429. #undef BOOST_BGL_ONE_PARAM_REF
  430. #undef BOOST_BGL_ONE_PARAM_CREF
  431. }
  432. }
  433. namespace detail
  434. {
  435. template < typename Tag > struct convert_one_keyword
  436. {
  437. };
  438. #define BOOST_BGL_ONE_PARAM_REF(name, key) \
  439. template <> struct convert_one_keyword< BOOST_PP_CAT(key, _t) > \
  440. { \
  441. typedef boost::graph::keywords::tag::name type; \
  442. };
  443. #define BOOST_BGL_ONE_PARAM_CREF(name, key) BOOST_BGL_ONE_PARAM_REF(name, key)
  444. BOOST_BGL_DECLARE_NAMED_PARAMS
  445. #undef BOOST_BGL_ONE_PARAM_REF
  446. #undef BOOST_BGL_ONE_PARAM_CREF
  447. template < typename T > struct convert_bgl_params_to_boost_parameter
  448. {
  449. typedef
  450. typename convert_one_keyword< typename T::tag_type >::type new_kw;
  451. typedef boost::parameter::aux::tagged_argument< new_kw,
  452. const typename T::value_type >
  453. tagged_arg_type;
  454. typedef convert_bgl_params_to_boost_parameter< typename T::next_type >
  455. rest_conv;
  456. typedef boost::parameter::aux::arg_list< tagged_arg_type,
  457. typename rest_conv::type >
  458. type;
  459. static type conv(const T& x)
  460. {
  461. return type(tagged_arg_type(x.m_value), rest_conv::conv(x.m_base));
  462. }
  463. };
  464. template < typename P, typename R >
  465. struct convert_bgl_params_to_boost_parameter<
  466. bgl_named_params< P, int, R > >
  467. {
  468. typedef convert_bgl_params_to_boost_parameter< R > rest_conv;
  469. typedef typename rest_conv::type type;
  470. static type conv(const bgl_named_params< P, int, R >& x)
  471. {
  472. return rest_conv::conv(x.m_base);
  473. }
  474. };
  475. template <>
  476. struct convert_bgl_params_to_boost_parameter< boost::no_property >
  477. {
  478. typedef boost::parameter::aux::empty_arg_list type;
  479. static type conv(const boost::no_property&) { return type(); }
  480. };
  481. template <>
  482. struct convert_bgl_params_to_boost_parameter< boost::no_named_parameters >
  483. {
  484. typedef boost::parameter::aux::empty_arg_list type;
  485. static type conv(const boost::no_named_parameters&) { return type(); }
  486. };
  487. struct bgl_parameter_not_found_type
  488. {
  489. };
  490. }
  491. #define BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(old_type, old_var) \
  492. typedef typename boost::detail::convert_bgl_params_to_boost_parameter< \
  493. old_type >::type arg_pack_type; \
  494. arg_pack_type arg_pack \
  495. = boost::detail::convert_bgl_params_to_boost_parameter< \
  496. old_type >::conv(old_var);
  497. namespace detail
  498. {
  499. template < typename ArgType, typename Prop, typename Graph, bool Exists >
  500. struct override_const_property_t
  501. {
  502. typedef typename boost::remove_const< ArgType >::type result_type;
  503. result_type operator()(const Graph&, const ArgType& a) const
  504. {
  505. return a;
  506. }
  507. };
  508. template < typename ArgType, typename Prop, typename Graph >
  509. struct override_const_property_t< ArgType, Prop, Graph, false >
  510. {
  511. typedef
  512. typename boost::property_map< Graph, Prop >::const_type result_type;
  513. result_type operator()(const Graph& g, const ArgType&) const
  514. {
  515. return get(Prop(), g);
  516. }
  517. };
  518. template < typename ArgPack, typename Tag, typename Prop, typename Graph >
  519. struct override_const_property_result
  520. {
  521. typedef typename boost::mpl::has_key< ArgPack, Tag >::type
  522. _parameter_exists;
  523. typedef typename override_const_property_t<
  524. typename boost::parameter::value_type< ArgPack, Tag, int >::type,
  525. Prop, Graph, _parameter_exists::value >::result_type type;
  526. };
  527. template < typename ArgPack, typename Tag, typename Prop, typename Graph >
  528. typename override_const_property_result< ArgPack, Tag, Prop, Graph >::type
  529. override_const_property(const ArgPack& ap,
  530. const boost::parameter::keyword< Tag >& t, const Graph& g, Prop)
  531. {
  532. typedef typename boost::mpl::has_key< ArgPack, Tag >::type
  533. _parameter_exists;
  534. return override_const_property_t<
  535. typename boost::parameter::value_type< ArgPack, Tag, int >::type,
  536. Prop, Graph, _parameter_exists::value >()(g, ap[t | 0]);
  537. }
  538. template < typename ArgType, typename Prop, typename Graph, bool Exists >
  539. struct override_property_t
  540. {
  541. typedef ArgType result_type;
  542. result_type operator()(const Graph&,
  543. typename boost::add_lvalue_reference< ArgType >::type a) const
  544. {
  545. return a;
  546. }
  547. };
  548. template < typename ArgType, typename Prop, typename Graph >
  549. struct override_property_t< ArgType, Prop, Graph, false >
  550. {
  551. typedef typename boost::property_map< Graph, Prop >::type result_type;
  552. result_type operator()(const Graph& g, const ArgType&) const
  553. {
  554. return get(Prop(), g);
  555. }
  556. };
  557. template < typename ArgPack, typename Tag, typename Prop, typename Graph >
  558. struct override_property_result
  559. {
  560. typedef typename boost::mpl::has_key< ArgPack, Tag >::type
  561. _parameter_exists;
  562. typedef typename override_property_t<
  563. typename boost::parameter::value_type< ArgPack, Tag, int >::type,
  564. Prop, Graph, _parameter_exists::value >::result_type type;
  565. };
  566. template < typename ArgPack, typename Tag, typename Prop, typename Graph >
  567. typename override_property_result< ArgPack, Tag, Prop, Graph >::type
  568. override_property(const ArgPack& ap,
  569. const boost::parameter::keyword< Tag >& t, const Graph& g, Prop)
  570. {
  571. typedef typename boost::mpl::has_key< ArgPack, Tag >::type
  572. _parameter_exists;
  573. return override_property_t<
  574. typename boost::parameter::value_type< ArgPack, Tag, int >::type,
  575. Prop, Graph, _parameter_exists::value >()(g, ap[t | 0]);
  576. }
  577. template < typename F > struct make_arg_pack_type;
  578. template <> struct make_arg_pack_type< void() >
  579. {
  580. typedef boost::parameter::aux::empty_arg_list type;
  581. };
  582. template < typename K, typename A > struct make_arg_pack_type< void(K, A) >
  583. {
  584. typedef boost::parameter::aux::tagged_argument< K, A > type;
  585. };
  586. #define BOOST_GRAPH_OPENING_PART_OF_PAIR(z, i, n) \
  587. boost::parameter::aux::arg_list \
  588. < boost::parameter::aux::tagged_argument< BOOST_PP_CAT(Keyword, \
  589. BOOST_PP_SUB(n, i)), \
  590. BOOST_PP_CAT(Arg, BOOST_PP_SUB(n, i)) >,
  591. #define BOOST_GRAPH_MAKE_PAIR_PARAM(z, i, _) \
  592. const boost::parameter::aux::tagged_argument< BOOST_PP_CAT(Keyword, i), \
  593. BOOST_PP_CAT(Arg, i) >& BOOST_PP_CAT(kw, i)
  594. #define BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION(z, i, _) \
  595. template < BOOST_PP_ENUM_PARAMS(i, typename Keyword), \
  596. BOOST_PP_ENUM_PARAMS(i, typename Arg) > \
  597. struct make_arg_pack_type< void( \
  598. BOOST_PP_ENUM_PARAMS(i, Keyword), BOOST_PP_ENUM_PARAMS(i, Arg)) > \
  599. { \
  600. typedef BOOST_PP_REPEAT(i, BOOST_GRAPH_OPENING_PART_OF_PAIR, \
  601. BOOST_PP_DEC(i)) boost::parameter::aux::empty_arg_list \
  602. BOOST_PP_REPEAT(i, > BOOST_PP_TUPLE_EAT(3), ~) type; \
  603. };
  604. BOOST_PP_REPEAT_FROM_TO(2, 11, BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION, ~)
  605. #undef BOOST_GRAPH_MAKE_AP_TYPE_SPECIALIZATION
  606. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(name, nfixed, nnamed_max) \
  607. /* Entry point for conversion from BGL-style named parameters */ \
  608. template < BOOST_PP_ENUM_PARAMS(nfixed, typename Param) \
  609. BOOST_PP_COMMA_IF(nfixed) typename ArgPack > \
  610. typename boost::result_of< detail::BOOST_PP_CAT(name, _impl) \
  611. < BOOST_PP_ENUM_PARAMS(nfixed, Param) >(BOOST_PP_ENUM_PARAMS( \
  612. nfixed, Param) BOOST_PP_COMMA_IF(nfixed) const ArgPack&) \
  613. > ::type BOOST_PP_CAT(name, _with_named_params)( \
  614. BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, &param) \
  615. BOOST_PP_COMMA_IF(nfixed) const ArgPack& arg_pack) \
  616. { \
  617. return detail::BOOST_PP_CAT( \
  618. name, _impl)< BOOST_PP_ENUM_PARAMS(nfixed, Param) >()( \
  619. BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) \
  620. arg_pack); \
  621. } \
  622. /* Individual functions taking Boost.Parameter-style keyword arguments */ \
  623. BOOST_PP_REPEAT(BOOST_PP_INC(nnamed_max), \
  624. BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE, (name)(nfixed))
  625. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONE(z, nnamed, seq) \
  626. BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX( \
  627. z, nnamed, BOOST_PP_SEQ_ELEM(0, seq), BOOST_PP_SEQ_ELEM(1, seq))
  628. #define BOOST_GRAPH_MAKE_FORWARDING_FUNCTION_ONEX(z, nnamed, name, nfixed) \
  629. template < BOOST_PP_ENUM_PARAMS_Z(z, nfixed, typename Param) \
  630. BOOST_PP_ENUM_TRAILING_PARAMS_Z( \
  631. z, nnamed, typename ArgumentPack) > \
  632. typename BOOST_PP_EXPR_IF(nnamed, \
  633. boost::lazy_enable_if \
  634. < boost::parameter::is_argument_pack< ArgumentPack0 >) \
  635. BOOST_PP_COMMA_IF(nnamed)::boost::graph::detail::BOOST_PP_CAT( \
  636. name, _impl)< BOOST_PP_ENUM_PARAMS_Z(z, nfixed, Param) > \
  637. BOOST_PP_EXPR_IF(nnamed, >)::type name( \
  638. BOOST_PP_ENUM_BINARY_PARAMS_Z(z, nfixed, Param, const& param) \
  639. BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z( \
  640. z, nnamed, ArgumentPack, const& tagged_arg)) \
  641. { \
  642. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)( \
  643. BOOST_PP_ENUM_PARAMS_Z(z, nfixed, param) BOOST_PP_COMMA_IF(nnamed) \
  644. BOOST_PP_LPAREN_IF(nnamed) BOOST_PP_ENUM_PARAMS_Z( \
  645. z, nnamed, tagged_arg) BOOST_PP_RPAREN_IF(nnamed)); \
  646. }
  647. #define BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(name, nfixed) \
  648. template < BOOST_PP_ENUM_PARAMS(nfixed, typename Param) \
  649. BOOST_PP_COMMA_IF(nfixed) class P, \
  650. class T, class R > \
  651. typename boost::result_of< ::boost::graph::detail::BOOST_PP_CAT( \
  652. name, _impl) BOOST_PP_EXPR_IF(nfixed, <) BOOST_PP_ENUM_PARAMS(nfixed, \
  653. Param) BOOST_PP_EXPR_IF(nfixed, >)(BOOST_PP_ENUM_PARAMS(nfixed, Param) \
  654. BOOST_PP_COMMA_IF(nfixed) const typename boost::detail:: \
  655. convert_bgl_params_to_boost_parameter< \
  656. boost::bgl_named_params< P, T, R > >::type&) >::type \
  657. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, &param) \
  658. BOOST_PP_COMMA_IF(nfixed) \
  659. const boost::bgl_named_params< P, T, R >& old_style_params) \
  660. { \
  661. typedef boost::bgl_named_params< P, T, R > old_style_params_type; \
  662. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS( \
  663. old_style_params_type, old_style_params) \
  664. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)( \
  665. BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) \
  666. arg_pack); \
  667. } \
  668. BOOST_PP_EXPR_IF(nfixed, template < ) \
  669. BOOST_PP_ENUM_PARAMS(nfixed, typename Param) \
  670. BOOST_PP_EXPR_IF(nfixed, >) \
  671. BOOST_PP_EXPR_IF(nfixed, typename) \
  672. boost::result_of< ::boost::graph::detail::BOOST_PP_CAT( \
  673. name, _impl) BOOST_PP_EXPR_IF(nfixed, \
  674. <) BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_EXPR_IF(nfixed, \
  675. >)(BOOST_PP_ENUM_PARAMS(nfixed, Param) BOOST_PP_COMMA_IF(nfixed) \
  676. const boost::parameter::aux::empty_arg_list&) >::type \
  677. name(BOOST_PP_ENUM_BINARY_PARAMS(nfixed, const Param, &param)) \
  678. { \
  679. BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS( \
  680. boost::no_named_parameters, boost::no_named_parameters()) \
  681. return ::boost::graph::BOOST_PP_CAT(name, _with_named_params)( \
  682. BOOST_PP_ENUM_PARAMS(nfixed, param) BOOST_PP_COMMA_IF(nfixed) \
  683. arg_pack); \
  684. }
  685. }
  686. namespace detail
  687. {
  688. template < bool Exists, typename Graph, typename ArgPack, typename Value,
  689. typename PM >
  690. struct map_maker_helper
  691. {
  692. typedef PM map_type;
  693. static PM make_map(const Graph&, Value, const PM& pm, const ArgPack&)
  694. {
  695. return pm;
  696. }
  697. };
  698. template < typename Graph, typename ArgPack, typename Value, typename PM >
  699. struct map_maker_helper< false, Graph, ArgPack, Value, PM >
  700. {
  701. typedef typename boost::mpl::has_key< ArgPack,
  702. boost::graph::keywords::tag::vertex_index_map >::type
  703. _parameter_exists;
  704. typedef
  705. typename boost::remove_const< typename override_const_property_t<
  706. typename boost::parameter::value_type< ArgPack,
  707. boost::graph::keywords::tag::vertex_index_map, int >::type,
  708. boost::vertex_index_t, Graph,
  709. _parameter_exists::value >::result_type >::type vi_map_type;
  710. typedef boost::shared_array_property_map< Value, vi_map_type > map_type;
  711. static map_type make_map(
  712. const Graph& g, Value v, const PM&, const ArgPack& ap)
  713. {
  714. return make_shared_array_property_map(num_vertices(g), v,
  715. override_const_property(ap,
  716. boost::graph::keywords::_vertex_index_map, g,
  717. vertex_index));
  718. }
  719. };
  720. template < typename Graph, typename ArgPack, typename MapTag,
  721. typename ValueType >
  722. struct map_maker
  723. {
  724. typedef typename boost::mpl::has_key< ArgPack, MapTag >::type
  725. _parameter_exists;
  726. BOOST_STATIC_CONSTANT(bool, has_map = (_parameter_exists::value));
  727. typedef map_maker_helper< has_map, Graph, ArgPack, ValueType,
  728. typename boost::remove_const< typename boost::parameter::value_type<
  729. ArgPack, MapTag, int >::type >::type >
  730. helper;
  731. typedef typename helper::map_type map_type;
  732. static map_type make_map(
  733. const Graph& g, const ArgPack& ap, ValueType default_value)
  734. {
  735. return helper::make_map(g, default_value,
  736. ap[::boost::parameter::keyword< MapTag >::instance | 0], ap);
  737. }
  738. };
  739. template < typename MapTag, typename ValueType = void >
  740. class make_property_map_from_arg_pack_gen
  741. {
  742. ValueType default_value;
  743. public:
  744. make_property_map_from_arg_pack_gen(ValueType default_value)
  745. : default_value(default_value)
  746. {
  747. }
  748. template < typename Graph, typename ArgPack >
  749. typename map_maker< Graph, ArgPack, MapTag, ValueType >::map_type
  750. operator()(const Graph& g, const ArgPack& ap) const
  751. {
  752. return map_maker< Graph, ArgPack, MapTag, ValueType >::make_map(
  753. g, ap, default_value);
  754. }
  755. };
  756. template < typename MapTag >
  757. class make_property_map_from_arg_pack_gen< MapTag, void >
  758. {
  759. public:
  760. template < typename ValueType, typename Graph, typename ArgPack >
  761. typename map_maker< Graph, ArgPack, MapTag, ValueType >::map_type
  762. operator()(
  763. const Graph& g, const ArgPack& ap, ValueType default_value) const
  764. {
  765. return map_maker< Graph, ArgPack, MapTag, ValueType >::make_map(
  766. g, ap, default_value);
  767. }
  768. };
  769. static const make_property_map_from_arg_pack_gen<
  770. boost::graph::keywords::tag::color_map, default_color_type >
  771. make_color_map_from_arg_pack(white_color);
  772. template < bool Exists, class Graph, class ArgPack, class KeyT,
  773. class ValueT, class KeyMapTag, class IndexInHeapMapTag, class Compare,
  774. class Q >
  775. struct priority_queue_maker_helper
  776. {
  777. typedef Q priority_queue_type;
  778. static priority_queue_type make_queue(
  779. const Graph&, const ArgPack&, KeyT, const Q& q)
  780. {
  781. return q;
  782. }
  783. };
  784. template < class Graph, class ArgPack, class KeyT, class ValueT,
  785. class KeyMapTag, class IndexInHeapMapTag, class Compare, class Q >
  786. struct priority_queue_maker_helper< false, Graph, ArgPack, KeyT, ValueT,
  787. KeyMapTag, IndexInHeapMapTag, Compare, Q >
  788. {
  789. typedef typename std::vector< ValueT >::size_type
  790. default_index_in_heap_type;
  791. typedef typename map_maker< Graph, ArgPack, IndexInHeapMapTag,
  792. default_index_in_heap_type >::helper::map_type index_in_heap_map;
  793. typedef boost::d_ary_heap_indirect< ValueT, 4, index_in_heap_map,
  794. typename map_maker< Graph, ArgPack, KeyMapTag,
  795. KeyT >::helper::map_type,
  796. Compare >
  797. priority_queue_type;
  798. static priority_queue_type make_queue(
  799. const Graph& g, const ArgPack& ap, KeyT defaultKey, const Q&)
  800. {
  801. return priority_queue_type(
  802. map_maker< Graph, ArgPack, KeyMapTag, KeyT >::make_map(
  803. g, ap, defaultKey),
  804. map_maker< Graph, ArgPack, IndexInHeapMapTag,
  805. default_index_in_heap_type >::make_map(g, ap,
  806. typename boost::property_traits<
  807. index_in_heap_map >::value_type(-1)));
  808. }
  809. };
  810. template < class Graph, class ArgPack, class KeyT, class ValueT,
  811. class PriorityQueueTag, class KeyMapTag, class IndexInHeapMapTag,
  812. class Compare >
  813. struct priority_queue_maker
  814. {
  815. typedef typename boost::mpl::has_key< ArgPack, PriorityQueueTag >::type
  816. _parameter_exists;
  817. BOOST_STATIC_CONSTANT(bool, g_hasQ = (_parameter_exists::value));
  818. typedef boost::reference_wrapper< int > int_refw;
  819. typedef typename boost::parameter::value_type< ArgPack,
  820. PriorityQueueTag, int_refw >::type param_value_type_wrapper;
  821. typedef typename param_value_type_wrapper::type param_value_type;
  822. typedef typename boost::remove_const< param_value_type >::type
  823. param_value_type_no_const;
  824. typedef priority_queue_maker_helper< g_hasQ, Graph, ArgPack, KeyT,
  825. ValueT, KeyMapTag, IndexInHeapMapTag, Compare,
  826. param_value_type_no_const >
  827. helper;
  828. typedef typename helper::priority_queue_type priority_queue_type;
  829. static priority_queue_type make_queue(
  830. const Graph& g, const ArgPack& ap, KeyT defaultKey)
  831. {
  832. return helper::make_queue(g, ap, defaultKey,
  833. ap[::boost::parameter::keyword< PriorityQueueTag >::instance
  834. | 0]);
  835. }
  836. };
  837. template < class PriorityQueueTag, class KeyT, class ValueT,
  838. class Compare = std::less< KeyT >,
  839. class KeyMapTag = boost::graph::keywords::tag::distance_map,
  840. class IndexInHeapMapTag
  841. = boost::graph::keywords::tag::index_in_heap_map >
  842. struct make_priority_queue_from_arg_pack_gen
  843. {
  844. KeyT defaultKey;
  845. make_priority_queue_from_arg_pack_gen(KeyT defaultKey_)
  846. : defaultKey(defaultKey_)
  847. {
  848. }
  849. template < class F > struct result
  850. {
  851. typedef typename remove_const< typename remove_reference<
  852. typename function_traits< F >::arg1_type >::type >::type
  853. graph_type;
  854. typedef typename remove_const< typename remove_reference<
  855. typename function_traits< F >::arg2_type >::type >::type
  856. arg_pack_type;
  857. typedef typename priority_queue_maker< graph_type, arg_pack_type,
  858. KeyT, ValueT, PriorityQueueTag, KeyMapTag, IndexInHeapMapTag,
  859. Compare >::priority_queue_type type;
  860. };
  861. template < class Graph, class ArgPack >
  862. typename priority_queue_maker< Graph, ArgPack, KeyT, ValueT,
  863. PriorityQueueTag, KeyMapTag, IndexInHeapMapTag,
  864. Compare >::priority_queue_type
  865. operator()(const Graph& g, const ArgPack& ap) const
  866. {
  867. return priority_queue_maker< Graph, ArgPack, KeyT, ValueT,
  868. PriorityQueueTag, KeyMapTag, IndexInHeapMapTag,
  869. Compare >::make_queue(g, ap, defaultKey);
  870. }
  871. };
  872. template < typename G >
  873. typename boost::graph_traits< G >::vertex_descriptor get_null_vertex(
  874. const G&)
  875. {
  876. return boost::graph_traits< G >::null_vertex();
  877. }
  878. template < typename G >
  879. typename boost::graph_traits< G >::vertex_descriptor
  880. get_default_starting_vertex(const G& g)
  881. {
  882. std::pair< typename boost::graph_traits< G >::vertex_iterator,
  883. typename boost::graph_traits< G >::vertex_iterator >
  884. iters = vertices(g);
  885. return (iters.first == iters.second)
  886. ? boost::graph_traits< G >::null_vertex()
  887. : *iters.first;
  888. }
  889. template < typename G > struct get_default_starting_vertex_t
  890. {
  891. typedef
  892. typename boost::graph_traits< G >::vertex_descriptor result_type;
  893. const G& g;
  894. get_default_starting_vertex_t(const G& g) : g(g) {}
  895. result_type operator()() const
  896. {
  897. return get_default_starting_vertex(g);
  898. }
  899. };
  900. // Wrapper to avoid instantiating numeric_limits when users provide
  901. // distance_inf value manually
  902. template < typename T > struct get_max
  903. {
  904. T operator()() const { return (std::numeric_limits< T >::max)(); }
  905. typedef T result_type;
  906. };
  907. } // namespace detail
  908. } // namespace boost
  909. #undef BOOST_BGL_DECLARE_NAMED_PARAMS
  910. #endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP