mpi_datatype_cache.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // (C) Copyright 2005 Matthias Troyer
  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. // Authors: Matthias Troyer
  6. #ifndef BOOST_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
  7. #define BOOST_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP
  8. #include <boost/mpi/datatype_fwd.hpp>
  9. #include <boost/mpi/detail/mpi_datatype_oarchive.hpp>
  10. #include <boost/mpi/exception.hpp>
  11. #include <boost/utility/enable_if.hpp>
  12. #include <boost/mpl/assert.hpp>
  13. #include <boost/noncopyable.hpp>
  14. #include <typeinfo>
  15. // The std::type_info::before function in Visual C++ 8.0 (and probably earlier)
  16. // incorrectly returns an "int" instead of a "bool". Then the compiler has the
  17. // audacity to complain when that "int" is converted to a "bool". Silence
  18. // this warning.
  19. #ifdef BOOST_MSVC
  20. # pragma warning(push)
  21. # pragma warning(disable : 4800)
  22. #endif
  23. namespace boost { namespace mpi { namespace detail {
  24. /// @brief comparison function object for two std::type_info pointers
  25. ///
  26. /// is implemented using the before() member function of the std::type_info
  27. /// class
  28. struct type_info_compare
  29. {
  30. bool operator()(std::type_info const* lhs, std::type_info const* rhs) const
  31. {
  32. return lhs->before(*rhs);
  33. }
  34. };
  35. /// @brief a map of MPI data types, indexed by their type_info
  36. ///
  37. ///
  38. class BOOST_MPI_DECL mpi_datatype_map
  39. : public boost::noncopyable
  40. {
  41. struct implementation;
  42. implementation *impl;
  43. public:
  44. mpi_datatype_map();
  45. ~mpi_datatype_map();
  46. template <class T>
  47. MPI_Datatype datatype(const T& x = T(), typename boost::enable_if<is_mpi_builtin_datatype<T> >::type* =0)
  48. {
  49. return get_mpi_datatype<T>(x);
  50. }
  51. template <class T>
  52. MPI_Datatype datatype(const T& x =T(), typename boost::disable_if<is_mpi_builtin_datatype<T> >::type* =0 )
  53. {
  54. BOOST_MPL_ASSERT((is_mpi_datatype<T>));
  55. // check whether the type already exists
  56. std::type_info const* t = &typeid(T);
  57. MPI_Datatype datatype = get(t);
  58. if (datatype == MPI_DATATYPE_NULL) {
  59. // need to create a type
  60. mpi_datatype_oarchive ar(x);
  61. datatype = ar.get_mpi_datatype();
  62. set(t, datatype);
  63. }
  64. return datatype;
  65. }
  66. void clear();
  67. private:
  68. MPI_Datatype get(const std::type_info* t);
  69. void set(const std::type_info* t, MPI_Datatype datatype);
  70. };
  71. /// Retrieve the MPI datatype cache
  72. BOOST_MPI_DECL mpi_datatype_map& mpi_datatype_cache();
  73. } } } // end namespace boost::mpi::detail
  74. #ifdef BOOST_MSVC
  75. # pragma warning(pop)
  76. #endif
  77. #endif // BOOST_MPI_DETAIL_TYPE_MPI_DATATYPE_CACHE_HPP