• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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