]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // (C) Copyright 2005-2007 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 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | // Authors: Matthias Troyer | |
8 | ||
9 | #ifndef BOOST_MPI_BINARY_BUFFER_IPRIMITIVE_HPP | |
10 | #define BOOST_MPI_BINARY_BUFFER_IPRIMITIVE_HPP | |
11 | ||
12 | #include <mpi.h> | |
13 | #include <iostream> | |
14 | #include <cstddef> // size_t | |
15 | #include <boost/config.hpp> | |
16 | #include <boost/mpi/exception.hpp> | |
17 | #include <boost/assert.hpp> | |
18 | #include <boost/mpl/assert.hpp> | |
19 | #include <boost/serialization/array.hpp> | |
20 | #include <boost/serialization/is_bitwise_serializable.hpp> | |
21 | #include <vector> | |
22 | #include <boost/mpi/allocator.hpp> | |
23 | #include <cstring> // for memcpy | |
24 | #include <cassert> | |
25 | ||
26 | namespace boost { namespace mpi { | |
27 | ||
28 | /// deserialization using MPI_Unpack | |
29 | ||
30 | class BOOST_MPI_DECL binary_buffer_iprimitive | |
31 | { | |
32 | public: | |
33 | /// the type of the buffer from which the data is unpacked upon deserialization | |
34 | typedef std::vector<char, allocator<char> > buffer_type; | |
35 | ||
36 | binary_buffer_iprimitive(buffer_type & b, MPI_Comm const &, int position = 0) | |
37 | : buffer_(b), | |
38 | position(position) | |
39 | { | |
40 | } | |
41 | ||
42 | void* address () | |
43 | { | |
44 | return &buffer_.front(); | |
45 | } | |
46 | ||
47 | void const* address () const | |
48 | { | |
49 | return &buffer_.front(); | |
50 | } | |
51 | ||
52 | const std::size_t& size() const | |
53 | { | |
54 | return size_ = buffer_.size(); | |
55 | } | |
56 | ||
57 | void resize(std::size_t s) | |
58 | { | |
59 | buffer_.resize(s); | |
60 | } | |
61 | ||
62 | void load_binary(void *address, std::size_t count) | |
63 | { | |
64 | load_impl(address,count); | |
65 | } | |
66 | ||
67 | // fast saving of arrays of fundamental types | |
68 | template<class T> | |
69 | void load_array(serialization::array_wrapper<T> const& x, unsigned int /* file_version */) | |
70 | { | |
71 | BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>)); | |
72 | if (x.count()) | |
73 | load_impl(x.address(), sizeof(T)*x.count()); | |
74 | } | |
75 | ||
76 | typedef serialization::is_bitwise_serializable<mpl::_1> use_array_optimization; | |
77 | ||
78 | template<class T> | |
79 | void load(serialization::array_wrapper<T> const& x) | |
80 | { | |
81 | load_array(x,0u); | |
82 | } | |
83 | ||
84 | // default saving of primitives. | |
85 | template<class T> | |
86 | void load( T & t) | |
87 | { | |
88 | BOOST_MPL_ASSERT((serialization::is_bitwise_serializable<BOOST_DEDUCED_TYPENAME remove_const<T>::type>)); | |
89 | load_impl(&t, sizeof(T)); | |
90 | } | |
91 | ||
92 | template<class CharType> | |
93 | void load(std::basic_string<CharType> & s) | |
94 | { | |
95 | unsigned int l; | |
96 | load(l); | |
97 | // borland de-allocator fixup | |
98 | #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) | |
99 | if(NULL != s.data()) | |
100 | #endif | |
101 | s.resize(l); | |
102 | // note breaking a rule here - could be a problem on some platform | |
103 | load_impl(const_cast<char *>(s.data()),l); | |
104 | } | |
105 | ||
106 | private: | |
107 | ||
108 | void load_impl(void * p, int l) | |
109 | { | |
110 | assert(position+l<=static_cast<int>(buffer_.size())); | |
111 | if (l) | |
112 | std::memcpy(p,&buffer_[position],l); | |
113 | position += l; | |
114 | } | |
115 | ||
116 | buffer_type & buffer_; | |
117 | mutable std::size_t size_; | |
118 | int position; | |
119 | }; | |
120 | ||
121 | } } // end namespace boost::mpi | |
122 | ||
123 | #endif // BOOST_MPI_PACKED_IPRIMITIVE_HPP |