1 // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>.
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 // http://www.boost.org/LICENSE_1_0.txt)
6
7 /** @file status.hpp
8 *
9 * This header defines the class @c status, which reports on the
10 * results of point-to-point communication.
11 */
12 #ifndef BOOST_MPI_STATUS_HPP
13 #define BOOST_MPI_STATUS_HPP
14
15 #include <boost/mpi/config.hpp>
16 #include <boost/mpi/datatype.hpp>
17 #include <boost/optional.hpp>
18 #include <boost/mpl/bool.hpp>
19
20 namespace boost { namespace mpi {
21
22 class request;
23 class communicator;
24
25 /** @brief Contains information about a message that has been or can
26 * be received.
27 *
28 * This structure contains status information about messages that
29 * have been received (with @c communicator::recv) or can be received
30 * (returned from @c communicator::probe or @c
31 * communicator::iprobe). It permits access to the source of the
32 * message, message tag, error code (rarely used), or the number of
33 * elements that have been transmitted.
34 */
35 class BOOST_MPI_DECL status
36 {
37 public:
status()38 status() : m_count(-1) { }
39
status(MPI_Status const & s)40 status(MPI_Status const& s) : m_status(s), m_count(-1) {}
41
42 /**
43 * Retrieve the source of the message.
44 */
source() const45 int source() const { return m_status.MPI_SOURCE; }
46
47 /**
48 * Retrieve the message tag.
49 */
tag() const50 int tag() const { return m_status.MPI_TAG; }
51
52 /**
53 * Retrieve the error code.
54 */
error() const55 int error() const { return m_status.MPI_ERROR; }
56
57 /**
58 * Determine whether the communication associated with this object
59 * has been successfully cancelled.
60 */
61 bool cancelled() const;
62
63 /**
64 * Determines the number of elements of type @c T contained in the
65 * message. The type @c T must have an associated data type, i.e.,
66 * @c is_mpi_datatype<T> must derive @c mpl::true_. In cases where
67 * the type @c T does not match the transmitted type, this routine
68 * will return an empty @c optional<int>.
69 *
70 * @returns the number of @c T elements in the message, if it can be
71 * determined.
72 */
count() const73 template<typename T> optional<int> count() const { return count_impl<T>(is_mpi_datatype<T>()); }
74
75 /**
76 * References the underlying @c MPI_Status
77 */
operator MPI_Status&()78 operator MPI_Status&() { return m_status; }
79
80 /**
81 * References the underlying @c MPI_Status
82 */
operator const MPI_Status&() const83 operator const MPI_Status&() const { return m_status; }
84
85 private:
86 /**
87 * INTERNAL ONLY
88 */
89 template<typename T> optional<int> count_impl(mpl::true_) const;
90
91 /**
92 * INTERNAL ONLY
93 */
94 template<typename T> optional<int> count_impl(mpl::false_) const;
95
96 public: // friend templates are not portable
97
98 /// INTERNAL ONLY
99 mutable MPI_Status m_status;
100 mutable int m_count;
101
102 friend class communicator;
103 friend class request;
104 };
105
106 template<typename T>
count_impl(mpl::true_) const107 inline optional<int> status::count_impl(mpl::true_) const
108 {
109 if (m_count != -1)
110 return m_count;
111
112 int return_value;
113 BOOST_MPI_CHECK_RESULT(MPI_Get_count,
114 (&m_status, get_mpi_datatype<T>(T()), &return_value));
115 if (return_value == MPI_UNDEFINED)
116 return optional<int>();
117 else
118 /* Cache the result. */
119 return m_count = return_value;
120 }
121
122 template<typename T>
count_impl(mpl::false_) const123 inline optional<int> status::count_impl(mpl::false_) const
124 {
125 if (m_count == -1)
126 return optional<int>();
127 else
128 return m_count;
129 }
130
131
132 } } // end namespace boost::mpi
133
134 #endif // BOOST_MPI_STATUS_HPP
135