property_holders.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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/serialization/base_object.hpp>
  17. #include <boost/mpl/and.hpp>
  18. #include <boost/graph/parallel/detail/untracked_pair.hpp>
  19. namespace boost { namespace detail { namespace parallel {
  20. /**
  21. * This structure contains an instance of @c Property, unless @c
  22. * Property is a placeholder for "no property". Always access the
  23. * property through @c get_property. Typically used as a base class.
  24. */
  25. template<typename Property>
  26. struct maybe_store_property
  27. {
  28. maybe_store_property() {}
  29. maybe_store_property(const Property& p) : p(p) {}
  30. Property& get_property() { return p; }
  31. const Property& get_property() const { return p; }
  32. private:
  33. Property p;
  34. friend class boost::serialization::access;
  35. template<typename Archiver>
  36. void serialize(Archiver& ar, const unsigned int /*version*/)
  37. {
  38. ar & p;
  39. }
  40. };
  41. template<>
  42. struct maybe_store_property<no_property>
  43. {
  44. maybe_store_property() {}
  45. maybe_store_property(no_property) {}
  46. no_property get_property() const { return no_property(); }
  47. private:
  48. friend class boost::serialization::access;
  49. template<typename Archiver>
  50. void serialize(Archiver&, const unsigned int /*version*/) { }
  51. };
  52. /**
  53. * This structure is a simple pair that also contains a property.
  54. */
  55. template<typename T, typename U, typename Property>
  56. class pair_with_property
  57. : public boost::parallel::detail::untracked_pair<T, U>
  58. , public maybe_store_property<Property>
  59. {
  60. public:
  61. typedef boost::parallel::detail::untracked_pair<T, U> pair_base;
  62. typedef maybe_store_property<Property> property_base;
  63. pair_with_property() { }
  64. pair_with_property(const T& t, const U& u, const Property& property)
  65. : pair_base(t, u), property_base(property) { }
  66. private:
  67. friend class boost::serialization::access;
  68. template<typename Archiver>
  69. void serialize(Archiver& ar, const unsigned int /*version*/)
  70. {
  71. ar & boost::serialization::base_object<pair_base>(*this)
  72. & boost::serialization::base_object<property_base>(*this);
  73. }
  74. };
  75. template<typename T, typename U, typename Property>
  76. inline pair_with_property<T, U, Property>
  77. make_pair_with_property(const T& t, const U& u, const Property& property)
  78. {
  79. return pair_with_property<T, U, Property>(t, u, property);
  80. }
  81. } } } // end namespace boost::parallel::detail
  82. namespace boost { namespace mpi {
  83. template<>
  84. struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<no_property> > : mpl::true_ { };
  85. template<typename Property>
  86. struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<Property> >
  87. : is_mpi_datatype<Property> { };
  88. template<typename T, typename U, typename Property>
  89. struct is_mpi_datatype<boost::detail::parallel::pair_with_property<T, U, Property> >
  90. : boost::mpl::and_<is_mpi_datatype<boost::parallel::detail::untracked_pair<T, U> >,
  91. is_mpi_datatype<Property> > { };
  92. } } // end namespace boost::mpi
  93. BOOST_IS_BITWISE_SERIALIZABLE(boost::detail::parallel::maybe_store_property<no_property>)
  94. namespace boost { namespace serialization {
  95. template<typename Property>
  96. struct is_bitwise_serializable<boost::detail::parallel::maybe_store_property<Property> >
  97. : is_bitwise_serializable<Property> { };
  98. template<typename Property>
  99. struct implementation_level<boost::detail::parallel::maybe_store_property<Property> >
  100. : mpl::int_<object_serializable> {} ;
  101. template<typename Property>
  102. struct tracking_level<boost::detail::parallel::maybe_store_property<Property> >
  103. : mpl::int_<track_never> {} ;
  104. template<typename T, typename U, typename Property>
  105. struct is_bitwise_serializable<
  106. boost::detail::parallel::pair_with_property<T, U, Property> >
  107. : boost::mpl::and_<is_bitwise_serializable<boost::parallel::detail::untracked_pair<T, U> >,
  108. is_bitwise_serializable<Property> > { };
  109. template<typename T, typename U, typename Property>
  110. struct implementation_level<
  111. boost::detail::parallel::pair_with_property<T, U, Property> >
  112. : mpl::int_<object_serializable> {} ;
  113. template<typename T, typename U, typename Property>
  114. struct tracking_level<
  115. boost::detail::parallel::pair_with_property<T, U, Property> >
  116. : mpl::int_<track_never> {} ;
  117. } } // end namespace boost::serialization
  118. #endif // BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP