PSCF v1.2
TextFileOArchive.h
1#ifndef UTIL_TEXT_FILE_O_ARCHIVE_H
2#define UTIL_TEXT_FILE_O_ARCHIVE_H
3
4/*
5* Util Package - C++ Utilities for Scientific Computation
6*
7* Copyright 2010 - 2017, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "Byte.h"
12#include "serialize.h"
13
14#include <util/space/Vector.h>
15#include <util/space/IntVector.h>
16
17#include <complex>
18#include <string>
19#include <vector>
20#include <fstream>
21
22namespace Util
23{
24
31 {
32
33 public:
34
36 static bool is_saving();
37
39 static bool is_loading();
40
45
51 TextFileOArchive(std::string filename);
52
58 TextFileOArchive(std::ofstream& file);
59
63 virtual ~TextFileOArchive();
64
68 std::ofstream& file();
69
77 template <typename T>
79
87 template <typename T>
89
99 template <typename T, size_t N>
100 TextFileOArchive& operator << (T (& data)[N]);
101
109 template <typename T, size_t N>
110 TextFileOArchive& operator & (T (& data)[N]);
111
112 // Pack function templates
113
119 template <typename T>
120 void pack(const T& data);
121
128 template <typename T>
129 void pack(const T* array, int n);
130
139 template <typename T>
140 void pack(const T* array, int m, int n, int np);
141
142 private:
143
145 std::ofstream* filePtr_;
146
148 unsigned int version_;
149
151 bool createdFile_;
152
153 };
154
155 // Static inline methods
156
158 { return true; }
159
161 { return false; }
162
163 // Overloaded << (insertion) and & operators
164
165 /*
166 * Save one object of type T to this archive via the << operator.
167 */
168 template <typename T>
170 {
171 serialize(*this, data, version_);
172 return *this;
173 }
174
175 /*
176 * Save one object of type T to this archive via the & operator.
177 */
178 template <typename T>
180 {
181 serialize(*this, data, version_);
182 return *this;
183 }
184
185 /*
186 * Save a fixed size array of T objects via operator <<.
187 */
188 template <typename T, size_t N>
190 {
191 for (size_t i = 0; i < N; ++i) {
192 serialize(*this, data[i], version_);
193 }
194 return *this;
195 }
196
197 /*
198 * Save a fixed size array of T objects via operator &.
199 */
200 template <typename T, size_t N>
202 {
203 for (size_t i = 0; i < N; ++i) {
204 serialize(*this, data[i], version_);
205 }
206 return *this;
207 }
208
209 // Pack function templates and template instantiations
210
211 /*
212 * Save a single object of type T.
213 */
214 template <typename T>
215 inline void TextFileOArchive::pack(const T& data)
216 { *filePtr_ << data << std::endl; }
217
218 /*
219 * Save a single object of type double.
220 */
221 template <>
222 inline void TextFileOArchive::pack(const double& data)
223 {
224 filePtr_->setf(std::ios::scientific);
225 filePtr_->width(25);
226 filePtr_->precision(17);
227 *filePtr_ << data << std::endl;
228 }
229
230 /*
231 * Save a C-array of objects of type T.
232 */
233 template <typename T>
234 inline void TextFileOArchive::pack(const T* array, int n)
235 {
236 for (int i=0; i < n; ++i) {
237 *filePtr_ << array[i] << " ";
238 }
239 *filePtr_ << std::endl;
240 }
241
242 /*
243 * Pack a 2D C-array of objects of type T, from array type T array[][np].
244 */
245 template <typename T>
246 inline void TextFileOArchive::pack(const T* array, int m, int n, int np)
247 {
248 int i, j;
249 for (i = 0; i < m; ++i) {
250 for (j = 0; j < n; ++j) {
251 *filePtr_ << array[i*np + j] << " ";
252 }
253 *filePtr_ << std::endl;
254 }
255 }
256
257 /*
258 * Pack a C-array of double values.
259 */
260 template <>
261 inline void TextFileOArchive::pack(const double* array, int n)
262 {
263 filePtr_->setf(std::ios::scientific);
264 filePtr_->precision(16);
265 for (int i=0; i < n; ++i) {
266 filePtr_->width(25);
267 *filePtr_ << array[i] << " ";
268 }
269 *filePtr_ << std::endl;
270 }
271
272 // Explicit serialize functions for primitive types
273
274 /*
275 * Save a bool to a TextFileOArchive.
276 */
277 template <>
278 inline void serialize(TextFileOArchive& ar, bool& data,
279 const unsigned int version)
280 { ar.pack(data); }
281
282 /*
283 * Save a char to a TextFileOArchive.
284 */
285 template <>
286 inline void serialize(TextFileOArchive& ar, char& data,
287 const unsigned int version)
288 { ar.pack(data); }
289
290 /*
291 * Save an unsigned int to a TextFileOArchive.
292 */
293 template <>
294 inline void serialize(TextFileOArchive& ar, unsigned int& data,
295 const unsigned int version)
296 { ar.pack(data); }
297
298 /*
299 * Save an int to a TextFileOArchive.
300 */
301 template <>
302 inline void serialize(TextFileOArchive& ar, int& data,
303 const unsigned int version)
304 { ar.pack(data); }
305
306 /*
307 * Save an unsigned long int to a TextFileOArchive.
308 */
309 template <>
310 inline void serialize(TextFileOArchive& ar, unsigned long& data,
311 const unsigned int version)
312 { ar.pack(data); }
313
314 /*
315 * Save a long int to a TextFileOArchive.
316 */
317 template <>
318 inline void serialize(TextFileOArchive& ar, long& data,
319 const unsigned int version)
320 { ar.pack(data); }
321
322 /*
323 * Save a float to a TextFileOArchive.
324 */
325 template <>
326 inline void serialize(TextFileOArchive& ar, float& data,
327 const unsigned int version)
328 { ar.pack(data); }
329
330 /*
331 * Save an double to a TextFileOArchive.
332 */
333 template <>
334 inline void serialize(TextFileOArchive& ar, double& data,
335 const unsigned int version)
336 { ar.pack(data); }
337
338 /*
339 * Save a std::vector to a TextFileOArchive.
340 */
341 template <typename T>
342 void serialize(TextFileOArchive& ar, std::vector<T>& data,
343 const unsigned int version)
344 {
345 size_t size = data.size();
346 ar.pack(size);
347 for (size_t i = 0; i < size; ++i) {
348 ar & data[i];
349 }
350 }
351
352 // Explicit serialize functions for standard library types
353
354 /*
355 * Save a std::complex<float> to a TextFileOArchive.
356 *
357 * Implementation relies on existence of a << operator for
358 * std::complex<float>.
359 */
360 template <>
361 inline
362 void serialize(TextFileOArchive& ar, std::complex<float>& data,
363 const unsigned int version)
364 { ar.pack(data); }
365
366 /*
367 * Save a std::complex<double> to a TextFileOArchive.
368 *
369 * Implementation relies on existence of a << operator for
370 * std::complex<float>.
371 */
372 template <>
373 inline
374 void serialize(TextFileOArchive& ar, std::complex<double>& data,
375 const unsigned int version)
376 { ar.pack(data); }
377
378 /*
379 * Save a std::string to a TextFileOArchive.
380 */
381 template <>
382 inline void serialize(TextFileOArchive& ar, std::string& data,
383 const unsigned int version)
384 {
385 int size = data.size();
386 ar.pack(size);
387 if (size > 0) {
388 ar.pack(data);
389 }
390 }
391
392 // Explicit serialize functions for classes in namespace Util
393
394 /*
395 * Save a Util::Vector to a TextFileOArchive.
396 */
397 template <>
398 inline void serialize(TextFileOArchive& ar, Vector& data,
399 const unsigned int version)
400 { ar.pack(data); }
401
402 /*
403 * Save a Util::IntVector to a TextFileOArchive.
404 */
405 template <>
406 inline void serialize(TextFileOArchive& ar, IntVector& data,
407 const unsigned int version)
408 { ar.pack(data); }
409
410}
411#endif
Saving archive for character based ostream.
TextFileOArchive & operator<<(T &data)
Save one T object to this archive via the << (insertion) operator.
static bool is_loading()
Returns false;.
static bool is_saving()
Returns true;.
virtual ~TextFileOArchive()
Destructor.
TextFileOArchive & operator&(T &data)
Save one T object to this archive.
std::ofstream & file()
Get the underlying ifstream by reference.
void pack(const T &data)
Save one T object to this archive.
Utility classes for scientific computation.