status.hpp 3.4 KB

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