property_map.hpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. // (C) Copyright Jeremy Siek 1999-2001.
  2. // Copyright (C) 2006 Trustees of Indiana University
  3. // Authors: Douglas Gregor and Jeremy Siek
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/libs/property_map for documentation.
  8. #ifndef BOOST_PROPERTY_MAP_HPP
  9. #define BOOST_PROPERTY_MAP_HPP
  10. #include <boost/assert.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/static_assert.hpp>
  13. #include <boost/pending/cstddef.hpp>
  14. #include <boost/detail/iterator.hpp>
  15. #include <boost/concept_check.hpp>
  16. #include <boost/concept_archetype.hpp>
  17. #include <boost/mpl/assert.hpp>
  18. #include <boost/mpl/or.hpp>
  19. #include <boost/mpl/and.hpp>
  20. #include <boost/mpl/has_xxx.hpp>
  21. #include <boost/type_traits/is_same.hpp>
  22. namespace boost {
  23. //=========================================================================
  24. // property_traits class
  25. BOOST_MPL_HAS_XXX_TRAIT_DEF(key_type)
  26. BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
  27. BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
  28. BOOST_MPL_HAS_XXX_TRAIT_DEF(category)
  29. template<class PA>
  30. struct is_property_map :
  31. boost::mpl::and_<
  32. has_key_type<PA>,
  33. has_value_type<PA>,
  34. has_reference<PA>,
  35. has_category<PA>
  36. >
  37. {};
  38. template <typename PA>
  39. struct default_property_traits {
  40. typedef typename PA::key_type key_type;
  41. typedef typename PA::value_type value_type;
  42. typedef typename PA::reference reference;
  43. typedef typename PA::category category;
  44. };
  45. struct null_property_traits {};
  46. template <typename PA>
  47. struct property_traits :
  48. boost::mpl::if_<is_property_map<PA>,
  49. default_property_traits<PA>,
  50. null_property_traits>::type
  51. {};
  52. #if 0
  53. template <typename PA>
  54. struct property_traits {
  55. typedef typename PA::key_type key_type;
  56. typedef typename PA::value_type value_type;
  57. typedef typename PA::reference reference;
  58. typedef typename PA::category category;
  59. };
  60. #endif
  61. //=========================================================================
  62. // property_traits category tags
  63. namespace detail {
  64. enum ePropertyMapID { READABLE_PA, WRITABLE_PA,
  65. READ_WRITE_PA, LVALUE_PA, OP_BRACKET_PA,
  66. RAND_ACCESS_ITER_PA, LAST_PA };
  67. }
  68. struct readable_property_map_tag { enum { id = detail::READABLE_PA }; };
  69. struct writable_property_map_tag { enum { id = detail::WRITABLE_PA }; };
  70. struct read_write_property_map_tag :
  71. public readable_property_map_tag,
  72. public writable_property_map_tag
  73. { enum { id = detail::READ_WRITE_PA }; };
  74. struct lvalue_property_map_tag : public read_write_property_map_tag
  75. { enum { id = detail::LVALUE_PA }; };
  76. //=========================================================================
  77. // property_traits specialization for pointers
  78. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  79. // The user will just have to create their own specializations for
  80. // other pointers types if the compiler does not have partial
  81. // specializations. Sorry!
  82. #define BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(TYPE) \
  83. template <> \
  84. struct property_traits<TYPE*> { \
  85. typedef TYPE value_type; \
  86. typedef value_type& reference; \
  87. typedef std::ptrdiff_t key_type; \
  88. typedef lvalue_property_map_tag category; \
  89. }; \
  90. template <> \
  91. struct property_traits<const TYPE*> { \
  92. typedef TYPE value_type; \
  93. typedef const value_type& reference; \
  94. typedef std::ptrdiff_t key_type; \
  95. typedef lvalue_property_map_tag category; \
  96. }
  97. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(long);
  98. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned long);
  99. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(int);
  100. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned int);
  101. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(short);
  102. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned short);
  103. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(char);
  104. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned char);
  105. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(signed char);
  106. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(bool);
  107. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(float);
  108. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(double);
  109. BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(long double);
  110. // This may need to be turned off for some older compilers that don't have
  111. // wchar_t intrinsically.
  112. # ifndef BOOST_NO_INTRINSIC_WCHAR_T
  113. template <>
  114. struct property_traits<wchar_t*> {
  115. typedef wchar_t value_type;
  116. typedef value_type& reference;
  117. typedef std::ptrdiff_t key_type;
  118. typedef lvalue_property_map_tag category;
  119. };
  120. template <>
  121. struct property_traits<const wchar_t*> {
  122. typedef wchar_t value_type;
  123. typedef const value_type& reference;
  124. typedef std::ptrdiff_t key_type;
  125. typedef lvalue_property_map_tag category;
  126. };
  127. # endif
  128. #else
  129. template <class T>
  130. struct property_traits<T*> {
  131. // BOOST_STATIC_ASSERT(boost::is_same<T, T*>::value && !"Using pointers as property maps is deprecated");
  132. typedef T value_type;
  133. typedef value_type& reference;
  134. typedef std::ptrdiff_t key_type;
  135. typedef lvalue_property_map_tag category;
  136. };
  137. template <class T>
  138. struct property_traits<const T*> {
  139. // BOOST_STATIC_ASSERT(boost::is_same<T, T*>::value && !"Using pointers as property maps is deprecated");
  140. typedef T value_type;
  141. typedef const value_type& reference;
  142. typedef std::ptrdiff_t key_type;
  143. typedef lvalue_property_map_tag category;
  144. };
  145. #endif
  146. #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  147. // MSVC doesn't have Koenig lookup, so the user has to
  148. // do boost::get() anyways, and the using clause
  149. // doesn't really work for MSVC.
  150. } // namespace boost
  151. #endif
  152. // These need to go in global namespace because Koenig
  153. // lookup does not apply to T*.
  154. // V must be convertible to T
  155. template <class T, class V>
  156. inline void put(T* pa, std::ptrdiff_t k, const V& val) { pa[k] = val; }
  157. template <class T>
  158. inline const T& get(const T* pa, std::ptrdiff_t k) { return pa[k]; }
  159. #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  160. namespace boost {
  161. using ::put;
  162. using ::get;
  163. #endif
  164. //=========================================================================
  165. // concept checks for property maps
  166. template <class PMap, class Key>
  167. struct ReadablePropertyMapConcept
  168. {
  169. typedef typename property_traits<PMap>::key_type key_type;
  170. typedef typename property_traits<PMap>::reference reference;
  171. typedef typename property_traits<PMap>::category Category;
  172. typedef boost::readable_property_map_tag ReadableTag;
  173. void constraints() {
  174. function_requires< ConvertibleConcept<Category, ReadableTag> >();
  175. val = get(pmap, k);
  176. }
  177. PMap pmap;
  178. Key k;
  179. typename property_traits<PMap>::value_type val;
  180. };
  181. template <typename KeyArchetype, typename ValueArchetype>
  182. struct readable_property_map_archetype {
  183. typedef KeyArchetype key_type;
  184. typedef ValueArchetype value_type;
  185. typedef convertible_to_archetype<ValueArchetype> reference;
  186. typedef readable_property_map_tag category;
  187. };
  188. template <typename K, typename V>
  189. const typename readable_property_map_archetype<K,V>::reference&
  190. get(const readable_property_map_archetype<K,V>&,
  191. const typename readable_property_map_archetype<K,V>::key_type&)
  192. {
  193. typedef typename readable_property_map_archetype<K,V>::reference R;
  194. return static_object<R>::get();
  195. }
  196. template <class PMap, class Key>
  197. struct WritablePropertyMapConcept
  198. {
  199. typedef typename property_traits<PMap>::key_type key_type;
  200. typedef typename property_traits<PMap>::category Category;
  201. typedef boost::writable_property_map_tag WritableTag;
  202. void constraints() {
  203. function_requires< ConvertibleConcept<Category, WritableTag> >();
  204. put(pmap, k, val);
  205. }
  206. PMap pmap;
  207. Key k;
  208. typename property_traits<PMap>::value_type val;
  209. };
  210. template <typename KeyArchetype, typename ValueArchetype>
  211. struct writable_property_map_archetype {
  212. typedef KeyArchetype key_type;
  213. typedef ValueArchetype value_type;
  214. typedef void reference;
  215. typedef writable_property_map_tag category;
  216. };
  217. template <typename K, typename V>
  218. void put(const writable_property_map_archetype<K,V>&,
  219. const typename writable_property_map_archetype<K,V>::key_type&,
  220. const typename writable_property_map_archetype<K,V>::value_type&) { }
  221. template <class PMap, class Key>
  222. struct ReadWritePropertyMapConcept
  223. {
  224. typedef typename property_traits<PMap>::category Category;
  225. typedef boost::read_write_property_map_tag ReadWriteTag;
  226. void constraints() {
  227. function_requires< ReadablePropertyMapConcept<PMap, Key> >();
  228. function_requires< WritablePropertyMapConcept<PMap, Key> >();
  229. function_requires< ConvertibleConcept<Category, ReadWriteTag> >();
  230. }
  231. };
  232. template <typename KeyArchetype, typename ValueArchetype>
  233. struct read_write_property_map_archetype
  234. : public readable_property_map_archetype<KeyArchetype, ValueArchetype>,
  235. public writable_property_map_archetype<KeyArchetype, ValueArchetype>
  236. {
  237. typedef KeyArchetype key_type;
  238. typedef ValueArchetype value_type;
  239. typedef convertible_to_archetype<ValueArchetype> reference;
  240. typedef read_write_property_map_tag category;
  241. };
  242. template <class PMap, class Key>
  243. struct LvaluePropertyMapConcept
  244. {
  245. typedef typename property_traits<PMap>::category Category;
  246. typedef boost::lvalue_property_map_tag LvalueTag;
  247. typedef typename property_traits<PMap>::reference reference;
  248. void constraints() {
  249. function_requires< ReadablePropertyMapConcept<PMap, Key> >();
  250. function_requires< ConvertibleConcept<Category, LvalueTag> >();
  251. typedef typename property_traits<PMap>::value_type value_type;
  252. BOOST_MPL_ASSERT((boost::mpl::or_<
  253. boost::is_same<const value_type&, reference>,
  254. boost::is_same<value_type&, reference> >));
  255. reference ref = pmap[k];
  256. ignore_unused_variable_warning(ref);
  257. }
  258. PMap pmap;
  259. Key k;
  260. };
  261. template <typename KeyArchetype, typename ValueArchetype>
  262. struct lvalue_property_map_archetype
  263. : public readable_property_map_archetype<KeyArchetype, ValueArchetype>
  264. {
  265. typedef KeyArchetype key_type;
  266. typedef ValueArchetype value_type;
  267. typedef const ValueArchetype& reference;
  268. typedef lvalue_property_map_tag category;
  269. const value_type& operator[](const key_type&) const {
  270. return static_object<value_type>::get();
  271. }
  272. };
  273. template <class PMap, class Key>
  274. struct Mutable_LvaluePropertyMapConcept
  275. {
  276. typedef typename property_traits<PMap>::category Category;
  277. typedef boost::lvalue_property_map_tag LvalueTag;
  278. typedef typename property_traits<PMap>::reference reference;
  279. void constraints() {
  280. boost::function_requires< ReadWritePropertyMapConcept<PMap, Key> >();
  281. boost::function_requires<ConvertibleConcept<Category, LvalueTag> >();
  282. typedef typename property_traits<PMap>::value_type value_type;
  283. BOOST_MPL_ASSERT((boost::is_same<value_type&, reference>));
  284. reference ref = pmap[k];
  285. ignore_unused_variable_warning(ref);
  286. }
  287. PMap pmap;
  288. Key k;
  289. };
  290. template <typename KeyArchetype, typename ValueArchetype>
  291. struct mutable_lvalue_property_map_archetype
  292. : public readable_property_map_archetype<KeyArchetype, ValueArchetype>,
  293. public writable_property_map_archetype<KeyArchetype, ValueArchetype>
  294. {
  295. typedef KeyArchetype key_type;
  296. typedef ValueArchetype value_type;
  297. typedef ValueArchetype& reference;
  298. typedef lvalue_property_map_tag category;
  299. value_type& operator[](const key_type&) const {
  300. return static_object<value_type>::get();
  301. }
  302. };
  303. template <typename T>
  304. struct typed_identity_property_map;
  305. // A helper class for constructing a property map
  306. // from a class that implements operator[]
  307. template <class Reference, class LvaluePropertyMap>
  308. struct put_get_helper { };
  309. template <class PropertyMap, class Reference, class K>
  310. inline Reference
  311. get(const put_get_helper<Reference, PropertyMap>& pa, const K& k)
  312. {
  313. Reference v = static_cast<const PropertyMap&>(pa)[k];
  314. return v;
  315. }
  316. template <class PropertyMap, class Reference, class K, class V>
  317. inline void
  318. put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v)
  319. {
  320. static_cast<const PropertyMap&>(pa)[k] = v;
  321. }
  322. //=========================================================================
  323. // Adapter to turn a RandomAccessIterator into a property map
  324. template <class RandomAccessIterator,
  325. class IndexMap
  326. #ifdef BOOST_NO_STD_ITERATOR_TRAITS
  327. , class T, class R
  328. #else
  329. , class T = typename std::iterator_traits<RandomAccessIterator>::value_type
  330. , class R = typename std::iterator_traits<RandomAccessIterator>::reference
  331. #endif
  332. >
  333. class iterator_property_map
  334. : public boost::put_get_helper< R,
  335. iterator_property_map<RandomAccessIterator, IndexMap,
  336. T, R> >
  337. {
  338. public:
  339. typedef typename property_traits<IndexMap>::key_type key_type;
  340. typedef T value_type;
  341. typedef R reference;
  342. typedef boost::lvalue_property_map_tag category;
  343. inline iterator_property_map(
  344. RandomAccessIterator cc = RandomAccessIterator(),
  345. const IndexMap& _id = IndexMap() )
  346. : iter(cc), index(_id) { }
  347. inline R operator[](key_type v) const { return *(iter + get(index, v)) ; }
  348. protected:
  349. RandomAccessIterator iter;
  350. IndexMap index;
  351. };
  352. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  353. template <class RAIter, class ID>
  354. inline iterator_property_map<
  355. RAIter, ID,
  356. typename std::iterator_traits<RAIter>::value_type,
  357. typename std::iterator_traits<RAIter>::reference>
  358. make_iterator_property_map(RAIter iter, ID id) {
  359. function_requires< RandomAccessIteratorConcept<RAIter> >();
  360. typedef iterator_property_map<
  361. RAIter, ID,
  362. typename std::iterator_traits<RAIter>::value_type,
  363. typename std::iterator_traits<RAIter>::reference> PA;
  364. return PA(iter, id);
  365. }
  366. #endif
  367. template <class RAIter, class Value, class ID>
  368. inline iterator_property_map<RAIter, ID, Value, Value&>
  369. make_iterator_property_map(RAIter iter, ID id, Value) {
  370. function_requires< RandomAccessIteratorConcept<RAIter> >();
  371. typedef iterator_property_map<RAIter, ID, Value, Value&> PMap;
  372. return PMap(iter, id);
  373. }
  374. template <class RandomAccessIterator,
  375. class IndexMap
  376. #ifdef BOOST_NO_STD_ITERATOR_TRAITS
  377. , class T, class R
  378. #else
  379. , class T = typename std::iterator_traits<RandomAccessIterator>::value_type
  380. , class R = typename std::iterator_traits<RandomAccessIterator>::reference
  381. #endif
  382. >
  383. class safe_iterator_property_map
  384. : public boost::put_get_helper< R,
  385. safe_iterator_property_map<RandomAccessIterator, IndexMap,
  386. T, R> >
  387. {
  388. public:
  389. typedef typename property_traits<IndexMap>::key_type key_type;
  390. typedef T value_type;
  391. typedef R reference;
  392. typedef boost::lvalue_property_map_tag category;
  393. inline safe_iterator_property_map(
  394. RandomAccessIterator first,
  395. std::size_t n_ = 0,
  396. const IndexMap& _id = IndexMap() )
  397. : iter(first), n(n_), index(_id) { }
  398. inline safe_iterator_property_map() { }
  399. inline R operator[](key_type v) const {
  400. BOOST_ASSERT(get(index, v) < n);
  401. return *(iter + get(index, v)) ;
  402. }
  403. typename property_traits<IndexMap>::value_type size() const { return n; }
  404. protected:
  405. RandomAccessIterator iter;
  406. typename property_traits<IndexMap>::value_type n;
  407. IndexMap index;
  408. };
  409. #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  410. template <class RAIter, class ID>
  411. inline safe_iterator_property_map<
  412. RAIter, ID,
  413. typename boost::detail::iterator_traits<RAIter>::value_type,
  414. typename boost::detail::iterator_traits<RAIter>::reference>
  415. make_safe_iterator_property_map(RAIter iter, std::size_t n, ID id) {
  416. function_requires< RandomAccessIteratorConcept<RAIter> >();
  417. typedef safe_iterator_property_map<
  418. RAIter, ID,
  419. typename boost::detail::iterator_traits<RAIter>::value_type,
  420. typename boost::detail::iterator_traits<RAIter>::reference> PA;
  421. return PA(iter, n, id);
  422. }
  423. #endif
  424. template <class RAIter, class Value, class ID>
  425. inline safe_iterator_property_map<RAIter, ID, Value, Value&>
  426. make_safe_iterator_property_map(RAIter iter, std::size_t n, ID id, Value) {
  427. function_requires< RandomAccessIteratorConcept<RAIter> >();
  428. typedef safe_iterator_property_map<RAIter, ID, Value, Value&> PMap;
  429. return PMap(iter, n, id);
  430. }
  431. //=========================================================================
  432. // An adaptor to turn a Unique Pair Associative Container like std::map or
  433. // std::hash_map into an Lvalue Property Map.
  434. template <typename UniquePairAssociativeContainer>
  435. class associative_property_map
  436. : public boost::put_get_helper<
  437. typename UniquePairAssociativeContainer::value_type::second_type&,
  438. associative_property_map<UniquePairAssociativeContainer> >
  439. {
  440. typedef UniquePairAssociativeContainer C;
  441. public:
  442. typedef typename C::key_type key_type;
  443. typedef typename C::value_type::second_type value_type;
  444. typedef value_type& reference;
  445. typedef lvalue_property_map_tag category;
  446. associative_property_map() : m_c(0) { }
  447. associative_property_map(C& c) : m_c(&c) { }
  448. reference operator[](const key_type& k) const {
  449. return (*m_c)[k];
  450. }
  451. private:
  452. C* m_c;
  453. };
  454. template <class UniquePairAssociativeContainer>
  455. associative_property_map<UniquePairAssociativeContainer>
  456. make_assoc_property_map(UniquePairAssociativeContainer& c)
  457. {
  458. return associative_property_map<UniquePairAssociativeContainer>(c);
  459. }
  460. template <typename UniquePairAssociativeContainer>
  461. class const_associative_property_map
  462. : public boost::put_get_helper<
  463. const typename UniquePairAssociativeContainer::value_type::second_type&,
  464. const_associative_property_map<UniquePairAssociativeContainer> >
  465. {
  466. typedef UniquePairAssociativeContainer C;
  467. public:
  468. typedef typename C::key_type key_type;
  469. typedef typename C::value_type::second_type value_type;
  470. typedef const value_type& reference;
  471. typedef lvalue_property_map_tag category;
  472. const_associative_property_map() : m_c(0) { }
  473. const_associative_property_map(const C& c) : m_c(&c) { }
  474. reference operator[](const key_type& k) const {
  475. return m_c->find(k)->second;
  476. }
  477. private:
  478. C const* m_c;
  479. };
  480. template <class UniquePairAssociativeContainer>
  481. const_associative_property_map<UniquePairAssociativeContainer>
  482. make_assoc_property_map(const UniquePairAssociativeContainer& c)
  483. {
  484. return const_associative_property_map<UniquePairAssociativeContainer>(c);
  485. }
  486. //=========================================================================
  487. // A property map that always returns the same object by value.
  488. //
  489. template <typename ValueType>
  490. class static_property_map :
  491. public
  492. boost::put_get_helper<ValueType,static_property_map<ValueType> >
  493. {
  494. ValueType value;
  495. public:
  496. typedef void key_type;
  497. typedef ValueType value_type;
  498. typedef ValueType reference;
  499. typedef readable_property_map_tag category;
  500. static_property_map(ValueType v) : value(v) {}
  501. template<typename T>
  502. inline reference operator[](T) const { return value; }
  503. };
  504. //=========================================================================
  505. // A property map that always returns a reference to the same object.
  506. //
  507. template <typename KeyType, typename ValueType>
  508. class ref_property_map :
  509. public
  510. boost::put_get_helper<ValueType&,ref_property_map<KeyType,ValueType> >
  511. {
  512. ValueType* value;
  513. public:
  514. typedef KeyType key_type;
  515. typedef ValueType value_type;
  516. typedef ValueType& reference;
  517. typedef lvalue_property_map_tag category;
  518. ref_property_map(ValueType& v) : value(&v) {}
  519. ValueType& operator[](key_type const&) const { return *value; }
  520. };
  521. //=========================================================================
  522. // A generalized identity property map
  523. template <typename T>
  524. struct typed_identity_property_map
  525. : public boost::put_get_helper<T, typed_identity_property_map<T> >
  526. {
  527. typedef T key_type;
  528. typedef T value_type;
  529. typedef T reference;
  530. typedef boost::readable_property_map_tag category;
  531. inline value_type operator[](const key_type& v) const { return v; }
  532. };
  533. //=========================================================================
  534. // A property map that applies the identity function to integers
  535. typedef typed_identity_property_map<std::size_t> identity_property_map;
  536. //=========================================================================
  537. // A property map that does not do anything, for
  538. // when you have to supply a property map, but don't need it.
  539. namespace detail {
  540. struct dummy_pmap_reference {
  541. template <class T>
  542. dummy_pmap_reference& operator=(const T&) { return *this; }
  543. operator int() { return 0; }
  544. };
  545. }
  546. class dummy_property_map
  547. : public boost::put_get_helper<detail::dummy_pmap_reference,
  548. dummy_property_map >
  549. {
  550. public:
  551. typedef void key_type;
  552. typedef int value_type;
  553. typedef detail::dummy_pmap_reference reference;
  554. typedef boost::read_write_property_map_tag category;
  555. inline dummy_property_map() : c(0) { }
  556. inline dummy_property_map(value_type cc) : c(cc) { }
  557. inline dummy_property_map(const dummy_property_map& x)
  558. : c(x.c) { }
  559. template <class Vertex>
  560. inline reference operator[](Vertex) const { return reference(); }
  561. protected:
  562. value_type c;
  563. };
  564. // Convert a Readable property map into a function object
  565. template <typename PropMap>
  566. class property_map_function {
  567. PropMap pm;
  568. typedef typename property_traits<PropMap>::key_type param_type;
  569. public:
  570. explicit property_map_function(const PropMap& pm): pm(pm) {}
  571. typedef typename property_traits<PropMap>::value_type result_type;
  572. result_type operator()(const param_type& k) const {return get(pm, k);}
  573. };
  574. template <typename PropMap>
  575. property_map_function<PropMap>
  576. make_property_map_function(const PropMap& pm) {
  577. return property_map_function<PropMap>(pm);
  578. }
  579. } // namespace boost
  580. #ifdef BOOST_GRAPH_USE_MPI
  581. #include <boost/property_map/parallel/distributed_property_map.hpp>
  582. #include <boost/property_map/parallel/local_property_map.hpp>
  583. namespace boost {
  584. /** Distributed iterator property map.
  585. *
  586. * This specialization of @ref iterator_property_map builds a
  587. * distributed iterator property map given the local index maps
  588. * generated by distributed graph types that automatically have index
  589. * properties.
  590. *
  591. * This specialization is useful when creating external distributed
  592. * property maps via the same syntax used to create external
  593. * sequential property maps.
  594. */
  595. template<typename RandomAccessIterator, typename ProcessGroup,
  596. typename GlobalMap, typename StorageMap,
  597. typename ValueType, typename Reference>
  598. class iterator_property_map
  599. <RandomAccessIterator,
  600. local_property_map<ProcessGroup, GlobalMap, StorageMap>,
  601. ValueType, Reference>
  602. : public parallel::distributed_property_map
  603. <ProcessGroup,
  604. GlobalMap,
  605. iterator_property_map<RandomAccessIterator, StorageMap,
  606. ValueType, Reference> >
  607. {
  608. typedef iterator_property_map<RandomAccessIterator, StorageMap,
  609. ValueType, Reference> local_iterator_map;
  610. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  611. local_iterator_map> inherited;
  612. typedef local_property_map<ProcessGroup, GlobalMap, StorageMap>
  613. index_map_type;
  614. typedef iterator_property_map self_type;
  615. public:
  616. iterator_property_map() { }
  617. iterator_property_map(RandomAccessIterator cc, const index_map_type& id)
  618. : inherited(id.process_group(), id.global(),
  619. local_iterator_map(cc, id.base())) { }
  620. };
  621. /** Distributed iterator property map.
  622. *
  623. * This specialization of @ref iterator_property_map builds a
  624. * distributed iterator property map given a distributed index
  625. * map. Only the local portion of the distributed index property map
  626. * is utilized.
  627. *
  628. * This specialization is useful when creating external distributed
  629. * property maps via the same syntax used to create external
  630. * sequential property maps.
  631. */
  632. template<typename RandomAccessIterator, typename ProcessGroup,
  633. typename GlobalMap, typename StorageMap,
  634. typename ValueType, typename Reference>
  635. class iterator_property_map<
  636. RandomAccessIterator,
  637. parallel::distributed_property_map<ProcessGroup,GlobalMap,StorageMap>,
  638. ValueType, Reference
  639. >
  640. : public parallel::distributed_property_map
  641. <ProcessGroup,
  642. GlobalMap,
  643. iterator_property_map<RandomAccessIterator, StorageMap,
  644. ValueType, Reference> >
  645. {
  646. typedef iterator_property_map<RandomAccessIterator, StorageMap,
  647. ValueType, Reference> local_iterator_map;
  648. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  649. local_iterator_map> inherited;
  650. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  651. StorageMap>
  652. index_map_type;
  653. public:
  654. iterator_property_map() { }
  655. iterator_property_map(RandomAccessIterator cc, const index_map_type& id)
  656. : inherited(id.process_group(), id.global(),
  657. local_iterator_map(cc, id.base())) { }
  658. };
  659. namespace parallel {
  660. // Generate an iterator property map with a specific kind of ghost
  661. // cells
  662. template<typename RandomAccessIterator, typename ProcessGroup,
  663. typename GlobalMap, typename StorageMap>
  664. distributed_property_map<ProcessGroup,
  665. GlobalMap,
  666. iterator_property_map<RandomAccessIterator,
  667. StorageMap> >
  668. make_iterator_property_map(RandomAccessIterator cc,
  669. local_property_map<ProcessGroup, GlobalMap,
  670. StorageMap> index_map)
  671. {
  672. typedef distributed_property_map<
  673. ProcessGroup, GlobalMap,
  674. iterator_property_map<RandomAccessIterator, StorageMap> >
  675. result_type;
  676. return result_type(index_map.process_group(), index_map.global(),
  677. make_iterator_property_map(cc, index_map.base()));
  678. }
  679. } // end namespace parallel
  680. /** Distributed safe iterator property map.
  681. *
  682. * This specialization of @ref safe_iterator_property_map builds a
  683. * distributed iterator property map given the local index maps
  684. * generated by distributed graph types that automatically have index
  685. * properties.
  686. *
  687. * This specialization is useful when creating external distributed
  688. * property maps via the same syntax used to create external
  689. * sequential property maps.
  690. */
  691. template<typename RandomAccessIterator, typename ProcessGroup,
  692. typename GlobalMap, typename StorageMap, typename ValueType,
  693. typename Reference>
  694. class safe_iterator_property_map
  695. <RandomAccessIterator,
  696. local_property_map<ProcessGroup, GlobalMap, StorageMap>,
  697. ValueType, Reference>
  698. : public parallel::distributed_property_map
  699. <ProcessGroup,
  700. GlobalMap,
  701. safe_iterator_property_map<RandomAccessIterator, StorageMap,
  702. ValueType, Reference> >
  703. {
  704. typedef safe_iterator_property_map<RandomAccessIterator, StorageMap,
  705. ValueType, Reference> local_iterator_map;
  706. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  707. local_iterator_map> inherited;
  708. typedef local_property_map<ProcessGroup, GlobalMap, StorageMap> index_map_type;
  709. public:
  710. safe_iterator_property_map() { }
  711. safe_iterator_property_map(RandomAccessIterator cc, std::size_t n,
  712. const index_map_type& id)
  713. : inherited(id.process_group(), id.global(),
  714. local_iterator_map(cc, n, id.base())) { }
  715. };
  716. /** Distributed safe iterator property map.
  717. *
  718. * This specialization of @ref safe_iterator_property_map builds a
  719. * distributed iterator property map given a distributed index
  720. * map. Only the local portion of the distributed index property map
  721. * is utilized.
  722. *
  723. * This specialization is useful when creating external distributed
  724. * property maps via the same syntax used to create external
  725. * sequential property maps.
  726. */
  727. template<typename RandomAccessIterator, typename ProcessGroup,
  728. typename GlobalMap, typename StorageMap,
  729. typename ValueType, typename Reference>
  730. class safe_iterator_property_map<
  731. RandomAccessIterator,
  732. parallel::distributed_property_map<ProcessGroup,GlobalMap,StorageMap>,
  733. ValueType, Reference>
  734. : public parallel::distributed_property_map
  735. <ProcessGroup,
  736. GlobalMap,
  737. safe_iterator_property_map<RandomAccessIterator, StorageMap,
  738. ValueType, Reference> >
  739. {
  740. typedef safe_iterator_property_map<RandomAccessIterator, StorageMap,
  741. ValueType, Reference> local_iterator_map;
  742. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  743. local_iterator_map> inherited;
  744. typedef parallel::distributed_property_map<ProcessGroup, GlobalMap,
  745. StorageMap>
  746. index_map_type;
  747. public:
  748. safe_iterator_property_map() { }
  749. safe_iterator_property_map(RandomAccessIterator cc, std::size_t n,
  750. const index_map_type& id)
  751. : inherited(id.process_group(), id.global(),
  752. local_iterator_map(cc, n, id.base())) { }
  753. };
  754. }
  755. #endif // BOOST_GRAPH_USE_MPI
  756. #include <boost/property_map/vector_property_map.hpp>
  757. #endif /* BOOST_PROPERTY_MAP_HPP */