property_holders.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (C) 2007 Douglas Gregor and Matthias Troyer
  2. //
  3. // Use, modification and distribution is subject to the Boost Software
  4. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. //
  6. // This file contains helper data structures for use in transmitting
  7. // properties. The basic idea is to optimize away any storage for the
  8. // properties when no properties are specified.
  9. #ifndef BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
  10. #define BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
  11. #ifndef BOOST_GRAPH_USE_MPI
  12. #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
  13. #endif
  14. #include <boost/mpi/datatype.hpp>
  15. #include <boost/property_map/property_map.hpp>
  16. #include <boost/property_map/parallel/parallel_property_maps.hpp>
  17. #include <boost/serialization/base_object.hpp>
  18. #include <boost/mpl/and.hpp>
  19. #include <boost/graph/parallel/detail/untracked_pair.hpp>
  20. namespace boost { namespace detail { namespace parallel {
  21. /**
  22. * This structure contains an instance of @c Property, unless @c
  23. * Property is a placeholder for "no property". Always access the
  24. * property through @c get_property. Typically used as a base class.
  25. */
  26. template<typename Property>
  27. struct maybe_store_property
  28. {
  29. maybe_store_property() {}
  30. maybe_store_property(const Property& p) : p(p) {}
  31. Property& get_property() { return p; }
  32. const Property& get_property() const { return p; }
  33. private:
  34. Property p;
  35. friend class boost::serialization::access;
  36. template<typename Archiver>
  37. void serialize(Archiver& ar, const unsigned int /*version*/)
  38. {
  39. ar & p;
  40. }
  41. };
  42. template<>
  43. struct maybe_store_property<no_property>
  44. {
  45. maybe_store_property() {}
  46. maybe_store_property(no_property) {}
  47. no_property get_property() const { return no_property(); }
  48. private:
  49. friend class boost::serialization::access;
  50. template<typename Archiver>
  51. void serialize(Archiver&, const unsigned int /*version*/) { }
  52. };
  53. /**
  54. * This structure is a simple pair that also contains a property.
  55. */
  56. template<typename T, typename U, typename Property>
  57. class pair_with_property
  58. : public boost::parallel::detail::untracked_pair<T, U>
  59. , public maybe_store_property<Property>
  60. {
  61. public:
  62. typedef boost::parallel::detail::untracked_pair<T, U> pair_base;
  63. typedef maybe_store_property<Property> property_base;
  64. pair_with_property() { }
  65. pair_with_property(const T& t, const U& u, const Property& property)
  66. : pair_base(t, u), property_base(property) { }
  67. private:
  68. friend class boost::serialization::access;
  69. template<typename Archiver>
  70. void serialize(Archiver& ar, const unsigned int /*version*/)
  71. {
  72. ar & boost::serialization::base_object<pair_base>(*this)
  73. & boost::serialization::base_object<property_base>(*this);
  74. }
  75. };
  76. template<typename T, typename U, typename Property>
  77. inline pair_with_property<T, U, Property>
  78. make_pair_with_property(const T& t, const U& u, const Property& property)
  79. {
  80. return pair_with_property<T, U, Property>(t, u, property);
  81. }
  82. } } } // end namespace boost::parallel::detail
  83. namespace boost { namespace mpi {
  84. template<>
  85. struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<no_property> > : mpl::true_ { };
  86. template<typename Property>
  87. struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<Property> >
  88. : is_mpi_datatype<Property> { };
  89. template<typename T, typename U, typename Property>
  90. struct is_mpi_datatype<boost::detail::parallel::pair_with_property<T, U, Property> >
  91. : boost::mpl::and_<is_mpi_datatype<boost::parallel::detail::untracked_pair<T, U> >,
  92. is_mpi_datatype<Property> > { };
  93. } } // end namespace boost::mpi
  94. BOOST_IS_BITWISE_SERIALIZABLE(boost::detail::parallel::maybe_store_property<no_property>)
  95. namespace boost { namespace serialization {
  96. template<typename Property>
  97. struct is_bitwise_serializable<boost::detail::parallel::maybe_store_property<Property> >
  98. : is_bitwise_serializable<Property> { };
  99. template<typename Property>
  100. struct implementation_level<boost::detail::parallel::maybe_store_property<Property> >
  101. : mpl::int_<object_serializable> {} ;
  102. template<typename Property>
  103. struct tracking_level<boost::detail::parallel::maybe_store_property<Property> >
  104. : mpl::int_<track_never> {} ;
  105. template<typename T, typename U, typename Property>
  106. struct is_bitwise_serializable<
  107. boost::detail::parallel::pair_with_property<T, U, Property> >
  108. : boost::mpl::and_<is_bitwise_serializable<boost::parallel::detail::untracked_pair<T, U> >,
  109. is_bitwise_serializable<Property> > { };
  110. template<typename T, typename U, typename Property>
  111. struct implementation_level<
  112. boost::detail::parallel::pair_with_property<T, U, Property> >
  113. : mpl::int_<object_serializable> {} ;
  114. template<typename T, typename U, typename Property>
  115. struct tracking_level<
  116. boost::detail::parallel::pair_with_property<T, U, Property> >
  117. : mpl::int_<track_never> {} ;
  118. } } // end namespace boost::serialization
  119. #endif // BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP