packed_iprimitive.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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_PACKED_IPRIMITIVE_HPP
  7. #define BOOST_MPI_PACKED_IPRIMITIVE_HPP
  8. #include <boost/mpi/config.hpp>
  9. #include <cstddef> // size_t
  10. #include <boost/config.hpp>
  11. #include <boost/mpi/datatype.hpp>
  12. #include <boost/mpi/exception.hpp>
  13. #include <boost/mpi/detail/antiques.hpp>
  14. #include <boost/serialization/array.hpp>
  15. #include <vector>
  16. #include <boost/mpi/detail/antiques.hpp>
  17. #include <boost/mpi/allocator.hpp>
  18. namespace boost { namespace mpi {
  19. /// deserialization using MPI_Unpack
  20. class BOOST_MPI_DECL packed_iprimitive
  21. {
  22. public:
  23. /// the type of the buffer from which the data is unpacked upon deserialization
  24. typedef std::vector<char, allocator<char> > buffer_type;
  25. packed_iprimitive(buffer_type & b, MPI_Comm const & comm, int position = 0)
  26. : buffer_(b),
  27. comm(comm),
  28. position(position)
  29. {
  30. }
  31. void* address ()
  32. {
  33. return &buffer_[0];
  34. }
  35. void const* address () const
  36. {
  37. return &buffer_[0];
  38. }
  39. const std::size_t& size() const
  40. {
  41. return size_ = buffer_.size();
  42. }
  43. void resize(std::size_t s)
  44. {
  45. buffer_.resize(s);
  46. }
  47. void load_binary(void *address, std::size_t count)
  48. {
  49. load_impl(address,MPI_BYTE,count);
  50. }
  51. // fast saving of arrays of fundamental types
  52. template<class T>
  53. void load_array(serialization::array_wrapper<T> const& x, unsigned int /* file_version */)
  54. {
  55. if (x.count())
  56. load_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
  57. }
  58. /*
  59. template<class T>
  60. void load(serialization::array_wrapper<T> const& x)
  61. {
  62. load_array(x,0u);
  63. }
  64. */
  65. typedef is_mpi_datatype<mpl::_1> use_array_optimization;
  66. // default saving of primitives.
  67. template<class T>
  68. void load( T & t)
  69. {
  70. load_impl(&t, get_mpi_datatype(t), 1);
  71. }
  72. template<class CharType>
  73. void load(std::basic_string<CharType> & s)
  74. {
  75. unsigned int l;
  76. load(l);
  77. s.resize(l);
  78. // note breaking a rule here - could be a problem on some platform
  79. if (l)
  80. load_impl(const_cast<CharType *>(s.data()),
  81. get_mpi_datatype(CharType()),l);
  82. }
  83. private:
  84. void load_impl(void * p, MPI_Datatype t, int l)
  85. {
  86. BOOST_MPI_CHECK_RESULT(MPI_Unpack,
  87. (const_cast<char*>(detail::c_data(buffer_)), buffer_.size(), &position, p, l, t, comm));
  88. }
  89. buffer_type & buffer_;
  90. mutable std::size_t size_;
  91. MPI_Comm comm;
  92. int position;
  93. };
  94. } } // end namespace boost::mpi
  95. #endif // BOOST_MPI_PACKED_IPRIMITIVE_HPP