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
12 #ifndef BOOST_GRAPH_USE_MPI
13 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
14 #endif
15
16 #include <boost/mpi/datatype.hpp>
17 #include <boost/property_map/property_map.hpp>
18 #include <boost/serialization/base_object.hpp>
19 #include <boost/mpl/and.hpp>
20 #include <boost/graph/parallel/detail/untracked_pair.hpp>
21
22 namespace boost { namespace detail { namespace parallel {
23
24 /**
25 * This structure contains an instance of @c Property, unless @c
26 * Property is a placeholder for "no property". Always access the
27 * property through @c get_property. Typically used as a base class.
28 */
29 template<typename Property>
30 struct maybe_store_property
31 {
maybe_store_propertyboost::detail::parallel::maybe_store_property32 maybe_store_property() {}
maybe_store_propertyboost::detail::parallel::maybe_store_property33 maybe_store_property(const Property& p) : p(p) {}
34
get_propertyboost::detail::parallel::maybe_store_property35 Property& get_property() { return p; }
get_propertyboost::detail::parallel::maybe_store_property36 const Property& get_property() const { return p; }
37
38 private:
39 Property p;
40
41 friend class boost::serialization::access;
42
43 template<typename Archiver>
serializeboost::detail::parallel::maybe_store_property44 void serialize(Archiver& ar, const unsigned int /*version*/)
45 {
46 ar & p;
47 }
48 };
49
50 template<>
51 struct maybe_store_property<no_property>
52 {
maybe_store_propertyboost::detail::parallel::maybe_store_property53 maybe_store_property() {}
maybe_store_propertyboost::detail::parallel::maybe_store_property54 maybe_store_property(no_property) {}
55
get_propertyboost::detail::parallel::maybe_store_property56 no_property get_property() const { return no_property(); }
57
58 private:
59 friend class boost::serialization::access;
60
61 template<typename Archiver>
serializeboost::detail::parallel::maybe_store_property62 void serialize(Archiver&, const unsigned int /*version*/) { }
63 };
64
65 /**
66 * This structure is a simple pair that also contains a property.
67 */
68 template<typename T, typename U, typename Property>
69 class pair_with_property
70 : public boost::parallel::detail::untracked_pair<T, U>
71 , public maybe_store_property<Property>
72 {
73 public:
74 typedef boost::parallel::detail::untracked_pair<T, U> pair_base;
75 typedef maybe_store_property<Property> property_base;
76
pair_with_property()77 pair_with_property() { }
78
pair_with_property(const T & t,const U & u,const Property & property)79 pair_with_property(const T& t, const U& u, const Property& property)
80 : pair_base(t, u), property_base(property) { }
81
82 private:
83 friend class boost::serialization::access;
84
85 template<typename Archiver>
serialize(Archiver & ar,const unsigned int)86 void serialize(Archiver& ar, const unsigned int /*version*/)
87 {
88 ar & boost::serialization::base_object<pair_base>(*this)
89 & boost::serialization::base_object<property_base>(*this);
90 }
91 };
92
93 template<typename T, typename U, typename Property>
94 inline pair_with_property<T, U, Property>
make_pair_with_property(const T & t,const U & u,const Property & property)95 make_pair_with_property(const T& t, const U& u, const Property& property)
96 {
97 return pair_with_property<T, U, Property>(t, u, property);
98 }
99
100 } } } // end namespace boost::parallel::detail
101
102 namespace boost { namespace mpi {
103
104 template<>
105 struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<no_property> > : mpl::true_ { };
106
107 template<typename Property>
108 struct is_mpi_datatype<boost::detail::parallel::maybe_store_property<Property> >
109 : is_mpi_datatype<Property> { };
110
111 template<typename T, typename U, typename Property>
112 struct is_mpi_datatype<boost::detail::parallel::pair_with_property<T, U, Property> >
113 : boost::mpl::and_<is_mpi_datatype<boost::parallel::detail::untracked_pair<T, U> >,
114 is_mpi_datatype<Property> > { };
115
116 } } // end namespace boost::mpi
117
118 BOOST_IS_BITWISE_SERIALIZABLE(boost::detail::parallel::maybe_store_property<no_property>)
119
120 namespace boost { namespace serialization {
121
122 template<typename Property>
123 struct is_bitwise_serializable<boost::detail::parallel::maybe_store_property<Property> >
124 : is_bitwise_serializable<Property> { };
125
126 template<typename Property>
127 struct implementation_level<boost::detail::parallel::maybe_store_property<Property> >
128 : mpl::int_<object_serializable> {} ;
129
130 template<typename Property>
131 struct tracking_level<boost::detail::parallel::maybe_store_property<Property> >
132 : mpl::int_<track_never> {} ;
133
134 template<typename T, typename U, typename Property>
135 struct is_bitwise_serializable<
136 boost::detail::parallel::pair_with_property<T, U, Property> >
137 : boost::mpl::and_<is_bitwise_serializable<boost::parallel::detail::untracked_pair<T, U> >,
138 is_bitwise_serializable<Property> > { };
139
140 template<typename T, typename U, typename Property>
141 struct implementation_level<
142 boost::detail::parallel::pair_with_property<T, U, Property> >
143 : mpl::int_<object_serializable> {} ;
144
145 template<typename T, typename U, typename Property>
146 struct tracking_level<
147 boost::detail::parallel::pair_with_property<T, U, Property> >
148 : mpl::int_<track_never> {} ;
149
150 } } // end namespace boost::serialization
151
152 #endif // BOOST_PARALLEL_DETAIL_PROPERTY_HOLDERS_HPP
153