opm-common
MemPacker.hpp
1 /*
2  Copyright 2019 Equinor AS.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef MEM_PACKER_HPP
20 #define MEM_PACKER_HPP
21 
22 #include <opm/common/utility/TimeService.hpp>
23 
24 #include <bitset>
25 #include <cstddef>
26 #include <cstring>
27 #include <string>
28 #include <vector>
29 
30 namespace Opm {
31 namespace Serialization {
32 namespace detail {
33 
34 template <typename T>
35 constexpr bool is_pod_v = std::is_standard_layout_v<T> && std::is_trivial_v<T>;
36 
38 template <bool pod, class T>
39 struct Packing
40 {
41  static std::size_t packSize(const T&);
42  static void pack(const T&, std::vector<char>&, std::size_t&);
43  static void unpack(T&, const std::vector<char>&, std::size_t&);
44 };
45 
47 template<class T>
48 struct Packing<true,T>
49 {
52  static std::size_t packSize(const T& data)
53  {
54  return packSize(&data, 1);
55  }
56 
60  static std::size_t packSize(const T*, std::size_t n)
61  {
62  return n*sizeof(T);
63  }
64 
69  static void pack(const T& data,
70  std::vector<char>& buffer,
71  std::size_t& position)
72  {
73  pack(&data, 1, buffer, position);
74  }
75 
81  static void pack(const T* data,
82  std::size_t n,
83  std::vector<char>& buffer,
84  std::size_t& position)
85  {
86  std::memcpy(buffer.data() + position, data, n*sizeof(T));
87  position += n*sizeof(T);
88  }
89 
94  static void unpack(T& data,
95  const std::vector<char>& buffer,
96  std::size_t& position)
97  {
98  unpack(&data, 1, buffer, position);
99  }
100 
106  static void unpack(T* data,
107  std::size_t n,
108  const std::vector<char>& buffer,
109  std::size_t& position)
110  {
111  std::memcpy(data, buffer.data() + position, n*sizeof(T));
112  position += n*sizeof(T);
113  }
114 };
115 
117 template<class T>
118 struct Packing<false,T>
119 {
120  static std::size_t packSize(const T&)
121  {
122  static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
123  return 0;
124  }
125 
126  static void pack(const T&, std::vector<char>&, std::size_t&)
127  {
128  static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
129  }
130 
131  static void unpack(T&, const std::vector<char>&, std::size_t&)
132  {
133  static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
134  }
135 };
136 
138 template <std::size_t Size>
139 struct Packing<false,std::bitset<Size>>
140 {
141  static std::size_t packSize(const std::bitset<Size>& data);
142 
143  static void pack(const std::bitset<Size>& data,
144  std::vector<char>& buffer, std::size_t& position);
145 
146  static void unpack(std::bitset<Size>& data,
147  const std::vector<char>& buffer, std::size_t& position);
148 };
149 
150 template<>
151 struct Packing<false,std::string>
152 {
153  static std::size_t packSize(const std::string& data);
154 
155  static void pack(const std::string& data,
156  std::vector<char>& buffer, std::size_t& position);
157 
158  static void unpack(std::string& data, const std::vector<char>& buffer, std::size_t& position);
159 };
160 
161 template<>
162 struct Packing<false,time_point>
163 {
164  static std::size_t packSize(const time_point&);
165 
166  static void pack(const time_point& data,
167  std::vector<char>& buffer, std::size_t& position);
168 
169  static void unpack(time_point& data, const std::vector<char>& buffer, std::size_t& position);
170 };
171 
172 }
173 
175 struct MemPacker {
179  template<class T>
180  std::size_t packSize(const T& data) const
181  {
183  }
184 
189  template<class T>
190  std::size_t packSize(const T* data, std::size_t n) const
191  {
192  static_assert(detail::is_pod_v<T>, "Array packing not supported for non-pod data");
193  return detail::Packing<true,T>::packSize(data, n);
194  }
195 
201  template<class T>
202  void pack(const T& data,
203  std::vector<char>& buffer,
204  std::size_t& position) const
205  {
206  detail::Packing<detail::is_pod_v<T>,T>::pack(data, buffer, position);
207  }
208 
215  template<class T>
216  void pack(const T* data,
217  std::size_t n,
218  std::vector<char>& buffer,
219  std::size_t& position) const
220  {
221  static_assert(detail::is_pod_v<T>, "Array packing not supported for non-pod data");
222  detail::Packing<true,T>::pack(data, n, buffer, position);
223  }
224 
230  template<class T>
231  void unpack(T& data,
232  const std::vector<char>& buffer,
233  std::size_t& position) const
234  {
235  detail::Packing<detail::is_pod_v<T>,T>::unpack(data, buffer, position);
236  }
237 
244  template<class T>
245  void unpack(T* data,
246  std::size_t n,
247  const std::vector<char>& buffer,
248  std::size_t& position) const
249  {
250  static_assert(detail::is_pod_v<T>, "Array packing not supported for non-pod data");
251  detail::Packing<true,T>::unpack(data, n, buffer, position);
252  }
253 };
254 
255 } // end namespace Serialization
256 } // end namespace Opm
257 
258 #endif // MEM_PACKER_HPP
std::size_t packSize(const T &data) const
Calculates the pack size for a variable.
Definition: MemPacker.hpp:180
void unpack(T &data, const std::vector< char > &buffer, std::size_t &position) const
Unpack a variable.
Definition: MemPacker.hpp:231
std::size_t packSize(const T *data, std::size_t n) const
Calculates the pack size for an array.
Definition: MemPacker.hpp:190
Abstract struct for packing which is (partially) specialized for specific types.
Definition: MemPacker.hpp:39
static void unpack(T *data, std::size_t n, const std::vector< char > &buffer, std::size_t &position)
Unpack an array of POD.
Definition: MemPacker.hpp:106
Struct handling packing of serialization to a memory buffer.
Definition: MemPacker.hpp:175
void unpack(T *data, std::size_t n, const std::vector< char > &buffer, std::size_t &position) const
Unpack an array.
Definition: MemPacker.hpp:245
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
static void pack(const T &data, std::vector< char > &buffer, std::size_t &position)
Pack a POD.
Definition: MemPacker.hpp:69
Definition: CriticalError.hpp:115
void pack(const T &data, std::vector< char > &buffer, std::size_t &position) const
Pack a variable.
Definition: MemPacker.hpp:202
static void pack(const T *data, std::size_t n, std::vector< char > &buffer, std::size_t &position)
Pack an array of POD.
Definition: MemPacker.hpp:81
void pack(const T *data, std::size_t n, std::vector< char > &buffer, std::size_t &position) const
Pack an array.
Definition: MemPacker.hpp:216
static std::size_t packSize(const T *, std::size_t n)
Calculates the pack size for an array of POD.
Definition: MemPacker.hpp:60
static void unpack(T &data, const std::vector< char > &buffer, std::size_t &position)
Unpack a POD.
Definition: MemPacker.hpp:94
static std::size_t packSize(const T &data)
Calculates the pack size for a POD.
Definition: MemPacker.hpp:52